Kubernetes: 08-gateway-api
- TAGS: Kubernetes
安装
博文参考:Gateway-API-Setup
- 安装 Gateway API CRD
- Gateway API 的下游实现
- 安装 nginx gateway crd
- 安装 nginx-gateway-fabric
- Gatewayclass
- 创建 gateway
- 部署应用
- 使用 httproute 访问
ingress to gateway 转换工具
方案1:Ingress(2026.3 不维护)
- 创建ingress-controller,创建ingress-entrance: https://kubernetes.github.io/ingress-nginx/
方案2:gateway 之 NGINX Gateway Fabric
安装 gatewayapi crd
- 安装 Gateway API CRD
# 安装标准版 gateway api CRD kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.6.1/standard-install.yaml # 范例 root@ip-172-31-18-198:/docker/nginx/data/site.d# kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.6.1/standard-install.yaml customresourcedefinition.apiextensions.k8s.io/backendtlspolicies.gateway.networking.k8s.io serverside-applied customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io serverside-applied customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io serverside-applied customresourcedefinition.apiextensions.k8s.io/grpcroutes.gateway.networking.k8s.io serverside-applied customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io serverside-applied customresourcedefinition.apiextensions.k8s.io/listenersets.gateway.networking.k8s.io serverside-applied customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking.k8s.io serverside-applied customresourcedefinition.apiextensions.k8s.io/tcproutes.gateway.networking.k8s.io serverside-applied customresourcedefinition.apiextensions.k8s.io/tlsroutes.gateway.networking.k8s.io serverside-applied customresourcedefinition.apiextensions.k8s.io/udproutes.gateway.networking.k8s.io serverside-applied validatingadmissionpolicy.admissionregistration.k8s.io/safe-upgrades.gateway.networking.k8s.io serverside-applied validatingadmissionpolicybinding.admissionregistration.k8s.io/safe-upgrades.gateway.networking.k8s.io serverside-applied root@ip-172-31-18-198:~# kubectl get crd |grep gateway.networking.k8s.io backendtlspolicies.gateway.networking.k8s.io 2026-08-26T09:10:31Z gatewayclasses.gateway.networking.k8s.io 2026-08-26T09:10:31Z gateways.gateway.networking.k8s.io 2026-08-26T09:10:31Z grpcroutes.gateway.networking.k8s.io 2026-08-26T09:10:31Z httproutes.gateway.networking.k8s.io 2026-08-26T09:10:31Z listenersets.gateway.networking.k8s.io 2026-08-26T09:10:32Z referencegrants.gateway.networking.k8s.io 2026-08-26T09:10:32Z tcproutes.gateway.networking.k8s.io 2026-08-26T09:10:32Z tlsroutes.gateway.networking.k8s.io 2026-08-26T09:10:33Z udproutes.gateway.networking.k8s.io 2026-08-26T09:10:33Z
安装 nginx gateway crd
# 安装 NGINX Gateway Fabric CRDs # https://github.com/nginx/nginx-gateway-fabric/tree/v2.6.7/deploy kubectl apply --server-side -f https://raw.githubusercontent.com/nginx/nginx-gateway-fabric/refs/tags/v2.6.7/deploy/crds.yaml # 普通 kubectl apply 是客户端 apply:本地保存一份注解 kubectl.kubernetes.io/last-applied-configuration,用来对比变更。 # --server‑side 是把合并逻辑交给 **k8s APIServer 服务端处理**,不在客户端存大段 last‑applied 注解。 # 范例 root@ip-172-31-18-198:~# kubectl apply --server-side -f https://raw.githubusercontent.com/nginx/nginx-gateway-fabric/refs/tags/v2.6.7/deploy/crds.yaml customresourcedefinition.apiextensions.k8s.io/authenticationfilters.gateway.nginx.org serverside-applied customresourcedefinition.apiextensions.k8s.io/clientsettingspolicies.gateway.nginx.org serverside-applied customresourcedefinition.apiextensions.k8s.io/nginxgateways.gateway.nginx.org serverside-applied customresourcedefinition.apiextensions.k8s.io/nginxproxies.gateway.nginx.org serverside-applied customresourcedefinition.apiextensions.k8s.io/observabilitypolicies.gateway.nginx.org serverside-applied customresourcedefinition.apiextensions.k8s.io/proxysettingspolicies.gateway.nginx.org serverside-applied customresourcedefinition.apiextensions.k8s.io/ratelimitpolicies.gateway.nginx.org serverside-applied customresourcedefinition.apiextensions.k8s.io/snippetsfilters.gateway.nginx.org serverside-applied customresourcedefinition.apiextensions.k8s.io/snippetspolicies.gateway.nginx.org serverside-applied customresourcedefinition.apiextensions.k8s.io/upstreamsettingspolicies.gateway.nginx.org serverside-applied customresourcedefinition.apiextensions.k8s.io/wafpolicies.gateway.nginx.org serverside-applied root@ip-172-31-18-198:~# kubectl get crd |grep nginx authenticationfilters.gateway.nginx.org 2026-08-26T09:37:50Z clientsettingspolicies.gateway.nginx.org 2026-08-26T09:37:50Z nginxgateways.gateway.nginx.org 2026-08-26T09:37:50Z nginxproxies.gateway.nginx.org 2026-08-26T09:37:50Z observabilitypolicies.gateway.nginx.org 2026-08-26T09:37:50Z # 可观测规则 proxysettingspolicies.gateway.nginx.org 2026-08-26T09:37:51Z # 代理设置规则 ratelimitpolicies.gateway.nginx.org 2026-08-26T09:37:51Z # 限速规则 snippetsfilters.gateway.nginx.org 2026-08-26T09:37:51Z snippetspolicies.gateway.nginx.org 2026-08-26T09:37:51Z upstreamsettingspolicies.gateway.nginx.org 2026-08-26T09:37:51Z wafpolicies.gateway.nginx.org 2026-08-26T09:37:51Z # 应用防火墙规则
安装 nginx-gateway-fabric
# mkdir ngfdir cd ngfdir/ # 下载 2.6.7 版本文件。拉取 OCI 格式 Helm chart,解压到本地 helm pull oci://ghcr.io/nginx/charts/nginx-gateway-fabric --version 2.6.7 --untar cd nginx-gateway-fabric/ helm install ngf . \ --create-namespace -n nginx-gateway \ --set nginx.service.type=LoadBalancer \ --set nginx.service.externalTrafficPolicy=Cluster \ --set nginxGateway.snippetsFilters.enable=true # --set nginx.service.type=LoadBalancer 使用负载均衡器。会自动分配公网 LB # --set nginx.service.externalTrafficPolicy=Cluster 外部流量转发策略。 # Cluster(这里配置的):源 IP 会被 SNAT 改写为节点 IP;可以做负载均衡跨节点转发。 # Local:保留真实客户端源 IP,但流量只能落到后端 Pod 所在节点。 # --set nginxGateway.snippetsFilters.enable=true NGF 的扩展能力,可以在 Gateway API 资源中嵌入原生 Nginx 配置片段(nginx.conf 片段)。 root@ip-172-31-18-198:~/.jasper/ngfdir/nginx-gateway-fabric# kubectl get ns |grep gateway nginx-gateway Active 16m root@ip-172-31-18-198:~/.jasper/ngfdir/nginx-gateway-fabric# kubectl get pods -n nginx-gateway NAME READY STATUS RESTARTS AGE ngf-nginx-gateway-fabric-746f6d68fc-hspmf 1/1 Running 0 85s root@ip-172-31-18-198:~/.jasper/ngfdir/nginx-gateway-fabric# kubectl get svc -n nginx-gateway NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ngf-nginx-gateway-fabric ClusterIP 10.210.167.53 <none> 443/TCP 2m7s # 卸载 # helm uninstall ngf -n nginx-gateway # kubectl delete ns nginx-gateway --ignore-not-found
AWS 公网 NLB
root@ip-172-31-18-198:~/.jasper/ngfdir/nginx-gateway-fabric# cat values-dev.yaml
nginx:
config:
# 信任 TCP Proxy‑Protocol v2 四层 NLb
rewriteClientIP:
mode: ProxyProtocol
# AWS VPC CIDR,信任NLB的来源网段
trustedAddresses:
- type: CIDR
value: "172.31.0.0/16"
service:
type: LoadBalancer
externalTrafficPolicy: Cluster
patches:
- type: StrategicMerge
value:
metadata:
annotations:
# 创建公网 nlb
service.beta.kubernetes.io/aws-load-balancer-type: "external"
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
service.beta.kubernetes.io/aws-load-balancer-subnets: "subnet-0a415b6c73,subnet-0efd7596"
service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags: "Env=Dev"
# 让 AWS NLB 向外发 Proxy‑Protocol v2
service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
nginxGateway:
snippetsFilters:
enable: true
# balancer-subnets 为公有子网,pod所在实例安全组允许该网段
helm install ngf . \
--create-namespace -n nginx-gateway \
-f ./values-dev.yaml \
--wait --timeout 5m
# 安装完成后校验 NginxProxy CR 是否渲染正确 patches:
kubectl get nginxproxy ngf-proxy-config -n nginx-gateway -o yaml
Gatewayclass
- 部署完后得到名为 nginx 的 gatewayclass
# 控制器 nginx root@ip-172-31-18-198:~/.jasper/ngfdir/nginx-gateway-fabric# kubectl get gatewayclasses -n nginx-gateway NAME CONTROLLER ACCEPTED AGE nginx gateway.nginx.org/nginx-gateway-controller True 2m55s # nginxproxy 相当说configmap root@ip-172-31-18-198:~/.jasper/ngfdir/nginx-gateway-fabric# kubectl get nginxproxy -n nginx-gateway NAME AGE ngf-proxy-config 4m33s root@ip-172-31-18-198:~/.jasper/ngfdir/nginx-gateway-fabric# kubectl get nginxproxies -n nginx-gateway -oyaml apiVersion: v1 items: - apiVersion: gateway.nginx.org/v1alpha2 kind: NginxProxy metadata: labels: app.kubernetes.io/instance: ngf app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: nginx-gateway-fabric app.kubernetes.io/version: 2.6.7 helm.sh/chart: nginx-gateway-fabric-2.6.7 name: ngf-proxy-config namespace: nginx-gateway spec: ipFamily: dual kubernetes: deployment: container: image: pullPolicy: IfNotPresent repository: ghcr.io/nginx/nginx-gateway-fabric/nginx tag: 2.6.7 replicas: 1 service: externalTrafficPolicy: Cluster type: LoadBalancer kind: List metadata: resourceVersion: ""
创建 gateway
实际上 gateway 是 pod + service 的组合。
cat <<\EOF>> 01-gateway-test.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: nginx-gateway-test namespace: default spec: gatewayClassName: nginx listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All # 允许所有namespace的HTTPRoute绑定这个Gateway。默认为允许当前名称空间的规则 EOF kubectl apply -f 01-gateway-test.yaml # gateway 的地址就是 service 的地址 root@ip-172-31-18-198:~/.jasper/ngfdir# kubectl get gateway NAME CLASS ADDRESS PROGRAMMED AGE nginx-gateway-test nginx k8s-d-1.amazonaws.com True 25m root@ip-172-31-18-198:~/.jasper/ngfdir# kubectl get svc nginx-gateway-test-nginx LoadBalancer 10.210.170.159 k8s-d-1.amazonaws.com 80:31363/TCP
安装多个 gateway 内外网
gateway class 只能有一个。上文 gateway 是公网的,下面添加内网 gateway
先创建 nginxporxy,再创建 gateway
# 创建 nginxporxy cat <<\EOF>> nginxproxy-internal-config.yaml apiVersion: gateway.nginx.org/v1alpha2 kind: NginxProxy metadata: annotations: meta.helm.sh/release-name: ngf meta.helm.sh/release-namespace: nginx-gateway labels: app.kubernetes.io/instance: ngf app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: nginx-gateway-fabric app.kubernetes.io/version: 2.6.7 helm.sh/chart: nginx-gateway-fabric-2.6.7 name: nginxproxy-internal-config namespace: default spec: ipFamily: dual kubernetes: deployment: container: image: pullPolicy: IfNotPresent repository: ghcr.io/nginx/nginx-gateway-fabric/nginx tag: 2.6.7 replicas: 1 service: externalTrafficPolicy: Cluster patches: - type: StrategicMerge value: metadata: annotations: service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags: Env=Dev service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: '*' service.beta.kubernetes.io/aws-load-balancer-scheme: internal service.beta.kubernetes.io/aws-load-balancer-subnets: subnet-01c,subnet-0b,subnet-03 service.beta.kubernetes.io/aws-load-balancer-type: external service.beta.kubernetes.io/aws-load-balancer-attributes: load_balancing.cross_zone.enabled=true type: LoadBalancer rewriteClientIP: mode: ProxyProtocol trustedAddresses: - type: CIDR value: 172.31.0.0/16 EOF # 创建内网 gateway cat <<\EOF>> ng-internal-gateway.yaml apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: gateway-internal namespace: default spec: gatewayClassName: nginx infrastructure: parametersRef: group: gateway.nginx.org kind: NginxProxy name: nginxproxy-internal-config listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All EOF
部署应用
# 部署 echo ,打印请求信息 cat > 02-deploy-test.yaml <<\EOF apiVersion: apps/v1 kind: Deployment metadata: name: echo namespace: default spec: replicas: 1 selector: matchLabels: app: echo template: metadata: labels: app: echo spec: containers: - name: echo image: ealen/echo-server:latest ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: echo-svc namespace: default spec: selector: app: echo ports: - port: 80 targetPort: 80 name: http type: ClusterIP EOF kubectl apply -f 02-deploy-test.yaml
使用 httproute 访问
# 创建 gateway 规则 cat <<\EOF>> 03-httproute.yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: ngfapp-httproute namespace: default spec: parentRefs: - name: nginx-gateway-test namespace: default hostnames: - "www.echo.com" rules: - backendRefs: - name: echo-svc port: 80 kind: Service matches: - path: type: PathPrefix value: / EOF root@ip-172-31-18-198:~/.jasper/ngfdir# kubectl apply -f 03-httproute.yaml root@ip-172-31-18-198:~/.jasper/ngfdir# kubectl get httproute NAME HOSTNAMES AGE echo-route ["www.echo.com"] 11m # 排查。查看 gateway 对应的 pod 日志。 kubectl logs -f nginx-gateway-test-nginx-79d64d4cc4-kcp5q # 查看 nginx 配置文件 root@ip-172-31-18-198:~/.jasper/ngfdir# kubectl exec -it nginx-gateway-test-nginx-79d64d4cc4-kcp5q -c nginx -- nginx -T nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful # configuration file /etc/nginx/nginx.conf: load_module modules/ngx_http_js_module.so; include /etc/nginx/main-includes/*.conf; worker_processes auto; pid /var/run/nginx/nginx.pid;
访问
- 本机域名解析。修改
/etc/hosts - 浏览器访问
http://www.echo.com
# 真实客户端 ip "headers": { "host": "www.echo.com", "x-forwarded-for": "1.1.162.204", "x-real-ip": "1.1.162.204", # 或在 pod echo 所在主机使用 tcpdump 命令查看 tcpdump -i any -nn -vvv -A dst host 172.31.82.72 and port 80 |grep -C50 echo
配置
Rewrite 路径重写
ingress-nginx
# 都重写为 $2 路径 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/proxy-http-version: "1.1" nginx.ingress.kubernetes.io/rewrite-target: /$2 nginx.ingress.kubernetes.io/ssl-redirect: "false" nginx.ingress.kubernetes.io/use-regex: "true" name: gateway-ingress namespace: default spec: ingressClassName: nginx rules: - host: devg.xxx.me http: paths: - backend: service: name: cloud-gateway port: number: 8080 path: /(api)/(.*) pathType: ImplementationSpecific - backend: service: name: wallet-admin-server port: number: 8080 path: /(api)/alpha/v1/(system/exchangeRateFacede/.*) pathType: ImplementationSpecific
转为对应 gatewai api
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: gateway-httproute
namespace: default
spec:
hostnames:
- devg.xxx.me
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: nginx-gateway-test
namespace: default
rules:
- backendRefs:
- group: ""
kind: Service
name: cloud-gateway
port: 8080
weight: 1
filters:
- type: URLRewrite
urlRewrite:
path:
replacePrefixMatch: /
type: ReplacePrefixMatch
matches:
- path:
type: PathPrefix
value: /api/
- backendRefs:
- group: ""
kind: Service
name: wallet-admin-server
port: 8080
weight: 1
filters:
- type: URLRewrite
urlRewrite:
path:
replacePrefixMatch: /system/exchangeRateFacede/
type: ReplacePrefixMatch
matches:
- path:
type: PathPrefix
value: /api/alpha/v1/system/exchangeRateFacede/
上传限制
- https://gateway-api.sigs.k8s.io/geps/gep-713/
- nginx gateway fabric Custom policies
cat h5-web-antd-httproute.yaml
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: h5-web-antd-httproute
namespace: default
spec:
hostnames:
- xxx.com
- devpt.xxx.com
parentRefs:
- name: nginx-gateway-test
namespace: default
rules:
- backendRefs:
- name: h5-web-antd-svc
port: 80
matches:
- path:
type: PathPrefix
value: /
---
apiVersion: gateway.nginx.org/v1alpha1
kind: ClientSettingsPolicy
metadata:
name: h5-web-antd-client-policy
namespace: default
spec:
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
name: h5-web-antd-httproute
body:
maxSize: "100m"
kubectl get clientsettingspolicies.gateway.nginx.org h5-web-antd-client-policy
# 查看 nginx 对应配置
kubectl exec nginx-gateway-test-nginx-5f5dcf8454-9tdlp -c nginx -- nginx -T
server {
listen 80 proxy_protocol;
listen [::]:80 proxy_protocol;
server_name devpt.xxx.com;
set_real_ip_from 172.31.0.0/16;
real_ip_header proxy_protocol;
location / {
include /etc/nginx/includes/ClientSettingsPolicy_default_h5-web-antd-client-policy.conf;
# configuration file /etc/nginx/includes/ClientSettingsPolicy_default_h5-web-antd-client-policy.conf:
client_max_body_size 100m;