将 Ingress 迁移到 Gateway API

本页面介绍了如何将 Google Kubernetes Engine (GKE) 中的流量管理从 Ingress API 迁移到 Gateway API。Gateway API 提供全托管式 Google Cloud 解决方案,用于处理应用流量。

为了最大限度地减少停机时间并降低风险,迁移到 Gateway API 的最有效方法是同时运行现有的 Ingress API 和新的 Gateway API 配置。此方法可在实际环境中对新的 Gateway 配置进行全面测试,而不会影响当前服务。验证新的 Gateway 配置后,您可以执行快速 DNS 割接,将流量重定向到 Gateway API,从而确保平稳且低风险的过渡。

概括来讲,迁移策略涉及以下阶段:

  1. 配置新的负载均衡器。
  2. 定义用于处理入站流量的规则。
  3. 部署新配置并测试流向新 Gateway IP 地址的流量。
  4. 将生产流量切换到 Gateway API。
  5. 清理剩余的 Ingress 资源。

配置新的负载均衡器

在此阶段,您将部署 Kubernetes Gateway 资源,以将流量负载均衡到 GKE 集群。部署 Gateway 资源后,GKE 会配置第 7 层应用负载均衡器,以将 HTTP(S) 流量公开给在集群中运行的应用。您可以为每个集群或每个所需的负载均衡器部署一个 Gateway 资源。

在以下示例中,您将配置全球外部应用负载均衡器。如需创建 Gateway,请将以下清单保存为 gateway.yaml

kind: Gateway
apiVersion: gateway.networking.k8s.io/v1
metadata:
  name: external-http-gateway
spec:
  gatewayClassName: gke-l7-global-external-managed # GKE's managed external Application Load Balancer
  listeners:
  - name: http
    protocol: HTTP
    port: 80
    allowedRoutes:
      namespaces:
        from: Same # Only allow HTTPRoutes from the same namespace

上述清单描述了一个包含以下字段的 Gateway:

  • gatewayClassName: gke-l7-global-external-managed:指定此 Gateway 的 GatewayClass。此 Gateway 类使用全球外部应用负载均衡器。
  • protocol: HTTPport: 80:指定 Gateway 为 HTTP 流量公开端口 80。

为入站流量定义流量规则

路由资源定义了用于将流量从 Gateway 映射到后端服务的协议特有规则。

在此阶段,您将 Ingress 清单转换为 HTTPRoute 资源。如需转换 Ingress 清单,请按照 ingress2gateway 工具中的步骤操作。

此示例假定您有以下 Ingress 资源:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cafe-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: cafe.example.com
    http:
      paths:
      - path: /tea
        pathType: Prefix
        backend:
          service:
            name: tea-svc
            port:
              number: 80
      - path: /coffee
        pathType: Prefix
        backend:
          service:
            name: coffee-svc
            port:
              number: 80

使用 ingress2gateway 工具转换清单后,输出是转换后的 HTTPRoute 清单。

将以下示例清单保存为 httproute.yaml

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: cafe-route
spec:
  # This route attaches to our new Gateway
  parentRefs:
  - name: external-http-gateway
  # The hostname is the same as before
  hostnames:
  - "cafe.example.com"
  # The routing rules are now more explicit
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /tea
    backendRefs:
    - name: tea-svc
      port: 80
  - matches:
    - path:
        type: PathPrefix
        value: /coffee
    backendRefs:
    - name: coffee-svc
      port: 80

请注意,HTTPRoute 清单中的 rules 字段直接对应于原始 Ingress 清单中定义的路由规则。

部署并测试新配置

在此阶段,您将应用在前两个阶段中创建的 Gateway 和 HTTPRoute 清单,并测试流量是否流向 Gateway 的新 IP 地址。

  1. 应用 Gateway 和 HTTPRoute 清单:

    kubectl apply -f gateway.yaml
    kubectl apply -f httproute.yaml
    
  2. 获取 Gateway 的 IP 地址。分配 IP 地址可能需要几分钟时间:

    kubectl get gateway external-http-gateway -o=jsonpath="{.status.addresses[0].value}" --watch
    

    输出为 Gateway 的外部 IP 地址,例如 203.0.113.90

  3. 测试新的 Gateway IP 地址。使用以下 curl 命令向该 IP 地址发送请求并指定 cafe.example.com 主机名。例如:

    curl --resolve cafe.example.com:80:203.0.113.90 http://cafe.example.com/tea
    curl --resolve cafe.example.com:80:203.0.113.90 http://cafe.example.com/coffee
    

    203.0.113.90 替换为您在上一步中获取的外部 IP 地址。输出会确认新的 Gateway IP 地址可正确路由 cafe.example.com 的流量,而无需执行 DNS 查找。

将流量定向到新的 Gateway IP 地址

在此阶段,您将更新 DNS 记录以指向新的 Gateway IP 地址,从而将实时流量从之前的 Ingress 割接到新的 Gateway。更新 DNS 记录的确切步骤因 DNS 提供商而异。

例如,如果您在 Ingress 中配置了 cafe.example.com,则需要通过 DNS 提供商找到 cafe.example.comA 记录,并将旧 Ingress IP 地址的值更改为 203.0.113.90(即新的 Gateway IP 地址)。

更新 DNS 记录后,流量会开始从 Ingress 转移到 Gateway,但并非所有客户端都会立即割接。如果 DNS 解析器已经缓存了之前的记录,则它会等到该记录的存留时间 (TTL) 值过期后再次查询该记录,并接收更新后的 IP 地址。因此,您应继续并行运行现有 Ingress 和新 Gateway,直到确认 Ingress 的流量已停止,这表示 DNS 传播已完成,客户端不再被定向到旧 IP 地址。您可以通过监控负载均衡器或 Ingress 控制器上的流量来验证这一点。如需了解详情,请参阅检查 DNS 传播

如果您使用 Cloud DNS,则可以使用目标权重将流量从旧 IP 地址逐步转移到新 IP 地址。如需了解详情,请参阅管理 DNS 路由政策和健康检查

清理剩余的 Ingress 资源

确认新 Gateway 成功运行后,清理旧的 Ingress 资源。

  1. 删除 Ingress 资源:

    kubectl delete ingress cafe-ingress
    
  2. 卸载 ingress-nginx 控制器。例如,如果您使用 Helm 安装了控制器,请运行以下命令:

    helm uninstall ingress-nginx -n ingress-nginx
    

Ingress NGINX 与 GKE Gateway 的功能比较

Gateway API 提供了一种更标准化的方式来配置入站流量,并且在大多数常见功能(例如路由、标头和流量拆分)方面具有对等的功能。

下表比较了 Ingress 控制器和 Gateway API 中用于常见功能的注解。

功能 Ingress 中的注解 GKE Gateway 中的注解 对等
网址重写 nginx.ingress.kubernetes.io/rewrite-target HTTPRoute,并带有 urlRewrite 过滤条件。 部分对等。GKE Gateway 仅支持前缀替换。
标头操纵 nginx.ingress.kubernetes.io/proxy-set-headersadd-headers HTTPRoute,并带有 requestHeaderModifier 修饰符或 responseHeaderModifier 过滤条件。 完全对等。
基于路径的路由 Ingress 对象中的 spec.rules.http.paths HTTPRoute 对象中的 rules.matches.path 完全对等。
根据主机发送流量 Ingress 对象中的 spec.rules.host HTTPRoute 对象中的 hostnames 完全对等。
流量拆分 nginx.ingress.kubernetes.io/canary 注解。 HTTPRoute,带有加权后的 backendRefs 完全对等。此外,您还可以精细控制流量拆分。
身份验证 nginx.ingress.kubernetes.io/auth-url,用于外部身份验证。
  • Identity-Aware Proxy (IAP):BackendPolicy CRD。
  • 其他:需要更自定义的方法,可能需要使用服务网格或自定义过滤条件。
部分对等。Identity-Aware Proxy 是保护 Gateway 安全的推荐方式,在后端进行配置。

后续步骤