在 Standard 叢集中設定 IP 偽裝代理程式

本頁說明如何設定以 Google Kubernetes Engine (GKE) Standard 模式建立的叢集,透過 ip-masq-agent 執行 IP 偽裝。如要進一步瞭解 GKE Autopilot 模式中的 IP 偽裝,請參閱「使用 Egress NAT 政策在 Autopilot 叢集中設定 IP 偽裝」。

事前準備

開始之前,請務必先完成下列工作:

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝並初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行 gcloud components update 指令,取得最新版本。較舊的 gcloud CLI 版本可能不支援執行本文件中的指令。

正在檢查「ip-masq-agent」狀態

本節將說明如何:

  • 判斷叢集是否具有 ip-masq-agent DaemonSet。
  • 檢查 ip-masq-agent ConfigMap 資源。

檢查 ip-masq-agent DaemonSet

如要確認叢集是否正在執行 ip-masq-agent DaemonSet,請使用 Google Cloud CLI 或 Google Cloud 控制台。

gcloud

  1. 取得叢集的憑證:

    gcloud container clusters get-credentials CLUSTER_NAME
    

    將 CLUSTER_NAME 替換為叢集名稱。

  2. 在 kube-system 命名空間中搜尋 ip-masq-agent:

    kubectl get daemonsets/ip-masq-agent -n kube-system
    

    如果 ip-masq-agent DaemonSet 存在,輸出內容會與下列內容相似:

    NAME            DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
    ip-masq-agent   3         3         3       3            3           <none>          13d
    

    如果 ip-masq-agent DaemonSet 不存在,輸出內容會類似於下列內容:

    Error from server (NotFound): daemonsets.apps "ip-masq-agent" not found
    
  3. 檢查 ip-masq-agent DaemonSet 是否執行最新版本:

    kubectl get daemonsets/ip-masq-agent -n kube-system -o jsonpath='{.spec.template.spec.containers[].image}'
    

    這個指令必須傳回與「部署 ip-masq-agent DaemonSet」中指定的相同容器映像檔。

控制台

  1. 前往 Google Cloud 控制台的「Workloads」(工作負載) 頁面。

    前往「Workloads」(工作負載)

  2. 在「 篩選器」部分,執行下列操作:

    1. 按一下 ,清除「Is system object: False」(是系統物件:False) 篩選器。
    2. 篩選下列屬性:
      • 名稱:ip-masq-agent。
      • 叢集:叢集名稱。

    如果 ip-masq-agent DaemonSet 存在,您會在表格中看到 DaemonSet 記錄。如果 ip-masq-agent DaemonSet 不存在,就不會顯示任何資料列。

如要建立 ip-masq-agent ConfigMap 並部署 ip-masq-agent DaemonSet,請參閱「設定及部署 ip-masq-agent」。

檢查 ip-masq-agent ConfigMap

如要檢查叢集是否正在執行 ip-masq-agent ConfigMap,請使用 Google Cloud CLI 或 Google Cloud 控制台。

gcloud

  1. 取得叢集的憑證:

    gcloud container clusters get-credentials CLUSTER_NAME
    

    將 CLUSTER_NAME 替換為叢集名稱。

  2. 說明 kube-system 命名空間中的 ip-masq-agent ConfigMap:

    kubectl describe configmaps/ip-masq-agent -n kube-system
    

    如果 ip-masq-agent ConfigMap 存在,輸出內容會類似於下列內容:

    Name:         ip-masq-agent
    Namespace:    kube-system
    Labels:       <none>
    Annotations:  <none>
    
    Data
    ====
    config:
    ----
    nonMasqueradeCIDRs:
      - 198.15.5.92/24
      - 10.0.0.0/8
    masqLinkLocal: false
    resyncInterval: 60s
    
    BinaryData
    ====
    
    Events:  <none>
    

    如果 ip-masq-agent ConfigMap 不存在,輸出內容會類似於下列內容:

    Error from server (NotFound): configmaps "ip-masq-agent" not found
    

控制台

  1. 前往 Google Cloud 控制台的「Configuration」(設定) 頁面。

    前往「設定」

  2. 如要 篩選,請執行下列操作:

    1. 按一下 ,清除「Is system object: False」(是系統物件:False) 篩選器。
    2. 篩選下列屬性:
      • 名稱:ip-masq-agent。
      • 叢集:叢集名稱。

    如果 ip-masq-agent ConfigMap 存在,您會在表格中看到 ConfigMap 記錄。如果 ip-masq-agent ConfigMap 不存在,就不會顯示任何資料列。

如果叢集已有 ip-masq-agent ConfigMap,即可設定及部署。

設定及部署 ip-masq-agent

本節說明如何建立或編輯 ip-masq-agent ConfigMap,以及如何部署或刪除 ip-masq-agent DaemonSet。如要判斷需要執行的工作,請先判斷叢集是否已有 ip-masq-agent ConfigMap 和 ip-masq-agent DaemonSet。

建立 ip-masq-agent ConfigMap

下列步驟說明如何建立 ip-masq-agent ConfigMap。如果叢集已有 ip-masq-agent ConfigMap,請改為編輯現有的 ip-masq-agent ConfigMap。

  1. 使用下列範本建立設定檔,並儲存至本機。 您可以為這個設定檔的本機副本使用任何名稱。

    nonMasqueradeCIDRs:
      - CIDR_1
      - CIDR_2
    masqLinkLocal: false
    resyncInterval: SYNC_INTERVALUNIT_OF_TIME
    

    更改下列內容:

    • CIDR_1 和 CIDR_2:CIDR 格式的 IP 位址範圍。 當封包傳送至這些目的地時,叢集不會偽裝 IP 位址來源,並保留來源 Pod IP 位址。如果需要兩個以上的 CIDR,請按照相同格式在 nonMasqueradeCIDRs 清單中新增更多項目。至少 nonMasqueradeCIDRs 屬性應包含叢集的節點和 Pod IP 位址範圍。

    • SYNC_INTERVAL:每個 ip-masq-agent Pod 檢查 ip-masq-agent ConfigMap 內容,並將任何變更寫入本機 /etc/config/ip-masq-agent 檔案的時間間隔。預設為 60。

    • UNIT_OF_TIME:resyncInterval 的時間單位。 有效值包括 s (秒) 或 ms (毫秒)。預設為 s。

    除非您需要為傳送至連結本機 IPv4 位址的封包啟用偽裝功能,否則請將 masqLinkLocal 設為 false (預設值)。詳情請參閱「偽裝成連結本機目的地」。

  2. 建立 ConfigMap 資源:

    kubectl create configmap ip-masq-agent \
       --namespace=kube-system \
       --from-file=config=LOCAL_CONFIG_FILE_PATH
    

    將 LOCAL_CONFIG_FILE_PATH 替換為您在上一個步驟中建立的設定檔路徑。

  3. 說明 kube-system 命名空間中的 ip-masq-agent ConfigMap:

    kubectl describe configmaps/ip-masq-agent -n kube-system
    

    輸出結果會與下列內容相似:

    Name:         ip-masq-agent
    Namespace:    kube-system
    Labels:       <none>
    Annotations:  <none>
    
    Data
    ====
    config:
    ----
    nonMasqueradeCIDRs:
      - 198.15.5.92/24
      - 10.0.0.0/8
    masqLinkLocal: false
    resyncInterval: 60s
    
    BinaryData
    ====
    Events:  <none>
    
    

    這項輸出內容包含 config 參數,以及您的設定變更。 您現在可以部署 ip-masq-agent DaemonSet。

編輯現有的 ip-masq-agent ConfigMap

如要修改現有 ip-masq-agent ConfigMap 的內容,請完成下列步驟:

  1. 在文字編輯器中開啟 ConfigMap:

    kubectl edit configmap ip-masq-agent --namespace=kube-system
    
  2. 編輯 ConfigMap 檔案內容:

    apiVersion: v1
    data:
      config: |
        nonMasqueradeCIDRs:
          - CIDR_1
          - CIDR_2
        masqLinkLocal: false
        resyncInterval: SYNC_INTERVALUNIT_OF_TIME
    kind: ConfigMap
    metadata:
      name: ip-masq-agent
      namespace: kube-system
    

    更改下列內容:

    • CIDR_1 和 CIDR_2:CIDR 格式的 IP 位址範圍。 當封包傳送至這些目的地時,叢集不會偽裝 IP 位址來源,並保留來源 Pod IP 位址。如果需要兩個以上的 CIDR,請按照相同格式在 nonMasqueradeCIDRs 清單中新增更多項目。nonMasqueradeCIDRs 屬性至少應包含叢集的節點和 Pod IP 位址範圍。

    • SYNC_INTERVAL:每個 ip-masq-agent Pod 檢查 ip-masq-agent ConfigMap 內容,並將所有變更寫入本機 /etc/config/ip-masq-agent 檔案的時間間隔。預設為 60。

    • UNIT_OF_TIME:resyncInterval 的時間單位。 有效值包括 s (秒) 或 ms (毫秒)。預設為 s。

    除非需要為傳送至連結本機 IPv4 位址的封包啟用偽裝,否則請將 masqLinkLocal 設為 false (預設值)。詳情請參閱「偽裝成連結本機目的地」。

  3. 說明 kube-system 命名空間中的 ip-masq-agent ConfigMap:

    kubectl describe configmaps/ip-masq-agent -n kube-system
    

    輸出結果會與下列內容相似:

    Name:         ip-masq-agent
    Namespace:    kube-system
    Labels:       <none>
    Annotations:  <none>
    
    Data
    ====
    config:
    ----
    nonMasqueradeCIDRs:
      - 198.15.5.92/24
      - 10.0.0.0/8
    masqLinkLocal: false
    resyncInterval: 60s
    
    BinaryData
    ====
    
    Events:  <none>
    

    這項輸出內容包含 config 參數,與您建立的檔案中的設定值相符。

部署 ip-masq-agent DaemonSet

建立或編輯 ip-masq-agent ConfigMap 後,請部署 ip-masq-agent DaemonSet。

  1. 將下列資訊清單儲存為 YAML 檔案:

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: ip-masq-agent
      namespace: kube-system
    spec:
      selector:
        matchLabels:
          k8s-app: ip-masq-agent
      template:
        metadata:
          labels:
            k8s-app: ip-masq-agent
        spec:
          hostNetwork: true
          containers:
          - name: ip-masq-agent
            image: gke.gcr.io/ip-masq-agent:v2.12.6-gke.15@sha256:c51e89bdc5073fdbaaff8bf42b32765f7f1eb0fec7d6189de5f14c48ac489448
            args:
            - --v=2
            - --logtostderr=false
            - --log_file=/dev/stdout
            - --log_file_max_size=0
            # The masq-chain must be IP-MASQ
            - --masq-chain=IP-MASQ
            # To non-masquerade reserved IP ranges by default,
            # uncomment the following line.
            # - --nomasq-all-reserved-ranges
            # Must be set to false when using Dataplane V2.
            - --random-fully=false
            securityContext:
              privileged: false
              capabilities:
                drop: ["ALL"]
                add: ["NET_ADMIN", "NET_RAW"]
              allowPrivilegeEscalation: false
              seccompProfile:
                type: RuntimeDefault
            volumeMounts:
            - name: config-volume
              mountPath: /etc/config
          volumes:
          - name: config-volume
            configMap:
              name: ip-masq-agent
              optional: true
              items:
              - key: config
                path: ip-masq-agent
          tolerations:
          - effect: NoSchedule
            operator: Exists
          - effect: NoExecute
            operator: Exists
          - key: "CriticalAddonsOnly"
            operator: "Exists"

    這個資訊清單會建立名為 config-volume 的磁碟區,並按照容器的 volumeMount 指定方式掛接。

    如要編輯這份資訊清單,請考量下列條件:

    • 磁碟區名稱可以任意指定,但必須與容器的volumeMount名稱相符。

    • ConfigMap 名稱必須與 Pod 中 config-volume Volume 參照的名稱相符。configMap

    • 鏈結名稱 (--masq-chain) 必須是 IP-MASQ。否則,GKE 不會覆寫預設的偽裝規則。

    • 從 ip-masq-agent 檔案讀取的 DaemonSet Pod。ip-masq-agent 檔案內容是 ConfigMap 中 config 鍵的值。

    • 如果您預設使用非偽裝保留 IP 範圍,請取消註解 arg 區段中的 arg 行。- --nomasq-all-reserved-ranges

  2. 部署 DaemonSet:

    kubectl apply -f LOCAL_FILE_PATH
    

    將 LOCAL_FILE_PATH 替換為您在上一個步驟中建立的檔案路徑。

您可以手動更新建立的 ip-masq-agent DaemonSet。詳情請參閱「更新 DaemonSet」。

正在刪除「ip-masq-agent」

本節說明如何刪除 ip-masq-agent DaemonSet 和 ip-masq-agent ConfigMap。刪除 ip-masq-agent 不會還原節點上現有的 IP 偽裝設定。

刪除 ip-masq-agent DaemonSet

如果您手動建立 ip-masq-agent DaemonSet,可以執行下列指令刪除:

kubectl delete daemonsets ip-masq-agent -n kube-system

刪除 ip-masq-agent ConfigMap

如要徹底刪除 ip-masq-agent ConfigMap,請執行下列指令:

kubectl delete configmap ip-masq-agent -n kube-system

疑難排解

以下各節提供疑難排解建議。

一般疑難排解

請按照下列步驟診斷 IP 位址偽裝問題:

  • 確認 ip-masq-agent 的狀態。如果未定義 ConfigMap,則傳送至所有預設目的地的流量不會偽裝,並會保留 Pod IP 位址。前往其他目的地的流量會保留節點 IP 位址。
  • 確認 DaemonSet 中指定的 ip-masq-agent 映像檔版本。 如果 ip-masq-agent DaemonSet 不是最新版本,請按照部署步驟更新 DaemonSet。
  • 在受影響的節點中執行 sudo iptables -t nat -L IP-MASQ 指令,檢查 IP-MASQ 鏈結是否已正確填入 NAT IP 表格。如果 ConfigMap 中定義的 nonMasqueradeCIDRs 未顯示在 NAT IP 表格中,請確認用於建立 ConfigMap 的設定檔中沒有錯字。
  • 確認目的地允許節點和 Pod IP 位址範圍。
  • 如果無法從節點或 Pod 存取流量,請執行 Connectivity Tests。

問題:Pod IP 位址變更為節點 IP 位址

使用 IP 偽裝代理程式時,您可能會發現 Pod 與外部目的地通訊時,Pod 的來源 IP 位址會意外使用節點的 IP 位址。

問題原因是缺少或不完整的自訂來源網路位址轉譯 (SNAT) 清單。使用 IP 偽裝代理程式時,如果 ConfigMap 遺失或不含 nonMasqueradeCIDRs 清單,系統會使用叢集的預設 SNAT。封包離開 Pod 時,預設 SNAT 會將來源 IP 位址從 Pod 的 IP 位址變更為節點的內部 IP 位址。如要進一步瞭解 SNAT,請參閱「IP 偽裝代理程式」。

如要解決這個問題,請在 ip-masq-agent ConfigMap 中定義 nonMasqueradeCIDRs 清單,設定自訂 SNAT 清單:

  1. 開啟 ip-masq-agent ConfigMap:

    kubectl edit configmap ip-masq-agent --namespace=kube-system
    
  2. 查看 ConfigMap 中的 nonMasqueradeCIDRs 清單。nonMasqueradeCIDRs 清單應完整呈現。例如:

    ...
    nonMasqueradeCIDRs:
      - 35.100.0.0/16
    ...
    
  3. 如果清單缺漏或不完整,請新增或修改清單,納入要保留來源 Pod IP 位址的目的地 IP 範圍。nonMasqueradeCIDRs 這份清單也應包含您要使用 Cloud NAT 的位址。

    如果不想讓任何外部流量使用 SNAT,請將 nonMasqueradeCIDRs 欄位設為 0.0.0.0/0。例如:

    ...
    nonMasqueradeCIDRs:
      - 0.0.0.0/0
    ...
    

    如果流量未使用 SNAT,從 Pod 傳送的所有封包都會保留 Pod 的 IP 位址做為來源 IP 位址,無論目的地為何。

  4. 檢查 Pod 傳出封包的來源 IP 位址。如要檢查這個地址,請擷取封包。如果不可行,您可以使用下列指令,檢查節點的 IP 位址,該位址應為受 SNAT 影響的傳出封包來源 IP 位址:

    kubectl get nodes -o wide
    

後續步驟