【Kubernetes】(二十)Gateway

目录

[一、为什么需要 Gateway?先搞懂 "流量入口" 的进化史](#一、为什么需要 Gateway?先搞懂 “流量入口” 的进化史)

[二、Gateway API 核心组件:理清 "谁在做什么"](#二、Gateway API 核心组件:理清 “谁在做什么”)

[1. GatewayClass:网关的 "模板"](#1. GatewayClass:网关的 “模板”)

[2. Gateway:实际的 "流量入口"](#2. Gateway:实际的 “流量入口”)

[3. Route:流量的 "导航规则"](#3. Route:流量的 “导航规则”)

[三、Gateway 实战:从部署到访问](#三、Gateway 实战:从部署到访问)

[1. 部署 Nginx Gateway Fabric](#1. 部署 Nginx Gateway Fabric)

[2. 创建 GatewayClass 和 Gateway](#2. 创建 GatewayClass 和 Gateway)

[3. 部署后端服务和 HTTPRoute](#3. 部署后端服务和 HTTPRoute)

[4. 测试访问](#4. 测试访问)

[四、Gateway 的进阶特性:不止于 "转发"](#四、Gateway 的进阶特性:不止于 “转发”)

[1. HTTPS 终止(SSL/TLS)](#1. HTTPS 终止(SSL/TLS))

[2. 流量灰度(权重路由)](#2. 流量灰度(权重路由))

[3. 跨命名空间路由](#3. 跨命名空间路由)

[4. 健康检查与重试](#4. 健康检查与重试)

[五、总结:Gateway 为什么是未来?](#五、总结:Gateway 为什么是未来?)


在 Kubernetes(简称 K8s)生态中,"如何让外部流量安全、高效地访问集群内服务" 一直是核心需求之一。从早期的 Service、Ingress 到如今的 Gateway API,K8s 在流量管理领域不断进化,而Gateway作为新一代流量入口标准,凭借其灵活性、扩展性和标准化特性,逐渐成为企业级 K8s 集群的首选方案。今天我们就从概念入手,拆解 Gateway 的核心能力,再通过实战案例带你掌握其落地方法。

一、为什么需要 Gateway?先搞懂 "流量入口" 的进化史

在聊 Gateway 之前,我们得先明白:K8s 为什么要推出 Gateway?它解决了之前方案的哪些痛点?

早期 K8s 中,服务暴露主要依赖Service:ClusterIP 用于集群内通信,NodePort 通过节点端口暴露服务,LoadBalancer 则依赖云厂商的负载均衡器。但这些方案存在明显局限 ------ 比如 NodePort 端口管理混乱、LoadBalancer 成本高且仅支持四层负载;而 Ingress 作为 "七层流量入口",虽然实现了域名路由、SSL 终止等功能,但又面临新问题:

  • 功能固化:Ingress 仅支持 HTTP/HTTPS 路由,无法满足 TCP/UDP、gRPC 等非 HTTP 协议的需求;
  • 扩展性差:不同 Ingress 控制器(如 Nginx Ingress、Traefik)自定义配置差异大,缺乏统一标准,跨控制器迁移成本高;
  • 权限割裂:Ingress 资源将 "路由规则" 和 "负载均衡器配置" 绑定在一起,运维团队(管负载均衡)和开发团队(管路由)无法分工协作。

为解决这些问题,K8s 社区推出了Gateway API (当前已进入 GA 阶段,即稳定版),而 Gateway 就是 Gateway API 体系中的核心资源之一。它的核心设计理念是 "分离关注点":将 "流量入口基础设施"(如负载均衡器、网关实例)和 "路由规则" 拆分开,同时支持多协议、多团队协作,彻底打破了 Ingress 的局限性。

二、Gateway API 核心组件:理清 "谁在做什么"

Gateway API 不是单一资源,而是一套 "资源组合",核心包括GatewayClassGatewayRoute三类资源,三者分工明确,共同实现流量管理。

1. GatewayClass:网关的 "模板"

GatewayClass 是 "集群级" 资源,相当于网关的 "模板定义",它指定了当前网关使用的 "控制器实现"(比如 Nginx Gateway Fabric、Traefik Gateway、Istio Gateway 等),以及该类网关的通用配置(如负载均衡器类型、资源限制)。

简单来说:一个 GatewayClass 对应一种 "网关产品",比如 "nginx-gateway-class" 对应 Nginx Gateway Fabric 控制器,"traefik-gateway-class" 对应 Traefik 控制器。集群中可以有多个 GatewayClass,供不同业务场景选择。

示例:定义一个基于 Nginx Gateway Fabric 的 GatewayClass

复制代码
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: nginx-gateway-class  # GatewayClass的名称,后续Gateway会引用它
spec:
  controllerName: nginx.org/gateway-controller  # 对应的控制器标识
  parametersRef:  # 可选,指定该类网关的通用参数(如负载均衡器配置)
    apiGroup: k8s.gateway.nginx.org
    kind: GatewayClassParameters
    name: nginx-gateway-params

2. Gateway:实际的 "流量入口"

Gateway 是 "命名空间级" 资源,它基于 GatewayClass 创建,代表一个 "实际运行的网关实例"------ 比如云厂商的负载均衡器、集群内的 NginxPod 集群。Gateway 的核心作用是 "暴露流量入口",比如绑定公网 IP、监听特定端口(如 80、443),并定义该入口支持的协议(HTTP、HTTPS、TCP 等)。

举个例子:创建一个监听 80 端口(HTTP)的 Gateway,使用上面定义的 "nginx-gateway-class" 模板

复制代码
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: demo-gateway
  namespace: default  # Gateway属于特定命名空间
spec:
  gatewayClassName: nginx-gateway-class  # 引用已定义的GatewayClass
  listeners:  # 定义"监听规则",即网关如何接收流量
    - name: http-listener  # 监听名称(自定义)
      protocol: HTTP  # 支持的协议(HTTP/HTTPS/TCP/UDP等)
      port: 80  # 监听端口
      allowedRoutes:  # 控制哪些Route可以绑定到该Gateway
        namespaces:
          from: Same  # 仅允许同一命名空间的Route绑定(可选:All/Selector)

创建 Gateway 后,控制器会自动创建对应的基础设施 ------ 比如 Nginx Gateway Fabric 会在集群内启动 Nginx Pod,并通过 Service(可能是 LoadBalancer 类型)暴露公网 IP。我们可以通过kubectl get gateway demo-gateway查看 Gateway 状态,当STATUSReady时,说明网关实例已就绪,且会显示ADDRESS(即公网访问 IP)。

3. Route:流量的 "导航规则"

Route 是 "命名空间级" 资源,用于定义 "流量如何转发到后端服务",相当于 Ingress 中的 "rules",但支持更多协议类型。根据协议不同,Route 分为多种类型:

  • HTTPRoute:处理 HTTP/HTTPS 流量,支持路径匹配、域名匹配、请求头匹配、重定向、重试等;
  • TCPRoute/UDPRoute:处理 TCP/UDP 流量(如数据库、消息队列);
  • GRPCRoute:专门处理 gRPC 流量,支持 gRPC 方法匹配。

Route 需要通过 "parentRef" 绑定到某个 Gateway,只有绑定成功后,规则才会生效。

示例:创建一个 HTTPRoute,将 "demo.example.com" 域名的流量转发到后端 "demo-service" 服务

复制代码
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: demo-httproute
  namespace: default
spec:
  parentRefs:  # 绑定到前面创建的Gateway
    - name: demo-gateway
      namespace: default
      sectionName: http-listener  # 绑定到Gateway的某个listener(可选)
  hostnames:  # 匹配的域名(支持通配符,如*.example.com)
    - "demo.example.com"
  rules:  # 路由规则
    - matches:  # 流量匹配条件(可选,不写则匹配所有流量)
        - path:
            type: PathPrefix  # 路径匹配类型:Prefix/Exact/RegularExpression
            value: /api  # 匹配以"/api"开头的路径
      backendRefs:  # 转发到的后端服务
        - name: demo-service  # 后端Service名称
          port: 8080  # Service端口
          weight: 100  # 权重(用于灰度发布,默认100)

三、Gateway 实战:从部署到访问

光说理论不够,我们通过 "Nginx Gateway Fabric"(Nginx 官方的 Gateway 控制器)来实战,完整流程包括 "部署控制器→创建 GatewayClass→创建 Gateway→创建 HTTPRoute→测试访问"。

1. 部署 Nginx Gateway Fabric

首先参考Nginx Gateway Fabric 官方文档,通过 Helm 部署控制器(确保集群已安装 Helm):

bash 复制代码
# 添加Nginx Helm仓库
helm repo add nginx-stable https://helm.nginx.com/stable
helm repo update

# 部署Nginx Gateway Fabric(默认命名空间为nginx-gateway)
helm install nginx-gateway nginx-stable/nginx-gateway \
  --namespace nginx-gateway \
  --create-namespace

部署完成后,检查控制器 Pod 是否正常运行:

复制代码
kubectl get pods -n nginx-gateway
# 输出应包含"nginx-gateway-xxxxxx",且STATUS为Running

2. 创建 GatewayClass 和 Gateway

参考前面的示例,创建 GatewayClass 和 Gateway:

复制代码
# gateway-class.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: nginx-gateway-class
spec:
  controllerName: nginx.org/gateway-controller
---
# gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: demo-gateway
  namespace: default
spec:
  gatewayClassName: nginx-gateway-class
  listeners:
    - name: http-listener
      protocol: HTTP
      port: 80
      allowedRoutes:
        namespaces:
          from: Same

应用配置:

复制代码
kubectl apply -f gateway-class.yaml
kubectl apply -f gateway.yaml

查看 Gateway 状态,获取公网 IP:

复制代码
kubectl get gateway demo-gateway
# 示例输出:
# NAME          CLASS                  ADDRESS         READY   AGE
# demo-gateway  nginx-gateway-class    1.2.3.4         True    5m
# 其中"ADDRESS"就是网关的公网访问IP

3. 部署后端服务和 HTTPRoute

先部署一个简单的后端服务(用 nginx 镜像模拟):

复制代码
# demo-service.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-deployment
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
---
apiVersion: v1
kind: Service
metadata:
  name: demo-service
  namespace: default
spec:
  selector:
    app: demo
  ports:
  - port: 8080
    targetPort: 80  # 容器内nginx的端口是80

再创建 HTTPRoute,绑定到 Gateway:

复制代码
# http-route.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: demo-httproute
  namespace: default
spec:
  parentRefs:
    - name: demo-gateway
      namespace: default
  hostnames:
    - "demo.example.com"  # 自定义域名,后续需要配置hosts解析
  rules:
    - backendRefs:
        - name: demo-service
          port: 8080

应用配置:

复制代码
kubectl apply -f demo-service.yaml
kubectl apply -f http-route.yaml

4. 测试访问

由于我们使用了自定义域名 "demo.example.com",需要先在本地配置 hosts(将域名解析到 Gateway 的公网 IP):

复制代码
# 编辑本地hosts文件(Windows:C:\Windows\System32\drivers\etc\hosts;Linux/Mac:/etc/hosts)
1.2.3.4  demo.example.com  # 替换1.2.3.4为Gateway的ADDRESS

然后通过 curl 或浏览器访问:

复制代码
curl http://demo.example.com
# 输出应包含nginx的默认页面内容,说明流量已成功转发到后端服务

四、Gateway 的进阶特性:不止于 "转发"

除了基础的流量转发,Gateway 还支持多种企业级特性,满足复杂业务场景需求:

1. HTTPS 终止(SSL/TLS)

Gateway 可以直接处理 HTTPS 流量,在网关层完成 SSL 终止,后端服务只需处理 HTTP 流量,减少服务端压力。实现方式是在 Gateway 的 listener 中配置 "tls" 字段,并引用 Secret 中的证书:

复制代码
# 先创建包含HTTPS证书的Secret(假设证书文件为tls.crt和tls.key)
kubectl create secret tls demo-tls-secret --cert=tls.crt --key=tls.key -n default

# 然后更新Gateway的listener,启用HTTPS
spec:
  listeners:
    - name: https-listener
      protocol: HTTPS
      port: 443
      allowedRoutes:
        namespaces:
          from: Same
      tls:  # HTTPS配置
        mode: Terminate  # 网关层终止SSL
        certificateRefs:  # 引用证书Secret
          - kind: Secret
            name: demo-tls-secret

2. 流量灰度(权重路由)

通过 HTTPRoute 的 "weight" 字段,可以实现流量灰度发布 ------ 比如将 10% 流量转发到新版本服务,90% 流量保留在旧版本:

复制代码
spec:
  rules:
    - backendRefs:
        - name: demo-service-v1  # 旧版本服务
          port: 8080
          weight: 90  # 90%流量
        - name: demo-service-v2  # 新版本服务
          port: 8080
          weight: 10  # 10%流量

3. 跨命名空间路由

默认情况下,Gateway 只允许绑定同一命名空间的 Route,但通过 "allowedRoutes.namespaces.from: All" 或 "Selector",可以支持跨命名空间路由,方便多团队共享网关:

复制代码
# 更新Gateway的listener配置
spec:
  listeners:
    - name: http-listener
      protocol: HTTP
      port: 80
      allowedRoutes:
        namespaces:
          from: All  # 允许所有命名空间的Route绑定
          # 或通过Selector限制:
          # from: Selector
          # selector:
          #   matchLabels:
          #     team: dev

4. 健康检查与重试

部分 Gateway 控制器(如 Nginx Gateway Fabric、Traefik)支持配置后端服务的健康检查和请求重试 ------ 当后端服务异常时,自动切换到健康实例,并重试失败的请求,提升服务可用性。配置通常通过控制器自定义的 CRD(如 Nginx 的 GatewayClassParameters)实现。

五、总结:Gateway 为什么是未来?

相比 Ingress,Gateway 的优势非常明显:

  • 标准化:Gateway API 是 K8s 官方标准,不同控制器(Nginx、Traefik、Istio)遵循同一规范,避免 "厂商锁定";
  • 多协议支持:除了 HTTP/HTTPS,还支持 TCP/UDP/gRPC,覆盖更多业务场景;
  • 分工协作:GatewayClass(运维管)、Gateway(运维管)、Route(开发管)分离,符合企业级团队协作模式;
  • 扩展性强:支持自定义策略(如认证、限流),且持续迭代新特性。

如果你正在搭建 K8s 集群的流量入口,或者计划从 Ingress 迁移到更灵活的方案,Gateway 绝对是值得优先考虑的选择。当然,不同控制器的实现细节可能存在差异,建议结合业务需求选择合适的控制器(如 Nginx Gateway Fabric 适合简单场景,Istio Gateway 适合服务网格场景),并参考官方文档进行配置。

最后,如果你在实践中遇到问题(比如 Gateway 状态一直未 Ready、路由不生效),可以先检查控制器日志(kubectl logs -n nginx-gateway nginx-gateway-xxxxxx),大部分问题都能通过日志定位到原因。

相关推荐
虫师c5 小时前
云原生微服务:Kubernetes+Istio 魔法学院实战指南
微服务·云原生·kubernetes·istio·服务网格
今天头发还在吗6 小时前
【Docker】在项目中如何实现Dockerfile 文件编写
java·docker·容器
早睡冠军候选人8 小时前
K8s学习----StorageClass:实现存储资源的动态管理
运维·学习·云原生·容器·kubernetes
稚辉君.MCA_P8_Java8 小时前
Git 基础 - 查看提交历史
spring boot·git·微服务·云原生·kubernetes
能不能别报错18 小时前
K8s学习笔记(十二) volume存储卷
笔记·学习·kubernetes
致宏Rex20 小时前
Docker 完整教程 | 从基础到实战 (1-2)
运维·docker·容器
爱码社长1 天前
centos8安装docker【新】
运维·docker·容器
yuezhilangniao1 天前
从对比eBPF和istio开始 ~ 了解eBPF
云原生·kubernetes·istio·ebpf
東雪蓮☆1 天前
从安装到上手实战——Docker 基础命令全解析
运维·docker·容器