创建Kubernetes Gateway
本文介绍如何通过Kubernetes Gateway API创建矩尺Gateway、Route和对外访问Service,并在矩尺Web界面中核验配置结果。集群接入尚未完成时,请先参见接入Kubernetes集群。
配置方式
当前版本通过kubectl apply创建或更新Gateway API资源。矩尺Web界面用于查看Gateway、Route、Service及其拓扑和事件,不在Web界面中直接创建这些资源。
配置关系如下:
| 对象 | 作用 | 关键关联 |
|---|---|---|
| GatewayClass | 指定矩尺Gateway控制器 | controllerName: normae.io/gateway |
| Gateway | 定义协议、监听器和端口 | gatewayClassName引用GatewayClass |
| Service | 将Gateway监听端口暴露到集群外 | targetPort与Gateway监听端口一致 |
| HTTPRoute | 定义匹配、过滤和后端转发规则 | parentRefs引用Gateway,backendRefs引用后端Service |
第一步:准备镜像
必须先将控制器镜像和业务后端镜像放入集群节点可访问的镜像仓库,或导入各节点的容器运行时,再创建Gateway实例。离线环境中应以交付包内的实际镜像文件和标签为准。
K3s环境可执行以下命令检查和导入镜像:
sudo k3s ctr images list
sudo k3s ctr images import /path/to/n6-k8sagent.tar
sudo k3s ctr images import /path/to/backend-image.tar控制器Deployment使用的镜像名称必须与已导入镜像完全一致。推荐在离线环境中设置imagePullPolicy: IfNotPresent,并在继续配置前确认控制器Pod和业务后端Pod均为Running:
kubectl get pods -A
kubectl get deployment -A -o wide如果出现ImagePullBackOff或ErrImagePull,应先修正镜像名称、标签或仓库访问问题,不要继续创建Gateway。
第二步:确认后端Service
HTTPRoute引用的是Kubernetes Service,而不是直接引用Pod。创建Route前,确认后端Service已存在、端口正确且拥有可用Endpoint:
kubectl get service -n <业务命名空间>
kubectl get endpoints -n <业务命名空间> <后端Service名称>后续示例使用命名空间n6-k8s-controller-system和后端Servicebackend-a:80。请替换为实际业务命名空间、Service名称和端口。
第三步:创建GatewayClass、Gateway和Service
创建gateway.yaml:
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: n6-gateway-class
labels:
network.normae.io/managed-by: n6-controller
spec:
controllerName: normae.io/gateway
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: example-gateway
namespace: n6-k8s-controller-system
labels:
network.normae.io/managed-by: n6-controller
spec:
gatewayClassName: n6-gateway-class
listeners:
- name: http
protocol: HTTP
port: 9442
allowedRoutes:
namespaces:
from: All
---
apiVersion: v1
kind: Service
metadata:
name: example-gateway
namespace: n6-k8s-controller-system
spec:
type: NodePort
selector:
control-plane: controller-manager
ports:
- name: http
port: 9442
targetPort: 9442
nodePort: 30221应用配置并等待Gateway完成编程:
kubectl apply -f gateway.yaml
kubectl wait -n n6-k8s-controller-system --for=condition=Programmed gateway/example-gateway --timeout=120s
kubectl get gateway -n n6-k8s-controller-system example-gateway
kubectl get service -n n6-k8s-controller-system example-gatewaynodePort必须在集群允许的NodePort范围内且未被占用。Service的selector必须能够选中矩尺Gateway控制器Pod,targetPort必须与Gateway监听端口一致。
第四步:创建HTTPRoute
创建route.yaml:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: example-route
namespace: n6-k8s-controller-system
spec:
parentRefs:
- name: example-gateway
namespace: n6-k8s-controller-system
rules:
- matches:
- path:
type: Exact
value: /example
method: GET
backendRefs:
- name: backend-a
port: 80应用配置:
kubectl apply -f route.yaml
kubectl get httproute -n n6-k8s-controller-system example-route
kubectl describe httproute -n n6-k8s-controller-system example-routeRoute状态中应同时出现Accepted=True和ResolvedRefs=True。如果ResolvedRefs=False,优先检查后端Service名称、命名空间和端口。
第五步:验证转发
使用任一集群Node IP和Service的NodePort发起请求:
curl -i http://<Node-IP>:30221/example请求应到达backend-a对应的业务Pod。若请求失败,依次检查Gateway状态、Route状态、Service Endpoint、NodePort防火墙和控制器日志。
第六步:在Web界面核验
- 进入【Kubernetes-环境配置】,确认目标集群已设为当前环境;
- 进入【Kubernetes-Gateway虚拟服务】,点击“查询”,确认
example-gateway及其监听器存在; - 进入【Kubernetes-Route分发规则】,点击“查询”,确认
example-route绑定到example-gateway且服务器池为backend-a; - 进入【Kubernetes-Service服务器池】,按名称查询
example-gateway,确认类型为NodePort且端口映射正确。
通过命令行创建、更新或删除资源后,列表不会自动刷新,应再次点击“查询”。

更新和删除
修改YAML后再次执行kubectl apply即可更新配置。删除时应先删除Route,再删除Gateway对应的Service和Gateway:
kubectl delete -f route.yaml
kubectl delete service -n n6-k8s-controller-system example-gateway
kubectl delete gateway -n n6-k8s-controller-system example-gatewayGatewayClass通常由多个Gateway共享。只有确认没有其他Gateway引用时,才能删除GatewayClass。建议将共享GatewayClass与业务Gateway分别保存为独立YAML文件,避免删除业务配置时误删共享对象。
常见问题
Gateway没有达到Programmed状态
执行以下命令检查Gateway事件和控制器Pod:
kubectl describe gateway -n n6-k8s-controller-system example-gateway
kubectl get pods -n n6-k8s-controller-system
kubectl logs -n n6-k8s-controller-system <控制器Pod名称> --tail=200重点检查GatewayClass的controllerName、监听端口、控制器镜像和Pod状态。
控制器出现OOMKilled
大量Gateway和Route同时创建时,如果控制器内存上限过低,可能在配置计算期间被OOMKilled。可通过kubectl describe pod确认上次终止原因。应根据资源规模提高控制器Deployment的内存限制,并在Pod重新就绪后重新检查Gateway、Route状态和实际流量。
ClusterIP或NodePort不可达
先检查Service、Endpoint、路由、防火墙和NAT规则:
kubectl get service,endpoints -A
sudo iptables -t nat -L -n
sudo nft -a list table ip raw在K3s节点上,如果raw表存在针对cni0或lo的异常notrack规则,可能绕过连接跟踪并破坏Service NAT,表现为Kubernetes API ClusterIP超时或NodePort拒绝连接。不要直接照搬规则句柄执行删除;应先备份规则并由网络管理员确认规则来源和影响范围,再移除冲突规则。
