本文介绍如何在服务网格(ASM)Ambient 模式下管理网格内服务的出站流量。根据管控粒度的不同,ASM 提供两种出口流量管理方式:通过 ServiceEntry 和 Waypoint 实现细粒度的单服务管控,以及通过 EgressPolicy 实现全局层面的策略管控。
方案选择
方式 | 适用场景 | 管控粒度 | 典型用途 |
ServiceEntry + Waypoint | 需要为特定外部服务配置路由、可观测性或访问控制 | 单个外部服务 | TLS 终结、请求鉴权、流量审计 |
EgressPolicy | 需要对网格整体出站流量实施放行或拦截策略 | 全局(按命名空间/IP 段) | 禁止访问内网地址段、放行指定命名空间 |
说明 两种方式可以同时使用。通过 ServiceEntry 声明的外部服务会被网格识别为已知目标,其流量不受 EgressPolicy 管控。EgressPolicy 仅对无法匹配任何已知 Service 或 Workload 的流量生效。
注意 EgressPolicy 功能需要 ASM 实例版本为 1.29 及以上。
前提条件
已创建服务网格(ASM)实例,且开启 Ambient 模式。
已将集群添加到 ASM 实例。
已为需要管控出站流量的命名空间启用 Ambient 模式。
已创建用于部署出口代理的
egress-gateway命名空间。
方式一:通过 ServiceEntry 和 Waypoint 管理出口流量
适用于需要对特定外部服务进行精确管控的场景。通过 ServiceEntry 将外部服务声明为网格内已知目标,再通过 Waypoint 代理实现流量治理。
部署出口 Waypoint
为出口流量创建一个专用的 Waypoint 代理,作为网格内服务访问外部服务的统一出口:
kubectl apply -n egress-gateway -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: egress-waypoint spec: gatewayClassName: istio-waypoint listeners: - name: mesh port: 15008 protocol: HBONE EOF验证 Waypoint 已就绪:
kubectl get pods -n egress-gateway -l gateway.istio.io/managed=istio.io-mesh-controller预期输出中 Pod 状态为
Running:NAME READY STATUS RESTARTS AGE egress-waypoint-xxxxxxxxx-xxxxx 1/1 Running 0 30s创建 ServiceEntry
以
httpbin.org为例,创建一个 ServiceEntry 将该外部服务声明为网格已知目标,并绑定到上一步部署的 Waypoint:apiVersion: networking.istio.io/v1beta1 kind: ServiceEntry metadata: name: httpbin namespace: egress-gateway labels: istio.io/use-waypoint: egress-waypoint spec: hosts: - httpbin.org location: MESH_EXTERNAL ports: - number: 80 name: http protocol: HTTP - number: 443 name: https protocol: HTTPS resolution: DNS说明
`
istio.io/use-waypoint: egress-waypoint标签将该 ServiceEntry 的流量路由到指定的 Waypoint 代理。resolution: DNS表示通过 DNS 解析获取外部服务的实际 IP 地址。kubectl apply -f httpbin-serviceentry.yaml配置访问策略(可选)
通过 AuthorizationPolicy 限制哪些服务可以访问该外部服务:
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-frontend-to-httpbin namespace: egress-gateway spec: targetRefs: - kind: ServiceEntry group: networking.istio.io name: httpbin action: ALLOW rules: - from: - source: namespaces: ["default"] to: - operation: methods: ["GET"] paths: ["/get", "/headers"]kubectl apply -f httpbin-authz.yaml该策略仅允许
default命名空间的服务以 GET 方法访问httpbin.org的/get和/headers路径。验证结果
从
default命名空间的 Pod 发起请求,验证流量经过 Waypoint 代理:kubectl exec -n default deploy/test-pod -- curl -sI http://httpbin.org/headers预期返回 HTTP 200 响应。
查看 Waypoint 的访问日志,确认请求已记录:
kubectl logs -n egress-gateway -l gateway.istio.io/managed=istio.io-mesh-controller --tail=20预期日志中出现对
httpbin.org的请求记录,包括来源命名空间、请求路径和响应状态码。从非授权命名空间发起请求,验证访问被拒绝:
kubectl exec -n other-ns deploy/test-pod -- curl -sI http://httpbin.org/headers预期返回
RBAC: access denied,表示 AuthorizationPolicy 已生效。
方式二:通过 EgressPolicy 管理出口流量
适用于需要从全局层面统一管控出站流量的场景(需要 ASM 实例版本 1.29 及以上)。通过 EgressPolicy 配置放行或拦截规则,对所有未被网格识别的出站流量实施策略控制。
EgressPolicy 的详细配置说明和完整操作步骤,请参见配置 Ambient 模式 EgressPolicy。以下展示一个典型配置示例。
配置示例
在 istio-system 命名空间下的 ztunnel-config ConfigMap 中配置 EgressPolicy:
kubectl apply -n istio-system -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: ztunnel-config
data:
ztunnel-config.yaml: |
egressPolicies:
# 允许指定命名空间的 Pod 直接访问外部服务
- namespaces:
- common-infrastructure
policy: Passthrough
# 禁止所有命名空间访问内网地址段
- matchCidrs:
- 172.16.0.0/16
- 2001:0db8::/32
policy: Deny
EOF注意 EgressPolicy 功能需要 ASM 实例版本为 1.29 及以上。
验证
从 default 命名空间的 Pod 发起目标为禁止地址段的请求:
kubectl exec -n default deploy/test-pod -- curl -sI --connect-timeout 5 http://172.16.0.1预期连接被拒绝,表示 Deny 策略已生效。
两种方式配合使用
在实际生产环境中,建议将两种方式结合使用:
使用 ServiceEntry + Waypoint 为需要精细管控的外部服务(如 API 网关、第三方支付等)配置路由和访问控制,实现可观测性、鉴权和 TLS 终结等能力。
使用 EgressPolicy 作为全局兜底策略,禁止网格内服务访问内网敏感地址段,防止未授权的网络访问。
通过 ServiceEntry 声明的外部服务不受 EgressPolicy 管控,两者互不干扰。
注意事项
EgressPolicy 无法在网格层面严格保证所有出站流量均被拦截。已被显式排除在网格之外的 Workload 可以绕过这些策略。建议结合 Kubernetes NetworkPolicy 实现纵深防御。
EgressPolicy 规则的排列顺序决定匹配优先级,第一条匹配的规则即为最终生效的规则。
如需基于域名进行全局管控(而非基于 IP),应使用 ServiceEntry 方式,因为 EgressPolicy 的
matchCidrs仅匹配目标 IP 地址。