本文介紹如何在服務網格(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 Gateway、第三方支付等)配置路由和存取控制,實現可觀測性、鑒權和 TLS 終結等能力。
使用 EgressPolicy 作為全域兜底策略,禁止網格內服務訪問內網敏感位址區段,防止未授權的網路訪問。
通過 ServiceEntry 聲明的外部服務不受 EgressPolicy 管控,兩者互不干擾。
注意事項
EgressPolicy 無法在網格層面嚴格保證所有出站流量均被攔截。已被顯式排除在網格之外的 Workload 可以繞過這些策略。建議結合 Kubernetes NetworkPolicy 實現縱深防禦。
EgressPolicy 規則的排列順序決定匹配優先順序,第一條匹配的規則即為最終生效的規則。
如需基於網域名稱進行全域管控(而非基於 IP),應使用 ServiceEntry 方式,因為 EgressPolicy 的
matchCidrs僅匹配目標 IP 位址。