全部產品
Search
文件中心

Alibaba Cloud Service Mesh:如何解決Kubernetes叢集中的Pod無法訪問入口網關的CLB地址的問題?

更新時間:Aug 30, 2026

當入口網關服務使用externalTrafficPolicy: Local時,部分節點上的Pod能訪問CLB地址,而其他節點上的Pod無法訪問。本文介紹該問題的原因和解決方案。

問題現象

Service MeshASM已添加Kubernetes叢集,並且使用Local類型的負載平衡CLB部署入口網關。當應用Pod訪問入口網關暴露的CLB地址時,出現以下問題:

  • 部分節點上的Pod能訪問入口網關暴露的CLB地址。

  • 部分節點上的Pod不能訪問入口網關暴露的CLB地址。

問題診斷

在修複問題前,請先確認問題由externalTrafficPolicy: Local配置引起。

  1. 查看入口網關服務的externalTrafficPolicy設定。如果輸出為Local,說明屬於本文情境。

    kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.externalTrafficPolicy}'
  2. 列出運行入口網關Pod的節點,記錄輸出中的NODE列。

    kubectl get pods -n istio-system -l app=istio-ingressgateway -o wide
  3. 確認異常Pod所在的節點。如果異常Pod運行在步驟2輸出中不存在的節點上,即可確認問題原因。

    kubectl get pod  -n  -o wide

問題原因

externalTrafficPolicy設定為Local時,kube-proxy會添加iptables(或IPVS)規則,這些規則僅將流量路由到本地節點上的端點(Endpoint)。以下流程展示kube-proxy如何處理叢集內發起的、訪問CLB地址的請求:

  1. Pod向CLB的外部IP地址發送請求。

  2. kube-proxy識別出該CLB地址是入口網關服務的外部IP地址,因此攔截該請求,而不是將其轉寄到CLB。

  3. kube-proxy在與發起請求的Pod相同的節點上尋找入口網關端點。

  4. 如果該節點上存在入口網關Pod,kube-proxy會將請求轉寄給該Pod,請求成功。

  5. 如果該節點上不存在入口網關Pod,kube-proxy找不到本地端點,請求失敗。

這是Kubernetes針對externalTrafficPolicy: Local的預期行為。更多資訊,請參見iptables規則

解決方案

根據是否需要保留源IP地址以及叢集使用的CNI外掛程式,選擇合適的解決方案。

解決方案

保留源IP地址

前提條件

配置變更

通過服務DNS名稱訪問

是(外部流量)

修改externalTrafficPolicy為Cluster

修改IstioGateway CRD

使用ENI直通

Terway CNI的ENI模式

修改IstioGateway CRD並添加Annotation

通過服務DNS名稱訪問(推薦)

在叢集內部訪問入口網關時,無需使用CLB的外部IP地址,可通過其ClusterIP或服務DNS名稱訪問。ClusterIP流量使用獨立的kube-proxy轉寄路徑,會轉寄到叢集內所有端點,從而繞過externalTrafficPolicy: Local的限制。

叢集內訪問時使用以下服務DNS名稱:

istio-ingressgateway.istio-system

例如,從Pod中發送請求:

curl http://istio-ingressgateway.istio-system
說明

該方法無需修改配置,適用於任何CNI外掛程式,並且能夠為通過CLB進入的外部流量保留源IP地址。

修改externalTrafficPolicy為Cluster

如果不需要保留源IP地址,可以將externalTrafficPolicy修改為Cluster。修改後,kube-proxy會將流量轉寄到任意節點上的入口網關Pod,而不僅限於本節點。

更新IstioGateway CRD(Custom Resource Definition,自訂資源定義):

apiVersion: istio.alibabacloud.com/v1beta1
kind: IstioGateway
metadata:
  name: ingressgateway
  namespace: istio-system
  ....
spec:
  externalTrafficPolicy: Cluster
....

關於CRD欄位的更多資訊,請參見ASM網關CRD說明

說明

使用externalTrafficPolicy: Cluster後,入站請求會經過源網路位址轉譯(SNAT),用戶端源IP會被替換為節點的內部IP。如果應用依賴用戶端源IP地址,請使用其他解決方案。

使用ENI直通

如果叢集使用Terway的彈性網卡(ENI)或運行在ENI多IP模式,可以將externalTrafficPolicy修改為Cluster,同時通過ENI直通保留源IP地址。

更新IstioGateway CRD,將externalTrafficPolicy設定為Cluster,並添加service.beta.kubernetes.io/backend-type: eni的Annotation:

apiVersion: istio.alibabacloud.com/v1beta1
kind: IstioGateway
metadata:
  name: ingressgateway
  namespace: istio-system
  ....
spec:
  externalTrafficPolicy: Cluster
  maxReplicas: 5
  minReplicas: 2
  ports:
    - name: status-port
      port: 15020
      targetPort: 15020
    - name: http2
      port: 80
      targetPort: 80
    - name: https
      port: 443
      targetPort: 443
    - name: tls
      port: 15443
      targetPort: 15443
  replicaCount: 2
  resources:
    limits:
      cpu: '2'
      memory: 2G
    requests:
      cpu: 200m
      memory: 256Mi
  runAsRoot: false
  serviceAnnotations:
    service.beta.kubernetes.io/backend-type: eni
  serviceType: LoadBalancer

關於CRD欄位的更多資訊,請參見ASM網關CRD說明

驗證結果

應用所選解決方案後,驗證此前無法訪問的Pod是否能夠訪問入口網關:

kubectl exec  -n  -- curl -s -o /dev/null -w "%{http_code}" http://istio-ingressgateway.istio-system

返回200響應碼(或其他有效HTTP響應),說明Pod已能夠訪問入口網關。