配置 GatewayAPI Gateway

概述

在 Envoy Gateway operator 和 EnvoyGatewayCtl 准备就绪后,配置一个 GatewayGateway 定义流量如何进入 gateway,而配套的 EnvoyProxy 则控制底层 Envoy data plane 的部署方式。

在推荐的工作流程中,请在 Envoy Gateway Operator 之后、配置 GatewayAPI Route 之前配置 Gateway

前提条件

请确保在继续之前已完成以下步骤:

  1. 阅读 Envoy Gateway Operator,以了解基本概念和资源关系
  2. 安装 Envoy Gateway operator 并创建一个 EnvoyGatewayCtl
NOTE

在创建 Gateway 之前,请先了解主要的 Gateway 概念。如果你已经熟悉这些概念, 可以直接跳到 创建 Gateway 部分。

Gateway 基础

什么是 Gateway

Gateway 是流量进入集群的入口点。它定义外部请求如何接收并路由到后端服务。Gateway 主要定义以下内容:

  • 监听器:定义 gateway 监听的端口、协议和主机名
  • GatewayClass:选择由哪个 gateway controller 管理该 Gateway
  • 基础设施引用:引用一个 EnvoyProxy,用于控制底层 Envoy data plane 的部署方式

Gateway 暴露方式 (Service Type)

Service Type 用于配置 gateway 如何通过底层 Envoy Service 暴露。共有三种模式: LoadBalancer、NodePort 和 ClusterIP。

在 YAML 中,此设置配置在配套的 EnvoyProxy 资源中,位置为 .spec.provider.kubernetes.envoyService.type

LoadBalancer (推荐)

其优点是易用,并具备高可用的负载均衡能力。 要使用 LoadBalancer,集群必须支持 LoadBalancer,可通过 MetalLB 启用。

使用 MetalLB 时,你可以通过 service 注解指定静态 VIP。在 Web Console 中,请使用 Service Annotation 字段:

metallb.universe.tf/address-pool: ADDRESS_POOL_NAME
# Or specify a specific IP directly
metallb.universe.tf/loadBalancerIPs: VIP_IP

更多详情请参见 如何在使用 MetalLB 时指定 VIP

NodePort

其优点是不需要任何外部依赖。

不过,使用 NodePort 有以下缺点:

  • 使用 NodePort 时,Kubernetes 分配的 NodePort 端口号与 service 自身端口不同。访问时必须使用 NodePort 端口号,而不是 service 端口。
  • 该 service 可通过集群中任意节点 IP 地址访问,可能带来潜在的安全风险。
使用 NodePort 时如何获取正确端口

在 Gateway 详情页中,当 Service Type 为 NodePort 时,监听器列表会显示 NodePort 列,展示分配的端口号。你也可以使用以下命令:

kubectl get svc -n ${ENVOYGATEWAYCTL_NS} -l gateway.envoyproxy.io/owning-gateway-name=${GATEWAY_NAME} -o=jsonpath="{.items[0].spec.ports[?(@.port==${PORT})].nodePort}"

输出结果即为 NodePort。

ClusterIP

如果你不需要对外暴露,这种方式非常方便。

监听器配置

监听器定义 gateway 监听的端口和协议。在 HTTP 或 HTTPS 协议中,不同的主机名可以视为不同的监听器。

你不能创建端口、协议或主机名冲突的监听器。

你必须在 Gateway 中至少创建一个监听器。

端口和协议

每个监听器都通过端口号和协议进行配置。支持的协议包括:HTTP、HTTPS、TCP、UDP、TLS。

AllowRouteNS

默认情况下,Route 只能附加到 Same 命名空间中的 Gateway。若要允许跨命名空间路由,请使用 Allowed Routes Namespace 字段:

  • Same:允许同一命名空间中的 Route 附加到此监听器。
  • All:允许任意命名空间中的 Route 附加到此监听器。
  • Selector:允许与选择器匹配的命名空间中的 Route 附加到此监听器。

在 ACP 中,一个项目通过命名空间上的标签来标识,例如 cpaas.io/project: <project-name>。如果你希望某个监听器仅供特定项目的 Route 使用,请使用 Selector 并匹配目标命名空间上的项目标签。

监听器的 Allowed Routes Namespace 设置与其协议共同决定了当你将 route 发布到监听器时,Route Web Console 中哪些监听器可用。

更多信息请参见 attach to gateway created in other ns

TLS 配置

对于 HTTPS 和 TLS 协议,你需要配置 TLS 设置。

TLS 模式:

TLS 模式描述是否需要证书
TerminateEnvoy 终止 TLS,并在转发到后端服务之前解密流量是,必须选择 TLS 证书
PassthroughEnvoy 直接将加密的 TLS 流量转发给后端服务,不进行解密
NOTE
  • HTTPS 协议仅支持 Terminate 模式
  • TLS 协议同时支持 TerminatePassthrough 模式
  • 采用 Passthrough 模式的 TLS 监听器支持 TLSRoute
  • 采用 Terminate 模式的 TLS 监听器支持 TCPRoute

证书要求:

  • 默认情况下,你只能使用在同一命名空间中创建的 secret
  • secret 必须是 kubernetes.io/tls 类型,并包含 tls.crttls.key
  • 关于跨命名空间 secret,请参见 use secret created in other ns

EnvoyProxy (部署配置)

Envoy Gateway 使用 EnvoyProxy 资源来控制 gateway 的部署配置。我们建议为每个 Gateway 创建一个专用的 EnvoyProxy 资源,并通过 Gateway 的 .spec.infrastructure.parametersRef 字段进行引用。

当你在 Web Console 中使用由 EnvoyGatewayCtl 创建的 GatewayClass 创建 Gateway 时,控制台会自动创建一个与其同名、同命名空间的配套 EnvoyProxy 资源。

当你通过应用 YAML 创建 Gateway 时,你需要自行保证 Gateway.spec.infrastructure.parametersRef 与所引用的 EnvoyProxy 资源保持一致。

这种一对一映射方式可以提供更好的隔离性,并对以下部署配置提供更细粒度的控制:

  • 从节点数
  • 资源限制和请求
  • 节点选择器
  • service 类型和注解
  • 镜像仓库

推荐的资源规格

对于典型的 HTTP 和 HTTPS 南北向流量,可将以下值作为单个 envoy-proxy Pod 的起始参考值。这些建议适用于 .spec.provider.kubernetes.envoyDeployment.container.resources

每个 envoy-proxy Pod 的峰值 QPS推荐 CPU推荐内存
4,0002 核1Gi
8,0004 核2Gi
12,0008 核4Gi
NOTE
  • 这些值是起始参考值,不是硬性限制。请结合你的实际流量特征进行验证。
  • TLS 终止、已启用的策略、路由复杂度、请求和响应大小,以及长连接都可能增加资源消耗。
  • 使用多个从节点时,应根据每个从节点实际处理的 QPS 进行扩缩容,而不仅仅是依据 Gateway 的总 QPS。

镜像仓库

镜像仓库已根据你集群的默认值预先配置。除非必要,请不要修改它。

有关其他部署配置方式,请参见 deployment-mode

创建 Gateway

通过 Web Console

  1. 导航到 Alauda Container Platform -> Networking -> Gateway -> Gateways
  2. 点击 Create Gateway 按钮
  3. Create Gateway 页面中,选择由你的 EnvoyGatewayCtl 创建的 GatewayClass。在 Envoy Gateway Operator 推荐的默认示例中,该值为 envoy-gateway-operator-cpaas-default

该页面显示以下配置项:

字段描述YAML 路径
名称Gateway 名称gateway: .metadata.name
envoyproxy: .metadata.name
GatewayClass要使用的 GatewayClassgateway: .spec.gatewayClassName
Service TypeService Typeenvoyproxy: .spec.provider.kubernetes.envoyService.type
Service AnnotationService 注解envoyproxy: .spec.provider.kubernetes.envoyService.annotations
资源限制部署资源限制envoyproxy: .spec.provider.kubernetes.envoyDeployment.container.resources
从节点数部署从节点数envoyproxy: .spec.provider.kubernetes.envoyDeployment.replicas
节点标签部署节点选择器envoyproxy: .spec.provider.kubernetes.envoyDeployment.nodeSelector
监听器监听器gateway: .spec.listeners
WARNING

Web Console 表单仅支持由 EnvoyGatewayCtl 创建的 GatewayClass。对于其他 GatewayClass,请使用 YAML 编辑器。

NOTE

当使用 EnvoyGatewayCtl 创建的 GatewayClass 时,Web Console 会自动创建一个与 Gateway 名称和命名空间匹配的配套 EnvoyProxy 资源

监听器配置

在创建或编辑监听器时,你可以配置以下内容:

字段描述YAML 路径
名称监听器名称.spec.listeners[].name
端口监听器监听的端口号.spec.listeners[].port
协议监听器的协议。可选项:HTTP、HTTPS、TCP、UDP、TLS.spec.listeners[].protocol
主机名可选。监听器的主机名.spec.listeners[].hostname
允许的 Route 命名空间控制哪些命名空间可以向此监听器附加 route.spec.listeners[].allowedRoutes.namespaces.from
HTTPS 协议配置

当选择 HTTPS 作为协议时:

字段描述YAML 路径
证书必填。选择包含 TLS 证书的 Kubernetes secret。.spec.listeners[].tls.certificateRefs
NOTE
  • HTTPS 协议仅支持 Terminate 模式
  • HTTPS 监听器必须选择证书
  • 默认情况下,你只能使用在同一命名空间中创建的 secret
TLS 协议配置

当选择 TLS 作为协议时:

配置字段

字段描述YAML 路径
TLS 模式选择 TLS 模式。可选项:Terminate、Passthrough。默认值:Terminate.spec.listeners[].tls.mode
TLS 证书仅当 TLS 模式为 Terminate 时必填。选择包含 TLS 证书的 secret。.spec.listeners[].tls.certificateRefs

有关 TLS 模式的详细信息,请参见 TLS 配置

通过 YAML

如果你没有使用推荐的默认示例,请将 envoy-gateway-operator-cpaas-default 替换为你自己的 EnvoyGatewayCtl 创建的 GatewayClass

下面这个最小示例创建了一个 HTTP Gateway 和一个专用 EnvoyProxy

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: demo
  namespace: demo
spec:
  infrastructure:
    parametersRef:
      group: gateway.envoyproxy.io
      kind: EnvoyProxy
      name: demo
  gatewayClassName: envoy-gateway-operator-cpaas-default
  listeners:
    - name: http
      port: 80
      protocol: HTTP
      allowedRoutes:
        namespaces:
          from: Same
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
  name: demo
  namespace: demo
spec:
  provider:
    kubernetes:
      envoyService:
        type: ClusterIP
      envoyDeployment:
        replicas: 1
        container:
          imageRepository: registry.alauda.cn:60080/acp/envoyproxy/envoy
          resources:
            limits:
              cpu: '1'
              memory: 1Gi
            requests:
              cpu: '1'
              memory: 1Gi
    type: Kubernetes

包含多种监听器类型的完整示例

如果你需要更多监听器类型,请使用以下完整示例:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: demo
  namespace: demo
spec:
  infrastructure:
    parametersRef:
      group: gateway.envoyproxy.io
      kind: EnvoyProxy
      name: demo
  gatewayClassName: envoy-gateway-operator-cpaas-default
  listeners:
    - name: http
      port: 80
      hostname: a.com
      protocol: HTTP
      allowedRoutes:
        namespaces:
          from: Same
    - name: https
      port: 443
      hostname: a.com
      protocol: HTTPS
      allowedRoutes:
        namespaces:
          from: Same
      tls:
        mode: Terminate
        certificateRefs:
          - name: demo-tls
    - name: tls-passthrough
      port: 8443
      hostname: tls.example.com
      protocol: TLS
      allowedRoutes:
        namespaces:
          from: Same
      tls:
        mode: Passthrough
    - name: tls-terminate
      port: 9443
      hostname: secure.example.com
      protocol: TLS
      allowedRoutes:
        namespaces:
          from: Same
      tls:
        mode: Terminate
        certificateRefs:
          - name: demo-tls
    - name: tcp
      port: 8080
      protocol: TCP
      allowedRoutes:
        namespaces:
          from: Same
    - name: udp
      port: 8081
      protocol: UDP
      allowedRoutes:
        namespaces:
          from: Same
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
  name: demo
  namespace: demo
spec:
  provider:
    kubernetes:
      envoyService:
        type: ClusterIP
      envoyDeployment:
        replicas: 1
        container:
          imageRepository: registry.alauda.cn:60080/acp/envoyproxy/envoy
          resources:
            limits:
              cpu: '1'
              memory: 1Gi
            requests:
              cpu: '1'
              memory: 1Gi
    type: Kubernetes
  1. 参考 EnvoyProxy resource 进行部署配置
  2. 如有需要,将 envoy-gateway-operator-cpaas-default 替换为你自己的 GatewayClass
  3. listeners 定义流量如何进入 gateway
  4. hostname 会影响基于主机名的路由如何匹配监听器
  5. protocol 决定哪些 route 类型可以附加到监听器
  6. allowedRoutes 控制哪些命名空间可以附加 route
  7. tls 为 HTTPS 和 TLS 监听器配置 TLS 终止或透传
  8. EnvoyProxy 名称必须与 .spec.infrastructure.parametersRef.name 匹配
  9. envoyService.type 控制 gateway 的暴露方式
  10. 除非你的环境确实需要,否则请保持 imageRepository 不变
  11. resources 配置 Envoy data plane 的资源限制和请求
  12. provider.type 保持为 Kubernetes

查看 Gateway 详情

在 Gateway 详情页中,监听器列表会显示以下信息:

描述
名称监听器名称
协议监听器协议(HTTP、HTTPS、TCP、UDP、TLS)
端口已配置的端口号
NodePort当 Service Type 为 NodePort 时显示。显示用于访问该监听器的已分配 NodePort 端口号。
NOTE

当 Gateway Service Type 为 NodePort 时,监听器列表会额外显示 NodePort 列。访问 gateway 时请使用 NodePort 值,而不是 service 端口。更多详情请参见 使用 NodePort 时如何获取正确端口

监听器与 Route 参考

Route 资源附加到 Gateway 时,请使用以下规则。

主机名

监听器中的主机名是相同协议下监听器的唯一标识符。你不能在 gateway 中添加或更新冲突的监听器。

主机名交集规则

请求到达时,会将其与监听器的主机名和 Route 的主机名做交集匹配。只有交集中的主机名才会用于流量路由。

监听器主机名Route 主机名交集结果示例
无主机名无主机名匹配所有主机接受任意传入的 Host header
无主机名有主机名(例如 api.example.com所有 Route 主机名仅匹配带有 api.example.com 的请求
有主机名(例如 api.example.com无主机名所有监听器主机名仅匹配带有 api.example.com 的请求
有主机名(例如 api.example.com有完全匹配的主机名精确匹配主机名仅匹配带有 api.example.com 的请求
有通配符(例如 *.example.com有匹配的主机名匹配具体主机名匹配 api.example.comweb.example.com 的请求
有主机名(例如 api.example.com有不匹配的主机名无交集 - Route 状态异常Route 无法处理流量
NOTE

通配符(*)执行后缀匹配。例如,*.example.com 可匹配 foo.example.combar.example.com, 但不能匹配 example.com

WARNING

无交集意味着 Route 状态会变为异常,并且无法处理流量。

支持的 Route 类型

每个监听器会根据其协议支持不同的 Route 类型:

监听器协议支持的 Route 类型
HTTPHTTPRoute, GRPCRoute
HTTPSHTTPRoute, GRPCRoute
TLS (Passthrough 模式)TLSRoute
TLS (Terminate 模式)TCPRoute
TCPTCPRoute
UDPUDPRoute

在配置 route 时,请确保它们与所附加监听器的协议相匹配。例如,你不能将 HTTPRoute 附加到 TCP 监听器。

下一步

Gateway 准备就绪后,请继续阅读 配置 GatewayAPI Route。如果在 route 附加后你还需要高级流量控制,请继续阅读 配置 GatewayAPI Policy