在 ambient 模式下使用 Kubernetes Gateway API 通过网关路由出口流量

本指南演示如何结合 Kubernetes Gateway API 和 waypoint proxy,在 ambient 模式下通过出口网关路由出站 HTTP 流量。

前提条件

  • 已安装 Alauda Service Mesh v2 Operator。
  • 已使用 ambient 配置文件配置 IstioIstioCNI 资源。
  • 已创建 Ztunnel 资源。
  • 已安装 Gateway API CRD。
  • 确认 Linux 内核兼容性

操作步骤

  1. 创建名为 egress-gateway 的命名空间:

    kubectl create namespace egress-gateway
    kubectl label namespace egress-gateway pod-security.kubernetes.io/enforce=restricted --overwrite
  2. istio-discovery=enabled 标签添加到 egress-gateway 命名空间:

    kubectl label namespace egress-gateway istio-discovery=enabled
  3. 通过应用数据平面模式标签,为该命名空间启用 ambient 模式:

    kubectl label namespace egress-gateway istio.io/dataplane-mode=ambient
  4. 创建名为 egress-se.yaml 的 YAML 文件,为外部服务定义 ServiceEntryistio.io/use-waypoint 标签会将此条目与 waypoint proxy 关联起来。

    apiVersion: networking.istio.io/v1
    kind: ServiceEntry
    metadata:
      name: httpbin-ext
      namespace: egress-gateway
      labels:
        istio.io/use-waypoint: waypoint
    spec:
      hosts:
        - httpbingo.org
      ports:
        - number: 80
          name: http
          protocol: HTTP
      resolution: DNS
    1. 将发往此 ServiceEntry 的流量通过同一命名空间中名为 waypoint 的 waypoint proxy。
  5. 应用 ServiceEntry

    kubectl apply -f egress-se.yaml
  6. istio-waypoint gateway class overlay 添加到 Istio 资源,以便 waypoint pod 能够被准入 Restricted egress-gateway 命名空间:

    kubectl patch istio default --type=merge -p '{"spec":{"values":{"gatewayClasses":{"istio-waypoint":{"deployment":{"spec":{"template":{"spec":{"securityContext":{"seccompProfile":{"type":"RuntimeDefault"}}}}}}}}}}}'

    有关更多信息,请参阅 Pod Security Admission

  7. 创建名为 waypoint.yaml 的 YAML 文件,在 egress-gateway 命名空间中部署 waypoint proxy。waypoint proxy 会拦截并处理此命名空间中服务的 L7 流量。

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: waypoint
      namespace: egress-gateway
      labels:
        istio.io/waypoint-for: service
    spec:
      gatewayClassName: istio-waypoint
      listeners:
        - name: mesh
          port: 15008
          protocol: HBONE
    1. istio.io/waypoint-for: service 标签表示此 waypoint 为服务处理流量。标签值决定所处理流量的类型。有关详细信息,请参阅 Waypoint 流量类型(Istio 文档)。
    2. 指定 istio-waypoint gateway class,该类部署 waypoint proxy,而不是标准 ingress gateway。
  8. 应用 waypoint proxy 配置:

    kubectl apply -f waypoint.yaml
    NOTE

    除了手动创建 YAML 文件之外,还可以使用以下命令部署 waypoint proxy:

    istioctl waypoint apply --enroll-namespace --name waypoint --namespace egress-gateway

    使用 --enroll-namespace 选项时,egress-gateway 命名空间中的所有服务(包括 ServiceEntries)都会将其流量路由通过 waypoint。

  9. 可选:将网关部署到 Infra Nodes

    单击展开
    Prerequisites

    Alauda Container Platform 4.2.0 或更高版本,或者将 Gateway API CRD 升级到最新版本。

    a. 在计划部署 Gateway 的同一命名空间中创建名为 asm-kube-gateway-options 的 ConfigMap:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: asm-kube-gateway-options
      namespace: egress-gateway
    data:
      deployment: |
        spec:
          template:
            spec:
              nodeSelector:
                node-role.kubernetes.io/infra: ""
              tolerations:
                - effect: NoSchedule
                  key: node-role.kubernetes.io/infra
                  value: reserved
                  operator: Equal
    1. 指定 configmap 的名称。
    2. 指定与 Gateway 相同的 configmap 命名空间。
    3. 设置节点选择器和容忍度,以便将 Gateway pod 调度到 Infra Nodes。

    b. 添加 infrastructure.parametersRef 字段,在 Gateway 资源中引用该 ConfigMap:

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: waypoint
      namespace: egress-gateway
    spec:
      # Add the following infrastructure configuration to your Gateway CR
      infrastructure:
        parametersRef:
          group: ""
          kind: ConfigMap
          name: asm-kube-gateway-options
      # ... rest of your Gateway configuration
    1. 指定 Gateway 的名称。
    2. 指定 Gateway 的命名空间。

验证

  1. 通过检查状态确认 waypoint proxy 已就绪:

    kubectl get gateways.gateway.networking.k8s.io waypoint -n egress-gateway

    PROGRAMMED 列应显示 True,表示配置成功。

    示例输出

    NAME       CLASS            ADDRESS      PROGRAMMED   AGE
    waypoint   istio-waypoint   10.4.61.76   True         38s
  2. egress-gateway 命名空间中部署 curl 客户端:

    kubectl apply -n egress-gateway -f https://raw.githubusercontent.com/alauda-mesh/istio/refs/heads/istio-1.30/samples/curl/curl.yaml
  3. curl pod 的名称存储在变量中:

    export CURL_POD=$(kubectl get pods -n egress-gateway -l app=curl -o jsonpath='{.items[*].metadata.name}')
    echo "CURL_POD=$CURL_POD"
  4. curl 客户端验证是否可以通过出口网关访问 httpbingo.org

    kubectl exec $CURL_POD -n egress-gateway -- \
      curl -sS -v http://httpbingo.org/get

    httpbingo.org 获得成功响应,表明出口流量正通过已配置的网关进行路由。

    示例输出

    < HTTP/1.1 200 OK
    ...
    < server: istio-envoy
    ...

    ztunnel 日志应显示流量正通过 waypoint,输出示例如下:

    ztunnel 日志输出示例

    2026-03-09T10:18:02.686121Z	info	access	connection complete
      src.addr=10.3.0.134:35092
      src.workload="curl-c658c5974-6zsnb"
      src.namespace="egress-gateway"
      src.identity="spiffe://cluster.local/ns/egress-gateway/sa/curl"
      dst.addr=10.3.0.131:15008
      dst.hbone_addr=240.240.0.3:80
      dst.service="httpbingo.org"
      dst.workload="waypoint-7d688546dc-v8x9c"
      dst.namespace="egress-gateway"
      dst.identity="spiffe://cluster.local/ns/egress-gateway/sa/waypoint"
      direction="outbound"
      bytes_sent=78
      bytes_recv=641
      duration="790ms"

清理

删除 egress-gateway 命名空间及所有关联资源:

# Remove the namespace from the ambient data plane
kubectl label namespace egress-gateway istio.io/dataplane-mode-
# Remove the namespace
kubectl delete namespace egress-gateway