(十四)Gateway API
上一章我们学了 Ingress 可以通过域名和路径,把外部 HTTP 请求转发到不同的 Service
这里我们来讲讲 Gateway API,它与 Ingress 解决的问题很像,都是让外部请求进入集群,然后根据规则把请求交给不同的 Service,不过 Gateway API 将入口和路由拆得更开一些
- GatewayClass -> 与 Ingress Class 类似,告诉 Kubernetes 用什么 Controller
- Gateway -> 网关,用于监听配置的
- 路由资源 -> 比如 HTTPRoute GRPCRoute等,负责请求怎么走
安装 Gateway API
kubectl get gatewayclass
如果出现 error,则说明未下载,因为 Kubernetes 不会默认携带 Gateway API 资源
# 安装
kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.6.1/standard-install.yaml
# 查看
kubectl get crd gatewayclasses.gateway.networking.k8s.io gateways.gateway.networking.k8s.io httproutes.gateway.networking.k8s.io
可以看到,已经安装完成了

配置 Traefik
由于上一节安装过,这里就不再需要安装了,直接配置即可
# 更新仓库
helm repo update
# 给当前 Traefik 打开 Gateway API Provider
helm upgrade traefik traefik/traefik --version 41.3.0 --namespace traefik --reuse-values --set providers.kubernetesGateway.enabled=true --set gateway.listeners.web.namespacePolicy.from=All --wait --timeout 10m
kubectl get pods, svc -n traefik
可以看到成功了,Warning 不是报错的意思,这里有两个重要的参数
- providers.kubernetesGateway.enabled=true 表示让 Traefik 开始读取 Gateway API 相关资源
- gateway.listeners.web.namespacePolicy.from=All 表示其他 Namespace 中的 HTTPRoute,也可以挂到 Traefik 的这个 HTTP listener 上

GatewayClass
现在重新查看
kubectl get gatewayclass
kubeclt get gatewayclass traefik -o yaml
可以看到,Traefik 已经创建了一个名为 traefik 的 GatewayClass,意思就是 告诉 Kubernetes,这种 Gateway 由什么 Controller 管理

Gateway
kubectl get gateway -n traefik
kubectl get gateway traefik-gateway -n traefik -o json | jq '.spec'
首先要注意的是 protocol: HTTP,代表这是 HTTP listener、port: 8000 表示 Traefik web EntryPoint 在 Pod 内使用的监听端口,不是集群外直接访问时使用的 NodePort,也就是监听这个 Pod 使用 8000

实验
创建两个 Deployment,Service
kubectl create namespace gateway-lab
# 创建 Deployment
kubectl create deployment web1 --image=traefik/whoami -n gateway-lab -- /whoami --name=web1
kubectl create deployment web2 --image=traefik/whoami -n gateway-lab -- /whoami --name=web2
kubectl get pods -n gateway-lab -o wide
# 创建 Service
kubectl expose deployment web1 --port=80 -n gateway-lab
kubectl expose deployment web2 --port=80 -n gateway-lab
kubectl get pods,svc -n gateway-lab -o wide
kubectl create deployment 中 -- 后面的内容会作为容器 command,traefik/whoami 镜像的启动程序是 /whoami,所以这里需要显式写
以及这里两个 Service 还是 ClusterIP,不是 NodePort;为什么不需要 NodePort,因为外部真正访问的是 Traefik,Traefik 再把请求交给这两个 Service
外部请求 ——> Traefik ——> web1 / web2 Service ——> Pod

创建 HTTPRoute
这里就以 HTTPRoute 为路由资源来看请求怎么走
cat > httproute.yaml <<'EOF' apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: web # 路由名字叫 web spec: parentRefs: - name: traefik-gateway # 网关名 namespace: traefik # 网关的命名空间 sectionName: web hostnames: - gateway.example.test # 匹配的域名 rules: - matches: - path: type: PathPrefix value: /web1 backendRefs: - name: web1 # 转发到的 Service port: 80 - matches: - path: type: PathPrefix value: /web2 backendRefs: - name: web2 port: 80 EOF
kubectl apply -n gateway-lab -f httproute.yaml
kubectl get httproute -n gateway-lab
## 查看 HTTPRoute 是否生效
kubectl describe httproute web -n gateway-lab
- Accepted=True 表示 HTTPRoute 已经成功挂到 Gateway
- ResolvedRefs=True 表示 HTTPRoute 里引用的所有外部资源(主要是 Service)都能在集群里找到

## 访问 Gateway
获取 master ip
kubectl get node master -o wide
获取 Traefik HTTP NodePort
kubectl get services -n traefik
访问
curl -H 'Host: gateway.example.test' "http://{master_ip}:{NodePort}/web1/" (| grep Name)
curl -H 'Host: gateway.example.test' "http://{master_ip}:{NodePort}/web2/" (| grep Name)
可以看到,两次请求访问的都是同一个 Traefik 入口,只是路径不同

# 配置关系和请求链路
这里需要讲解一下 GatewayClass、Gateway、HTTPRoute 是 Kubernetes 中的配置对象,它们不是客户端请求真正依次经过的网络节点
GatewayClass: traefik 用什么 Controller
↓Gateway: traefik-gateway 网关
↓HTTPRoute: web 路由资源
↓backendRefs 后端服务
↓web1 / web2 Service 哪个 Service
Traefik Controller 会读取这些对象,然后生成自己的实际的路由配置
所以,一次完整的 HTTP 请求是
curl ↓ Node IP : Traefik NodePort ↓ Traefik Service ↓ Traefik Pod ↓ 根据 Gateway / HTTPRoute 生成的规则匹配请求 ↓ web1 Service ↓ web1 Pod
# 其他 Route
Gateway API 不只有 HTTPRoute,还有
- GRPCRoute
- TLSRoute
- TCPRoute
- UDPRoute
这里就不过多介绍了
# 总结
这篇说实话,我其实并不太懂,并不是说这个非常难,而是很多没用的信息全部都堆在了一起,显的非常的....
这就是 AI 的弊端,让他写教程可以,但写出来什么样,是完全不可控的,简称拉坨大的,坨坨不一样
愿诸君顺遂