通过Envoy Gateway提供服务访问
Gateway API是Kubernetes官方提供的下一代的路由和负载均衡API,CCE提供了Envoy Gateway插件,使用基于Envoy实现的Gateway API方案,深度兼容Kubernetes官方Gateway API,支持配置诸多流量转发规则。本文介绍Envoy Gateway支持的一些基础能力及配置方法。
注意事项
- 创建Gateway对象时将使用Envoy Gateway插件中的配置自动创建负载均衡器。自动创建的负载均衡实例按需计费。
- Envoy Gateway插件安装后将自动创建一个名为enovy-gateway的GatewayClass,卸载后会保留,请不要手动删除。卸载后若需清理GatewayClass,必须在无关联Gateway的前提下手动清除其finalizers再删除,否则重装插件后可能会导致资源消失或功能异常。
- 删除自定义GatewayClass前,需要删除该GatewayClass关联的Gateway。
- 卸载插件不会删除已创建的Gateway资源及该Gateway的相关资源(涉及Deployment、Service、ConfigMap、ServiceAccount),建议在卸载插件前手动清理插件管理的Gateway资源。插件卸载后,删除Gateway时是否同时删除相关资源会由Envoy Gateway的数据面部署模式决定,在插件默认配置下,删除Gateway会同时删除其关联资源。
- 在CCE Standard集群中,Envoy Gateway插件对接独享型ELB时,插件控制器Pod(和Gateway同命名空间且同名)所在节点以及该节点上的其他容器无法使用ELB的私网地址访问路由。
- 插件配置完成后,其关联的ELB配置将持久化在插件的ConfigMap中。随后,插件实例通过内置的监听机制(Watch)实时捕获ConfigMap的变更,并自动将最新配置同步至插件内部。因此,插件更新负载均衡配置后,通常需要数十秒后生效。
前提条件
- 当前集群已安装Envoy Gateway插件,并且插件状态为运行中。
- 集群中已创建后端应用及对应的Service。 本文中后端应用为Nginx,Service名称为backend,Service端口为3000。您可以将以下YAML内容保存为backend.yaml,然后执行kubectl apply -f backend.yaml命令。
apiVersion: apps/v1 kind: Deployment metadata: name: backend namespace: default spec: replicas: 2 selector: matchLabels: app: backend version: v1 template: metadata: labels: app: backend version: v1 spec: containers: - name: container-1 image: nginx:latest imagePullSecrets: - name: default-secret --- apiVersion: v1 kind: Service metadata: name: backend labels: app: backend version: v1 namespace: default spec: selector: app: backend version: v1 ports: - name: cce-service-0 targetPort: 80 port: 3000 protocol: TCP type: ClusterIP
步骤一:创建Gateway
- 登录CCE控制台,单击集群名称进入集群。
- 选择左侧导航栏的“服务”,在右侧选择“网关 API”页签。
- 在“网关(Gateway)”页签下,单击“YAML创建”,填写Gateway YAML。 关于Gateway的完整参数定义,请参见Gateway。示例如下:
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway #Gateway名称 namespace: default spec: gatewayClassName: envoy-gateway #GatewayClass名称 listeners: - name: http protocol: HTTP #协议 port: 80 #监听端口在此示例中,该Gateway会根据插件中定义的ELB配置自动创建ELB,并为此ELB创建协议为HTTP、端口为80的监听器。
- 单击“提交”。等待ELB及监听器自动创建完成后,Gateway状态变为正常。

步骤二:创建HTTPRoute
- 登录CCE控制台,单击集群名称进入集群。
- 选择左侧导航栏的“服务”,在右侧选择“网关 API”页签。
- 在“路由(HTTPRoute)”页签下,单击“YAML创建”,填写HTTPRoute YAML。 关于HTTPRoute的完整参数定义,请参见HTTPRoute。示例如下:
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute #资源类型为HTTPRoute metadata: name: backend #HTTPRoute名称 namespace: default spec: parentRefs: - name: my-gateway #Gateway名称 hostnames: - "www.example.com" #域名 rules: - backendRefs: - group: "" kind: Service name: backend #已创建的service名称 port: 3000 #service的端口 weight: 1在此示例中,来自Gateway的HTTP流量, 访问域名为www.example.com将被路由到Service的3000端口。
- 单击“提交”。HTTPRoute创建完成后,返回“网关(Gateway)”页签,单击关联的Gateway名称,已添加相应的路由。

步骤三:测试访问
- 查看Gateway关联的ELB公网地址。

您也可以通过命令行获取,其中my-gateway为Gateway名称:
kubectl get gateway/my-gateway -o jsonpath='{.status.addresses[0].value}' - 测试访问,其中xx.xx.xx.xx为ELB公网地址。
curl -I -H "Host: www.example.com" http://xx.xx.xx.xx预期回显如下:
HTTP/1.1 200 OK server: nginx/1.23.2 date: Thu, 28 May 2026 01:47:02 GMT content-type: text/html content-length: 615 last-modified: Wed, 19 Oct 2022 07:56:21 GMT etag: "634fada5-267" accept-ranges: bytes
更多场景
Gateway中添加HTTPS访问
- 使用证书创建kubernetes.io/tls类型的Secret,具体操作步骤请参见创建密钥。
本示例中使用自签名证书,创建的Secret名称为example-cert。
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example.com.key -out example.com.crt openssl req -out www.example.com.csr -newkey rsa:2048 -nodes -keyout www.example.com.key -subj "/CN=www.example.com/O=example organization" openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in www.example.com.csr -out www.example.com.crt
使用生成的证书创建Secret。
kubectl create secret tls example-cert --key=www.example.com.key --cert=www.example.com.crt
- 在Gateway资源中添加HTTPS访问并配置证书。 示例如下:
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway #Gateway名称 namespace: default spec: gatewayClassName: envoy-gateway #GatewayClass名称 listeners: - name: http protocol: HTTP #HTTP协议 port: 80 #监听端口 - name: https protocol: HTTPS #HTTPS协议 port: 443 #监听端口 tls: certificateRefs: #TLS证书 - group: "" kind: Secret name: example-cert #Secret名称 mode: Terminate - 等待ELB及监听器自动创建完成后,Gateway状态变为正常,单击Gateway名称,已添加HTTPS协议的监听器。

- 测试访问,其中xx.xx.xx.xx为ELB公网地址。
curl -I --cacert example.com.crt --resolve www.example.com:443:xx.xx.xx.xx https://www.example.com预期回显如下:
HTTP/2 200 server: nginx/1.23.2 date: Thu, 28 May 2026 02:32:57 GMT content-type: text/html content-length: 615 last-modified: Wed, 19 Oct 2022 07:56:21 GMT etag: "634fada5-267" accept-ranges: bytes
HTTPRoute中使用路径前缀匹配
- 更新示例应用,添加/test访问路径。
路径匹配要求后端应用内存在相同的路径,否则会返回404。
例如,Nginx应用默认的Web访问路径为“/usr/share/nginx/html”,如果使用“/test”路径进行前缀匹配,需要应用的Web访问路径下也包含相同路径,即“/usr/share/nginx/html/test”,否则将返回404。
应用示例如下,使用启动命令在“/usr/share/nginx/html/test”路径下写入内容,返回内容为“This is a test.”:apiVersion: apps/v1 kind: Deployment metadata: name: backend namespace: default spec: replicas: 2 selector: matchLabels: app: backend version: v1 template: metadata: labels: app: backend version: v1 spec: containers: - name: container-1 image: nginx:latest command: ["/bin/sh", "-c"] args: - echo "This is a test." > /usr/share/nginx/html/test && nginx -g "daemon off;" # 添加test访问路径 imagePullSecrets: - name: default-secret - 更新HTTPRoute资源。
以下示例配置HTTPRoute匹配/test前缀:
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute #资源类型为HTTPRoute metadata: name: backend #HTTPRoute名称 namespace: default spec: parentRefs: - name: my-gateway #Gateway名称 hostnames: - "www.example.com" #域名 rules: - backendRefs: - group: "" kind: Service name: backend #已创建的service名称 port: 3000 #service的端口 weight: 1 matches: - path: type: PathPrefix #前缀匹配 value: /test #路径为test - 测试访问,其中xx.xx.xx.xx为ELB公网地址。
curl -i -H "Host: www.example.com" http://xx.xx.xx.xx/test预期回显如下:
HTTP/1.1 200 OK server: nginx/1.23.2 date: Thu, 28 May 2026 03:22:10 GMT content-type: application/octet-stream content-length: 16 last-modified: Thu, 28 May 2026 03:15:51 GMT etag: "6a17b367-10" accept-ranges: bytes This is a test.
HTTPRoute中设置按比例分发请求
本文示例中创建一个HTTPRoute配置,同时设置backend1和backend2的路由规则,并为backend1和backend2服务配置权重。
Gateway API所有请求的流量将按照“单个服务的权重/所有服务的权重之和”的比例进行分配。
- 创建两个示例应用,分别为backend1和backend2。 应用示例如下:
apiVersion: apps/v1 kind: Deployment metadata: name: backend1 namespace: default spec: replicas: 2 selector: matchLabels: app: backend1 version: v1 template: metadata: labels: app: backend1 version: v1 spec: containers: - name: container-1 image: nginx:latest command: ["/bin/sh", "-c"] args: - echo "This is backend1." > /usr/share/nginx/html/index.html && nginx -g "daemon off;" # 默认返回内容为backend1 imagePullSecrets: - name: default-secret --- apiVersion: v1 kind: Service metadata: name: backend1 labels: app: backend1 version: v1 namespace: default spec: selector: app: backend1 version: v1 ports: - name: cce-service-0 targetPort: 80 port: 3000 protocol: TCP type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: backend2 namespace: default spec: replicas: 2 selector: matchLabels: app: backend2 version: v1 template: metadata: labels: app: backend2 version: v1 spec: containers: - name: container-1 image: nginx:latest command: ["/bin/sh", "-c"] args: - echo "This is backend2." > /usr/share/nginx/html/index.html && nginx -g "daemon off;" # 默认返回内容为backend2 imagePullSecrets: - name: default-secret --- apiVersion: v1 kind: Service metadata: name: backend2 labels: app: backend2 version: v1 namespace: default spec: selector: app: backend2 version: v1 ports: - name: cce-service-0 targetPort: 80 port: 3000 protocol: TCP type: ClusterIP - 更新HTTPRoute资源,添加backend1和backend2的路由,并分别设置权重为2和8。
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute #资源类型为HTTPRoute metadata: name: backend #HTTPRoute名称 namespace: default spec: parentRefs: - name: my-gateway #Gateway名称 hostnames: - "www.example.com" #域名 rules: - backendRefs: - group: "" kind: Service name: backend1 #已创建的service名称 port: 3000 #service的端口 weight: 2 #设置权重为2 - group: "" kind: Service name: backend2 #已创建的service名称 port: 3000 #service的端口 weight: 8 #设置权重为8 - 测试连续访问20次,查看两个服务的比例,其中xx.xx.xx.xx为ELB公网地址。
for i in $(seq 1 20); do curl -sS -H "Host: www.example.com" http://xx.xx.xx.xx/; done预期输出如下,backend1服务接收到的流量比例大致为20%, backend2服务接收到的流量比例大致为80%。
This is backend2. This is backend2. This is backend2. This is backend1. This is backend1. This is backend2. This is backend2. This is backend2. This is backend2. This is backend2. This is backend2. This is backend2. This is backend1. This is backend2. This is backend2. This is backend2. This is backend2. This is backend1. This is backend2. This is backend2.
HTTPRoute中按请求Header进行转发
Envoy Gateway支持按请求Header进行转发,本文示例中设置以下场景进行演示:
- 请求头为x-env: test时,转发到backend-1服务
- 请求头为x-env: prod时,转发到backend-2服务
- 其他请求默认转发到backend服务
- 创建两个示例应用,分别为backend1和backend2。 应用示例如下:
apiVersion: apps/v1 kind: Deployment metadata: name: backend1 namespace: default spec: replicas: 2 selector: matchLabels: app: backend1 version: v1 template: metadata: labels: app: backend1 version: v1 spec: containers: - name: container-1 image: nginx:latest command: ["/bin/sh", "-c"] args: - echo "This is backend1." > /usr/share/nginx/html/index.html && nginx -g "daemon off;" # 默认返回内容为backend1 imagePullSecrets: - name: default-secret --- apiVersion: v1 kind: Service metadata: name: backend1 labels: app: backend1 version: v1 namespace: default spec: selector: app: backend1 version: v1 ports: - name: cce-service-0 targetPort: 80 port: 3000 protocol: TCP type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: backend2 namespace: default spec: replicas: 2 selector: matchLabels: app: backend2 version: v1 template: metadata: labels: app: backend2 version: v1 spec: containers: - name: container-1 image: nginx:latest command: ["/bin/sh", "-c"] args: - echo "This is backend2." > /usr/share/nginx/html/index.html && nginx -g "daemon off;" # 默认返回内容为backend2 imagePullSecrets: - name: default-secret --- apiVersion: v1 kind: Service metadata: name: backend2 labels: app: backend2 version: v1 namespace: default spec: selector: app: backend2 version: v1 ports: - name: cce-service-0 targetPort: 80 port: 3000 protocol: TCP type: ClusterIP - 更新HTTPRoute配置,按请求Header进行转发。
示例如下:
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: backend namespace: default spec: parentRefs: - name: my-gateway hostnames: - "www.example.com" rules: # 规则1:Header x-env = test → 测试环境backend1 - matches: - headers: - name: x-env value: test # 精确匹配值 type: Exact # 支持Exact(精确匹配,默认)、Prefix(前缀匹配)、RegularExpression(正则匹配) path: type: PathPrefix value: / backendRefs: - group: "" kind: Service name: backend1 port: 3000 # 规则2:Header x-env = prod → 生产环境backend2 - matches: - headers: - name: x-env value: prod # 精确匹配值 type: Exact # 支持Exact(精确匹配,默认)、Prefix(前缀匹配)、RegularExpression(正则匹配) path: type: PathPrefix value: / backendRefs: - group: "" kind: Service name: backend2 port: 3000 # 规则3:默认路由(无匹配Header时) - matches: - path: type: PathPrefix value: / backendRefs: - group: "" kind: Service name: backend port: 3000 - 测试带有请求头x-env: test进行访问:
curl -i -H "Host: www.example.com" -H "x-env: test" http://xx.xx.xx.xx/预期输出如下:
HTTP/1.1 200 OK server: nginx/1.23.2 date: Sat, 30 May 2026 10:09:03 GMT content-type: text/html content-length: 18 last-modified: Thu, 28 May 2026 06:49:53 GMT etag: "6a17e591-12" accept-ranges: bytes This is backend1.
结果显示访问到后端服务backend1,符合预期。
- 测试带有请求头x-env: prod进行访问:
curl -i -H "Host: www.example.com" -H "x-env: prod" http://xx.xx.xx.xx预期输出如下:
HTTP/1.1 200 OK server: nginx/1.23.2 date: Sat, 30 May 2026 10:09:01 GMT content-type: text/html content-length: 18 last-modified: Thu, 28 May 2026 07:07:17 GMT etag: "6a17e9a5-12" accept-ranges: bytes This is backend2.
结果显示访问到后端服务backend2,符合预期。
HTTPRoute中只指定Gateway中的某个监听器
HTTPRoute配置中,可通过sectionName或者port字段来指定当前转发策略绑定的端口。
- 更新HTTPRoute资源。
示例如下,只绑定Gateway下名为http且端口为80的监听器:
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: my-route namespace: default spec: parentRefs: - name: my-gateway sectionName: http # 只绑定名为 "http" 的监听器 port: 80 # 只绑定端口 80 的监听器 hostnames: - "www.example.com" #域名 rules: - backendRefs: - group: "" kind: Service name: backend #已创建的service名称 port: 3000 #service的端口 weight: 1- sectionName或者port字段非必填,不填写时,默认绑定Gateway下的所有端口。
- sectionName="http"时会绑定Gateway下name="http"的端口。
- port="80"时会绑定Gateway下port="80"的端口。
- 同时配置sectionName="http"和port="80"时,则会绑定Gateway下name="http"并且port="80"的端口。
- HTTPRoute创建完成后,返回“网关(Gateway)”页签,单击关联的Gateway名称,相应的路由只添加到80端口的监听器。

自定义EnvoyProxy来为Gateway配置已有ELB
- 创建自定义EnvoyProxy
- 关联自定义的EnvoyProxy
- 方式一:GatewayClass关联EnvoyProxy
- 创建GatewayClass:
apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: my-gateway-class spec: controllerName: gateway.envoyproxy.io/gatewayclass-controller parametersRef: group: gateway.envoyproxy.io kind: EnvoyProxy name: dev-proxy-config # 创建的自定义EnvoyProxy名称 namespace: default # EnvoyProxy命名空间 - 创建Gateway:
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway #gateway名称 namespace: default spec: gatewayClassName: my-gateway-class #创建的gatewayClass名称 listeners: - name: http protocol: HTTP #协议 port: 80 #监听端口 - name: http-2 protocol: HTTP #协议 port: 81 #监听端口
- 创建GatewayClass:
- 方式二:Gateway关联EnvoyProxy
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: my-gateway namespace: default spec: gatewayClassName: envoy-gateway #插件创建的gatewayClass名称 infrastructure: parametersRef: group: gateway.envoyproxy.io kind: EnvoyProxy name: dev-proxy-config # 创建的自定义EnvoyProxy名称 listeners: - name: http protocol: HTTP port: 82
- 方式一:GatewayClass关联EnvoyProxy
- 前往CCE控制台,查看“网关(Gateway)”页面中新建Gateway关联的ELB是否为已有ELB。
使用已有ELB时,不同的Gateway不能设置为相同端口,否则Gateway会产生状态异常。