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

本指南演示如何将 Kubernetes Gateway API 与 waypoint proxy 结合使用,以便在 ambient 模式下通过 egress gateway 路由出站 HTTP 流量。

前提条件

  • 已安装 Alauda Service Mesh v2 Operator。
  • IstioIstioCNI 资源已使用 ambient 配置文件进行配置。
  • 已创建 Ztunnel 资源。
  • 确认 Linux kernel 兼容性

操作步骤

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

    kubectl create namespace egress-gateway
  2. egress-gateway 命名空间添加 istio-discovery=enabled 标签:

    kubectl label namespace egress-gateway istio-discovery=enabled
  3. 通过应用 dataplane mode 标签,为该命名空间启用 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:
        - httpbin.org
      ports:
        - number: 80
          name: http
          protocol: HTTP
      resolution: DNS
    1. 将此 ServiceEntry 的流量通过同一命名空间中名为 waypoint 的 waypoint proxy 路由。
  5. 应用 ServiceEntry

    kubectl apply -f egress-se.yaml
  6. 创建一个名为 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 traffic types(Istio 文档)。
    2. 指定 istio-waypoint gateway class,它会部署 waypoint proxy,而不是标准的 ingress gateway。
  7. 应用 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 路由。

  8. 可选:将网关部署到 基础设施节点

    点击展开
    前提条件

    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 调度到基础设施节点上。

    b. 在 Gateway 资源中添加 infrastructure.parametersRef 字段以引用该 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/istio/istio/refs/heads/master/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 客户端验证你能够通过 egress gateway 访问 httpbin.org

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

    如果从 httpbin.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="httpbin.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