全部產品
Search
文件中心

Container Service for Kubernetes:容器網路FAQ

更新時間:Aug 16, 2024

本文為您介紹使用網路外掛程式Terway或Flannel遇到的常見問題,以及如何解決。例如,如何選擇網路外掛程式、叢集是否支援安裝第三方網路外掛程式、如何規劃叢集網路等。

索引

Terway相關

Flannel相關

kube-proxy相關

IPv6相關

如何解決IPv6雙棧的部分常見問題?

其他

已經建立的ACK叢集是否支援切換網路外掛程式?

網路外掛程式類型(Terway和Flannel)僅支援在叢集建立階段選擇,叢集建立後不支援修改。如需切換,請重新建立叢集,具體操作,請參見建立ACK託管叢集

Terway網路模式下增加了虛擬交換器後,叢集無法訪問公網怎麼辦?

問題現象

在Terway網路下,因Pod沒有IP資源而手動增加虛擬交換器,在增加虛擬交換器後,發現叢集不能正常訪問公網。

問題原因

Pod IP所屬的虛擬交換器不具備公網訪問的能力。

解決方案

您可以通過NAT Gateway的SNAT功能,為Pod IP所屬的虛擬交換器配置公網SNAT規則。更多資訊,請參見為已有叢集開啟公網訪問能力

手動升級了Flannel鏡像版本後,如何解決無法相容1.16以上版本叢集的問題?

問題現象

叢集版本升級到1.16之後,叢集節點變成NotReady。

問題原因

手動升級了Flannel版本,而並沒有升級Flannel的配置,導致Kubelet無法識別。

解決方案

  1. 執行以下命令,編輯Flannel,增加cniVersion欄位。

    kubectl edit cm kube-flannel-cfg -n kube-system 

    返回結果中增加cniVersion欄位。

    "name": "cb0",   
    "cniVersion":"0.3.0",
    "type": "flannel",
  2. 執行以下命令,重啟Flannel。

    kubectl delete pod -n kube-system -l app=flannel

如何解決Pod啟動後存在時延的問題?

問題現象

Pod啟動後網路需要延遲一會才能通訊。

問題原因

配置Network Policy會有一定的時延,關閉Network Policy後,就能解決該問題。

解決方案

  1. 執行以下命令,修改Terway的ConfigMap,增加禁用NetworkPolicy的配置。

    kubectl edit cm -n kube-system eni-config 

    在返回結果中增加以下欄位。

    disable_network_policy: "true"
  2. 可選:如果Terway版本不是最新的,請在控制台升級Terway版本。

    1. 登入Container Service管理主控台,在左側導覽列選擇叢集

    2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇營運管理 > 組件管理

    3. 組件管理頁面,單擊網路頁簽,單擊目標Terway組件地區的升級

    4. 提示對話方塊,單擊確定

  3. 執行以下命令,重啟所有Terway的Pod。

     kubectl delete pod -n kube-system -l app=terway-eniip

如何讓Pod訪問自己暴露的服務?

問題現象

Pod無法訪問自己暴露的服務,存在時好時壞或者調度到自己就出問題的現象。

問題原因

Flannel叢集可能未開啟迴環訪問。

說明
  • 低於v0.15.1.4-e02c8f12-aliyun版本的Flannel不允許迴環訪問。升級版本後,仍預設不允許迴環訪問,但可以手動開啟。

  • 只有全新部署的v0.15.1.4-e02c8f12-aliyun及以上版本的Flannel,才預設開啟迴環訪問。

解決方案

  • 使用Headless Service暴露服務和訪問,具體操作,請參見Headless Services

    說明

    推薦使用此方法。

  • 重建叢集使用Terway的網路外掛程式,具體操作,請參見使用Terway網路外掛程式

  • 修改Flannel的配置,然後重建Flannel和Pod。

    說明

    不推薦此方法,可能會被後續升級覆蓋。

    1. 執行以下命令編輯cni-config.json

      kubectl edit cm kube-flannel-cfg -n kube-system
    2. 在返回結果的delegate中增加hairpinMode: true

      樣本如下:

      cni-conf.json: |
          {
            "name": "cb0",
            "cniVersion":"0.3.1",
            "type": "flannel",
            "delegate": {
              "isDefaultGateway": true,
              "hairpinMode": true
            }
          }
    3. 執行以下命令,重啟Flannel。

      kubectl delete pod -n kube-system -l app=flannel   
    4. 刪除並重新建立Pod。

如何選擇Kubernetes叢集Terway和Flannel網路外掛程式?

下面為您詳細介紹在ACK建立叢集時使用的兩種網路外掛程式:Terway和Flannel。

在建立Kubernetes叢集時,阿里雲Container Service提供以下兩種網路外掛程式:

  • Flannel:使用的是簡單穩定的社區的Flannel CNI外掛程式,配合阿里雲的VPC的高速網路,能給叢集高效能和穩定的容器網路體驗,但功能偏簡單,支援的特性少,例如:不支援基於Kubernetes標準的Network Policy。

  • Terway:是阿里雲Container Service自研的網路外掛程式,功能上完全相容Flannel,支援將阿里雲的彈性網卡分配給容器,支援基於Kubernetes標準的NetworkPolicy來定義容器間的存取原則,支援對單個容器做頻寬的限流。對於不需要使用Network Policy的使用者,可以選擇Flannel,其他情況建議選擇Terway。瞭解更多Terway網路外掛程式的相關內容,請參見使用Terway網路外掛程式

如何規劃叢集網路?

在建立ACK叢集時,需要指定Virtual Private Cloud、虛擬交換器、Pod網路CIDR(位址區段)和Service CIDR(位址區段)。建議您提前規劃ECS地址、Kubernetes Pod地址和Service地址。詳情請參見Kubernetes叢集網路規劃

ACK是否支援hostPort的連接埠映射?

  • 只有Flannel外掛程式支援hostPort,其他外掛程式暫不支援hostPort。

  • Container ServiceACK的Pod地址是可以直接被VPC中其他資源訪問的,不需要額外的連接埠映射。

  • 如果需要把服務暴露到外部,可以使用NodePort或者LoadBalancer類型的Service。

如何查看叢集的網路類型及對應的虛擬交換器?

ACK支援兩種容器網路類型,分別是Flannel網路類型和Terway網路類型。

通過以下步驟查看您建立叢集時所選擇的網路類型

  1. 登入Container Service管理主控台,在左側導覽列單擊叢集

  2. 在叢集列表頁面中,單擊目的地組群名稱或者目的地組群右側操作列下的詳情

  3. 單擊基本資料頁簽,在叢集資訊地區查看叢集的容器網路類型,即網路外掛程式右側的值。

    • 如果網路外掛程式右側顯示terway-eniip ,則容器的網路類型為Terway網路。

    • 如果網路外掛程式右側顯示Flannel,則容器的網路類型為Flannel網路。

通過以下步驟查看對應網路類型使用的節點虛擬交換器

  1. 登入Container Service管理主控台,在左側導覽列單擊叢集

  2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇節點管理 > 節點池

  3. 節點池頁面,單擊目標節點池右側操作列下的詳情

    節點配置地區查看節點虛擬交換器ID。

通過以下步驟查詢Terway網路類型使用的Pod虛擬交換器ID

說明

只有Terway網路類型使用Pod虛擬交換器,Flannel網路類型無需使用Pod虛擬交換器。

  1. 登入Container Service管理主控台,在左側導覽列單擊叢集

  2. 在叢集列表中單擊目的地組群名稱或目的地組群右側操作列下的詳情

  3. 在叢集資訊頁面,單擊叢集資源頁簽,然後查看Pod虛擬交換器ID。

如何查看叢集中使用的雲資源?

通過以下步驟查看叢集中使用的雲資源資訊,包括虛擬機器、Virtual Private Cloud絡VPC、Worker RAM角色等。

  1. 登入Container Service管理主控台,在左側導覽列單擊叢集

  2. 在叢集列表頁面中,單擊目的地組群名稱或者目的地組群右側操作列下的詳情

  3. 單擊叢集資源頁簽,查看叢集中使用的雲資源資訊。

如何修改kube-proxy配置?

ACK託管版預設部署kube-proxy-worker DaemonSet作為負載平衡,可通過其同名配置項kube-proxy-worker ConfigMap控制其參數。如果您使用的是ACK專有版,您在叢集中會額外部署kube-proxy-master DaemonSet和同名配置項,其會運行於Master節點上。

kube-proxy配置項均相容社區KubeProxyConfiguration標準,您可以參考社區KubeProxyConfiguration標準進行自訂配置,更多資訊,請參見kube-proxy Configuration。kube-proxy設定檔對格式要求嚴格,請勿漏填冒號和空格。修改kube-proxy配置操作如下:

  • 如果您使用的是託管版叢集,您需要修改kube-proxy-worker的配置。

    1. 登入Container Service管理主控台,在左側導覽列單擊叢集

    2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇組態管理 > 配置項

    3. 在頂部選擇kube-system命名空間,然後單擊配置項kube-proxy-worker右側的YAML編輯

    4. 查看YAML面板上修改參數,然後單擊確定

    5. 重建所有名為kube-proxy-worker的容器,使配置生效。

      重要

      kube-proxy的重啟不會導致已有運行業務中斷,如果有並發業務發布,新啟動的業務在kube-proxy的生效時間會略有延遲,請盡量於業務低峰期操作。

      1. 在叢集管理頁左側導覽列中,選擇工作負載 > 守護進程集

      2. 在守護進程集列表中,找到並單擊kube-proxy-worker

      3. kube-proxy-worker頁面的容器組頁簽下,選擇更多 > 刪除,然後單擊確定

        重複操作刪除所有容器組。刪除容器組後,系統會自動重建所有容器。

  • 如果您使用的是專有版叢集,您需要修改kube-proxy-worker和kube-proxy-master的配置,然後刪除kube-proxy-worker和kube-proxy-master Pod,該Pod自動重新建立後會使配置生效。具體操作,請參見上文。

如何提升Linux串連跟蹤Conntrack數量限制?

核心日誌(dmesg)中出現conntrack full的報錯日誌,說明Conntrack數量已經達到conntrack_max數量限制。您需要提升Linux串連跟蹤Conntrack數量限制。

  1. 執行conntrack -L命令,確認目前Conntrack中的各協議佔用情況。

    • 如果出現大量TCP協議的佔用,您需要確認具體業務,如果是短串連型應用可以考慮整改成長串連型。

    • 如果出現大量DNS的佔用,您需要在ACK叢集中使用NodeLocal DNSCache,提高DNS的效能,具體操作,請參見使用NodeLocal DNSCache

  2. 如果Conntrack實際佔用情況合理,或者您不希望對業務進行整改,您可以通過配置kube-proxy增加maxPerCore參數,調整串連跟蹤數量限制。

    • 如果您使用的是託管版叢集,您需要在kube-proxy-worker中增加maxPerCore參數,並設定其值為65536或更高的數值,然後刪除kube-proxy-worker Pod,該Pod自動重新建立後會使配置生效。關於如何修改並刪除kube-proxy-worker,請參見如何修改kube-proxy配置?

      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: kube-proxy-worker
        namespace: kube-system
      data:
        config.conf: |
          apiVersion: kubeproxy.config.k8s.io/v1alpha1
          kind: KubeProxyConfiguration
          featureGates:
            IPv6DualStack: true
          clusterCIDR: 172.20.0.0/16
          clientConnection:
            kubeconfig: /var/lib/kube-proxy/kubeconfig.conf
          conntrack:
            maxPerCore: 65536 # 需設定maxPerCore至合理值,此處65536為預設設定。
          mode: ipvs
      # 其它略
    • 如果您使用的是專有版叢集,您需要在kube-proxy-worker和kube-proxy-master中增加maxPerCore參數,並設定其值為65536或更高的數值,然後刪除kube-proxy-worker和kube-proxy-master Pod,該Pod自動重新建立後會使配置生效。關於如何修改並刪除kube-proxy-worker和kube-proxy-master,請參見如何修改kube-proxy配置?

如何修改kube-proxy中IPVS負載平衡模式?

您可以通過修改kube-proxy中IPVS負載平衡模式來解決大量長串連的負載不均問題,具體操作如下:

  1. 選擇合適的調度演算法。關於如何選擇合適的調度演算法,請參見K8s官方文檔parameter-changes

  2. 早於2022年10月建立的叢集節點可能未預設啟用所有IPVS調度演算法,您需要手動在所有叢集節點上啟用IPVS調度演算法核心模組(以最小串連數調度演算法lc為例,如果選用其他演算法,請替換lc關鍵字),逐台登入每個節點,並運行lsmod | grep ip_vs_lc查看是否有輸出。

    • 如果命令輸出ip_vs_lc,則說明調度演算法核心模組已經載入,可以跳過本步驟。

    • 如果沒有載入,運行modprobe ip_vs_lc使節點立即生效,並運行echo "ip_vs_lc" >> /etc/modules-load.d/ack-ipvs-modules.conf使機器重啟後生效。

  3. 設定kube-proxy中的ipvs scheduler參數值為合理的調度演算法。

    • 如果您使用的是託管版叢集,您需要修改kube-proxy-worker的ipvs scheduler參數值為合理的調度演算法,然後刪除kube-proxy-worker Pod,該Pod自動重新建立後會使配置生效。關於如何修改並刪除kube-proxy-worker,請參見如何修改kube-proxy配置?

      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: kube-proxy-worker
        namespace: kube-system
      data:
        config.conf: |
          apiVersion: kubeproxy.config.k8s.io/v1alpha1
          kind: KubeProxyConfiguration
          featureGates:
            IPv6DualStack: true
          clusterCIDR: 172.20.0.0/16
          clientConnection:
            kubeconfig: /var/lib/kube-proxy/kubeconfig.conf
          conntrack:
            maxPerCore: 65536
          mode: ipvs
          ipvs:
            scheduler: lc # 需設定scheduler成合理的調度演算法。
      # 其它略
    • 如果您使用的是專有版叢集,您需要修改kube-proxy-worker和kube-proxy-master中的ipvs scheduler參數值為合理的調度演算法,然後刪除kube-proxy-worker和kube-proxy-master Pod,該Pod自動重新建立後會使配置生效。關於如何修改並刪除kube-proxy-worker和kube-proxy-master,請參見如何修改kube-proxy配置?

  4. 查看kube-proxy作業記錄。

    • 通過kubectl get pods命令查看kube-system命名空間下建立的kube-proxy-worker容器(如果您使用專有版叢集,還需查看kube-proxy-master)是否為Running狀態。

    • 通過kubectl logs命令查看建立容器的日誌。

      • 如果出現Can't use the IPVS proxier: IPVS proxier will not be used because the following required kernel modules are not loaded: [ip_vs_lc]則說明IPVS調度演算法核心模組未成功載入,您需要檢查上述步驟是否已經正確執行,並嘗試重試。

      • 如果出現Using iptables Proxier.說明kube-proxy無法啟用IPVS模組,開始自動回退使用iptables模式,此時建議先復原kube-proxy配置,再對機器進行重啟操作。

      • 如果未出現上述日誌,並顯示Using ipvs Proxier.說明IPVS模組成功啟用。

    • 如果上述檢查均返回正常,說明變更成功。

如何修改kube-proxy中IPVS UDP會話保持的逾時時間?

如果您的ACK叢集使用了kube-proxy IPVS模式,IPVS的預設會話保持策略會使UDP協議後端在摘除後五分鐘內出現機率性丟包的問題。如果您業務依賴於CoreDNS,當CoreDNS組件升級或所在節點重啟時,您可能會在五分鐘內遇到業務介面延遲、請求逾時等現象。

若您在ACK叢集中的業務沒有使用UDP協議,您可以通過降低IPVS UDP協議的會話保持的逾時時間來減少解析延遲或失敗的影響時間。具體操作如下:

說明

若您的自有業務使用了UDP協議,請提交工單諮詢。

  • K8s 1.18及以上版本叢集

    • 如果您使用的是託管版叢集,您需要在kube-proxy-worker中修改udpTimeout參數值。然後刪除kube-proxy-worker Pod,該Pod自動重新建立後會使配置生效。關於如何修改並刪除kube-proxy-worker,請參見如何修改kube-proxy配置?

      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: kube-proxy-worker
        namespace: kube-system
      data:
        config.conf: |
          apiVersion: kubeproxy.config.k8s.io/v1alpha1
          kind: KubeProxyConfiguration
          # 其它不相關欄位已省略。
          mode: ipvs
          # 如果ipvs鍵不存在,需要添加此鍵。
          ipvs:
            udpTimeout: 10s # 此處預設為300秒,調整成10秒可以將IPVS UDP類型後端摘除後丟包問題的影響時間縮短到10秒。
    • 如果您使用的是專有版叢集,您需要在kube-proxy-worker和kube-proxy-master中修改udpTimeout參數值。然後刪除kube-proxy-worker和kube-proxy-master Pod,該Pod自動重新建立後會使配置生效。關於如何修改並刪除kube-proxy-worker,請參見如何修改kube-proxy配置?

  • K8s 1.16及以下版本叢集

    此類版本叢集的kube-proxy不支援udpTimeout參數,推薦使用CloudOps Orchestration Service (OOS)批量在所有叢集機器上執行ipvsadm命令以調整UDP逾時時間配置。命令如下:

    yum install -y ipvsadm
    ipvsadm -L --timeout > /tmp/ipvsadm_timeout_old
    ipvsadm --set 900 120 10
    ipvsadm -L --timeout > /tmp/ipvsadm_timeout_new
    diff /tmp/ipvsadm_timeout_old /tmp/ipvsadm_timeout_new

    關於OOS的大量操作執行個體介紹,請參見大量操作執行個體

如何解決IPv6雙棧的部分常見問題?

  • 問題現象:在kubectl中顯示的Pod IP仍然是IPv4地址。

    解決方案:執行以下命令,展示Pod IPs欄位,預期輸出IPv6地址。

    kubectl get pods -A -o jsonpath='{range .items[*]}{@.metadata.namespace} {@.metadata.name} {@.status.podIPs[*].ip} {"\n"}{end}'
  • 問題現象:在kubectl中顯示的Cluster IP仍然是IPv4地址。

    解決方案:

    1. 請確認spec.ipFamilyPolicy配置的不是SingleStack。

    2. 執行以下命令,展示Cluster IPs欄位,預期輸出IPv6地址。

      kubectl get svc -A -o jsonpath='{range .items[*]}{@.metadata.namespace} {@.metadata.name} {@.spec.ipFamilyPolicy} {@.spec.clusterIPs[*]} {"\n"}{end}'
  • 問題現象:無法通過IPv6地址訪問Pod。

    問題原因:部分應用預設不監聽IPv6地址,例如Nginx容器。

    解決方案:執行netstat -anp命令,確認Pod已監聽IPv6地址。

    預期輸出:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
    tcp        0      0 127.0.XX.XX:10248         0.0.0.0:*               LISTEN      8196/kubelet
    tcp        0      0 127.0.XX.XX:41935         0.0.0.0:*               LISTEN      8196/kubelet
    tcp        0      0 0.0.XX.XX:111             0.0.0.0:*               LISTEN      598/rpcbind
    tcp        0      0 0.0.XX.XX:22              0.0.0.0:*               LISTEN      3577/sshd
    tcp6       0      0 :::30500                :::*                    LISTEN      1916680/kube-proxy
    tcp6       0      0 :::10250                :::*                    LISTEN      8196/kubelet
    tcp6       0      0 :::31183                :::*                    LISTEN      1916680/kube-proxy
    tcp6       0      0 :::10255                :::*                    LISTEN      8196/kubelet
    tcp6       0      0 :::111                  :::*                    LISTEN      598/rpcbind
    tcp6       0      0 :::10256                :::*                    LISTEN      1916680/kube-proxy
    tcp6       0      0 :::31641                :::*                    LISTEN      1916680/kube-proxy
    udp        0      0 0.0.0.0:68              0.0.0.0:*                           4892/dhclient
    udp        0      0 0.0.0.0:111             0.0.0.0:*                           598/rpcbind
    udp        0      0 47.100.XX.XX:323           0.0.0.0:*                           6750/chronyd
    udp        0      0 0.0.0.0:720             0.0.0.0:*                           598/rpcbind
    udp6       0      0 :::111                  :::*                                598/rpcbind
    udp6       0      0 ::1:323                 :::*                                6750/chronyd
    udp6       0      0 fe80::216:XXXX:fe03:546 :::*                                6673/dhclient
    udp6       0      0 :::720                  :::*                                598/rpcbind

    Proto顯示為tcp即監聽IPv4地址,顯示為tcp6即監聽IPv6地址。

  • 問題現象:通過IPv6地址可以在叢集內訪問Pod,但無法從公網訪問。

    問題原因:該IPv6地址可能未配置公網頻寬。

    解決方案:配置該IPv6地址的公網頻寬。具體操作,請參見開通和管理IPv6公網頻寬

  • 問題現象:無法通過IPv6 Cluster IP訪問Pod。

    解決方案:

    1. 請確認spec.ipFamilyPolicy配置的不是SingleStack。

    2. 執行netstat -anp命令,確認Pod已監聽IPv6地址。

      預期輸出:

      Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
      tcp        0      0 127.0.XX.XX:10248         0.0.0.0:*               LISTEN      8196/kubelet
      tcp        0      0 127.0.XX.XX:41935         0.0.0.0:*               LISTEN      8196/kubelet
      tcp        0      0 0.0.XX.XX:111             0.0.0.0:*               LISTEN      598/rpcbind
      tcp        0      0 0.0.XX.XX:22              0.0.0.0:*               LISTEN      3577/sshd
      tcp6       0      0 :::30500                :::*                    LISTEN      1916680/kube-proxy
      tcp6       0      0 :::10250                :::*                    LISTEN      8196/kubelet
      tcp6       0      0 :::31183                :::*                    LISTEN      1916680/kube-proxy
      tcp6       0      0 :::10255                :::*                    LISTEN      8196/kubelet
      tcp6       0      0 :::111                  :::*                    LISTEN      598/rpcbind
      tcp6       0      0 :::10256                :::*                    LISTEN      1916680/kube-proxy
      tcp6       0      0 :::31641                :::*                    LISTEN      1916680/kube-proxy
      udp        0      0 0.0.0.0:68              0.0.0.0:*                           4892/dhclient
      udp        0      0 0.0.0.0:111             0.0.0.0:*                           598/rpcbind
      udp        0      0 47.100.XX.XX:323           0.0.0.0:*                           6750/chronyd
      udp        0      0 0.0.0.0:720             0.0.0.0:*                           598/rpcbind
      udp6       0      0 :::111                  :::*                                598/rpcbind
      udp6       0      0 ::1:323                 :::*                                6750/chronyd
      udp6       0      0 fe80::216:XXXX:fe03:546 :::*                                6673/dhclient
      udp6       0      0 :::720                  :::*                                598/rpcbind

      Proto顯示為tcp即監聽IPv4地址,顯示為tcp6即監聽IPv6地址。

    3. 問題現象:Pod無法通過IPv6訪問公網。

      解決方案:對IPv6使用公網,需要開通IPv6網關,並對IPv6地址配置公網頻寬。詳細資料,請參見建立和管理IPv6網關開通和管理IPv6公網頻寬

Container ServiceKubernetes的Terway網路情境中交換器的IP資源不足

  • 問題描述

在建立Pod時發現無法建立,登入VPC控制台,選擇目標地區,在左側導覽列單擊交換器,查看叢集使用的交換器(vSwitch)資訊,發現該vSwitch可用IP數為0。如何進一步確認問題請參見更多資訊

  • 問題原因

該節點的Terway所使用的vSwitch沒有空餘IP地址,導致Pod會因為沒有IP資源而一直處於ContainerCreating狀態。

  • 解決方案

    您可以參考以下內容,擴容vSwitch,即添加新的vSwitch,擴容叢集的IP資源:

    1. 登入VPC控制台,選擇目標地區,建立新的vSwitch。

      說明

      該vSwitch必須與IP資源不足的vSwitch在同一個地區和可用性區域。如果Pod密度越來越大,建議給Pod使用的vSwitch網段的網路位小於等於19,也就是網段至少包含8192個IP地址。

    2. 參考以下命令,刪除全部Terway Pod,刪除後Terway Pod會重新建立。

      說明

      如果您在建立叢集時,使用Terway並勾選了Pod獨佔彈性網卡以獲得最佳效能,說明您是ENI單IP;沒有勾選則是ENI多IP,詳細資料請參見Terway網路外掛程式

      • 針對ENI多IP情境:kubectl delete -n kube-system pod -l app=terway-eniip

      • 針對ENI單IP情境:kubectl delete -n kube-system pod -l app=terway-eni

    3. 然後執行kubectl get pod命令,確認全部Terway Pod重建成功。

    4. 建立新的Pod,確認Pod建立成功且可以重新vSwitch成功分配獲得IP。

  • 更多資訊

    串連Kubernetes叢集,如何串連請參見通過kubectl串連Kubernetes叢集,執行kubectl get pod命令,發現Pod狀態為ContainerCreating。執行以下命令,查看Pod所在節點上的Terway容器的日誌。

    kubectl get pod -l app=terway-eniip -n kube-system | grep [$Node_Name] # [$Node_Name] 為Pod所在節點的節點名,用來找出該節點上的Terway Pod的名稱
    kubectl logs --tail=100 -f [$Pod_Name] -n kube-system -c terway # [$Pod_Name]為Pod所在節點上的Terway Pod的名稱。

    系統顯示類似如下,出現類似InvalidVSwitchId.IpNotEnough錯誤資訊,表明存在交換器IP不足的情況。

    time="2020-03-17T07:03:40Z" level=warning msg="Assign private ip address failed: Aliyun API Error: RequestId: 2095E971-E473-4BA0-853F-0C41CF52651D Status Code: 403 Code: InvalidVSwitchId.IpNotEnough Message: The specified VSwitch \"vsw-AAA\" has not enough IpAddress., retrying"

Terway網路模式下,Pod分配的IP不在虛擬交換器網段中怎麼辦?

問題現象

在Terway網路下,建立的Pod IP不在配置的虛擬交換器網段內。

問題原因

Pod IP來源於VPC地址,並且通過ENI分配給容器使用。只有在建立ENI時,才可以配置虛擬交換器。如果ENI已經建立,則Pod IP將繼續從該ENI對應的虛擬交換器中分配。

通常以下兩個使用情境會遇到該問題:

  • 納管一個節點到叢集內,但這個節點之前在其他叢集使用,且刪除節點時沒有排空節點Pod。這種情況下節點上可能殘留之前叢集使用的ENI資源。

  • 手動增加、修改Terway使用的虛擬交換器配置,由於節點上可能還存在原有配置的ENI,則建立的Pod將可能繼續使用原有ENI上的IP。

解決方案

您可以通過建立節點、輪轉老節點的方式來確保設定檔在新節點上生效。

輪轉老節點操作步驟如下:

  1. 排空並移除老節點。操作詳情,請參考移除節點

  2. 將移出的節點的Eni網卡解除綁定。操作詳情,請參見解除綁定輔助彈性網卡

  3. 彈性網卡解除後,再將移出節點添加回原ACK叢集中。操作詳情,請參見添加已有節點

Terway網路模式擴容vSwitch後,依然無法分配Pod IP怎麼辦?

問題現象

在Terway網路下,Terway網路模式擴容vSwitch後依然無法分配Pod IP。

問題原因

Pod IP來源於VPC地址,並且通過ENI分配給容器使用。只有在建立ENI時,才可以配置虛擬交換器。如果ENI已經建立,則Pod IP將繼續從該ENI對應的虛擬交換器中分配。由於節點上ENI配額已經用完,無法建立ENI,也就無法讓新配置生效。關於ENI配額的具體資訊,請參見彈性網卡概述

解決方案

您可以通過建立節點、輪轉老節點的方式來確保設定檔在新節點上生效。

輪轉老節點操作步驟如下:

  1. 排空並移除老節點。操作詳情,請參考移除節點

  2. 將移出的節點的Eni網卡解除綁定。操作詳情,請參見解除綁定輔助彈性網卡

  3. 彈性網卡解除後,再將移出節點添加回原ACK叢集中。操作詳情,請參見添加已有節點

如何為Terway IPvlan叢集開啟叢集內負載平衡?

問題現象

在IPvlan模式下,v1.2.0及以上版本的Terway,建立的叢集預設開啟叢集內負載平衡功能。在叢集內訪問ExternalIP,LoadBalancer流量將被負載到Service網路。如何為已建立的Terway IPvlan叢集開啟叢集內負載平衡?

問題原因

Kube-Proxy會短路叢集內訪問ExternalIP、LoadBalancer的流量,即叢集內訪問這些外部地址,實際流量不會到外部,而會被轉為對應後端的Endpoint直接存取。在Terway IPvlan模式下,Pod訪問這些地址流量由Cilium而不是kube-proxy進行處理, 在Terway v1.2.0之前版本並不支援這種鏈路的短路。在Terway v1.2.0版本發布後,建立叢集將預設開啟該功能,已建立的叢集不會開啟。

解決方案

說明
  • Terway需要v1.2.0及以上版本,且使用IPvlan模式。

  • 如果叢集未啟用IPvlan模式,則該配置無效,無需配置。

  • 建立叢集此功能預設開啟,無需配置。

  1. 執行以下命令,修改Terway的配置ConfigMap。

    kubectl edit cm eni-config -n kube-system
  2. eni_conf中增加以下內容。

    in_cluster_loadbalance: "true"
    說明

    請保持in_cluster_loadbalanceeni_conf在同層級。

  3. 執行以下命令,重建Terway Pod,使叢集內負載平衡配置生效。

    kubectl delete pod -n kube-system -l app=terway-eniip

    驗證配置

    執行以下命令,檢查terway-ennippolicy日誌,如果顯示enable-in-cluster-loadbalance=true則配置生效。

    kubectl logs -n kube-system <terway pod name> policy | grep enable-in-cluster-loadbalance

如何在ACK中對Terway網路下的Pod指定網段加白?

問題現象

您通常需要在一些類似資料庫之類的服務設定白名單,以此來給服務提供更安全的存取控制能力。在容器網路下同樣有此需求,需要在容器中給動態變化的Pod IP設定白名單。

問題原因

ACK的容器網路主要有Flannel和Terway兩種:

  • 在Flannel網路下,因為Pod是通過節點訪問其他服務,所以在Flannel網路下的資料庫設定白名單時,首先可以將用戶端Pod通過節點綁定的方式調度到固定的少數節點上去,然後在資料庫側直接對節點的IP地址做加白操作即可。

  • 在Terway網路下,Pod IP是通過ENI提供。Pod通過ENI訪問外部服務,外部服務得到的用戶端IP是ENI提供的IP地址,即使把Pod和節點設定了親和性綁定,Pod訪問外部服務的用戶端IP仍然是ENI提供的IP而不是節點的IP。Pod IP還是會從Terway指定的vSwitch中隨機分配IP地址,而且用戶端Pod通常都會有自動調整之類的配置,那即使能固定Pod IP也很難滿足Auto Scaling的情境,建議直接給用戶端指定一個網段來分配IP,然後在資料庫側對這個網段來做加白操作。

解決方案

通過給指定節點添加標籤來指定Pod使用的vSwitch,從而當Pod調度到有固定標籤的節點上時,該Pod就可以通過自訂的vSwitch去建立Pod IP。

  1. 在kube-system命名空間下單獨建立一個名稱為eni-config-fixed的ConfigMap ,其中需要指定專門的vSwitch。

    本樣本以vsw-2zem796p76viir02c****,10.2.1.0/24為例。

    apiVersion: v1
    data:
      eni_conf: |
        {
           "vswitches": {"cn-beijing-h":["vsw-2zem796p76viir02c****"]},
           "security_group": "sg-bp19k3sj8dk3dcd7****",
           "security_groups": ["sg-bp1b39sjf3v49c33****","sg-bp1bpdfg35tg****"]
        }
    kind: ConfigMap
    metadata:
      name: eni-config-fixed
      namespace: kube-system
    
                            
  2. 建立節點池,為節點打上標籤terway-config:eni-config-fixed。關於建立節點池的具體操作,請參見操作步驟

    為了保證該節點池內的節點上不會出現其他Pod,可以給該節點池同時配置上汙點,例如fixed=true:NoSchedule節點標籤.png

  3. 擴容該節點池。具體操作,請參見擴縮容ACK叢集的節點

    通過該節點池擴容出來的節點預設會帶有上一步設定的節點標籤和汙點。

  4. 建立Pod,調度到已有terway-config:eni-config-fixed標籤的節點上,需要添加容忍。

    apiVersion: apps/v1 # 1.8.0以前的版本請使用apps/v1beta1。
    kind: Deployment
    metadata:
      name: nginx-fixed
      labels:
        app: nginx-fixed
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx-fixed
      template:
        metadata:
          labels:
            app: nginx-fixed
        spec:
          tolerations:        # 添加容忍。
          - key: "fixed"
            operator: "Equal"
            value: "true"
            effect: "NoSchedule"
          nodeSelector:
            terway-config: eni-config-fixed
          containers:
          - name: nginx
            image: nginx:1.9.0 #替換成您實際的鏡像<image_name:tags>。
            ports:
            - containerPort: 80

    結果驗證

    1. 執行以下命令,查看Pod IP。

      kubectl get po -o wide | grep fixed

      預期輸出:

      nginx-fixed-57d4c9bd97-l****                   1/1     Running             0          39s    10.2.1.124    bj-tw.062149.aliyun.com   <none>           <none>
      nginx-fixed-57d4c9bd97-t****                   1/1     Running             0          39s    10.2.1.125    bj-tw.062148.aliyun.com   <none>           <none>

      可以看到Pod IP已經從指定的vSwitch分配。

    2. 執行以下命令,將Pod擴容到30個。

      kubectl scale deployment nginx-fixed --replicas=30

      預期輸出:

      nginx-fixed-57d4c9bd97-2****                   1/1     Running     0          60s     10.2.1.132    bj-tw.062148.aliyun.com   <none>           <none>
      nginx-fixed-57d4c9bd97-4****                   1/1     Running     0          60s     10.2.1.144    bj-tw.062149.aliyun.com   <none>           <none>
      nginx-fixed-57d4c9bd97-5****                   1/1     Running     0          60s     10.2.1.143    bj-tw.062148.aliyun.com   <none>           <none>
      ...

      可以看到產生的Pod IP全部在指定的vSwitch下,然後在資料庫側直接對此vSwitch做加白操作,從而實現給動態Pod IP做存取控制。

說明
  • 建議您使用新建立的節點,如果使用已有節點,需要在節點添加進叢集之前先將ENI和ECS執行個體解除綁定,再添加進叢集。添加方式要選用自動添加已有節點(替換系統硬碟)。具體操作,請參見解除綁定輔助彈性網卡自動添加節點

  • 注意給特定的節點池打上標籤和汙點,儘可能保證不需要加白的業務不會調度到這部分節點上。

  • 這個設定白名單的方法其實是配置覆蓋,ACK會用現在指定的ConfigMap裡的配置來覆蓋之前的eni-config的配置,關於配置參數的具體資訊,請參見Terway節點動態配置

  • 指定vSwitch的IP個數建議為預計Pod個數的2倍(或更多),一方面可以給將來的擴容多一些餘量,另外也可以避免當發生故障導致Pod IP無法及時回收時,出現沒有IP可分配的情況。

為什麼Pod無法ping通部分ECS節點?

問題現象

Flannel網路模式下,檢查VPN路由正常,進入Pod,發現部分ECS節點無法ping通。

問題原因

Pod無法ping通部分ECS節點的原因分為兩種。

  • 原因一:Pod訪問的ECS和叢集在同一個VPC下,但不在同一個安全性群組。

  • 原因二:Pod訪問的ECS和叢集不在同一個VPC下。

解決方案

根據不同的原因,提供不同的解決方案。

  • 針對原因一,需要將ECS加入到叢集的安全性群組中。具體操作,請參見配置安全性群組

  • 針對原因二,需要通過ECS的公網入口訪問,需要在ECS的安全性群組中加入叢集的公網出口IP地址。

為什麼叢集節點有NodeNetworkUnavailable汙點?

問題現象

Flannel網路模式下,新增的叢集節點上有NodeNetworkUnavailable汙點,導致Pod無法調度。

問題原因

Cloud Controller Manager沒有及時刪除該節點汙點,可能原因是路由表滿、VPC存在多路由表等情況。

解決方案

使用kubectl describe node命令查看節點的Event事件資訊,根據實際輸出的報錯進行處理。關於多路由表的問題,需要手動設定CCM的支援,更多詳情請參見使用VPC的多路由表功能

為什麼Pod無法正常啟動,且報錯no IP addresses available in range?

問題現象

Flannel網路模式下,Pod無法正常啟動,查看Pod事件時顯示類似於failed to allocate for range 0: no IP addresses available in range set: 172.30.34.129-172.30.34.190的錯誤資訊。

問題原因

Flannel網路模式下,每個叢集節點會被分配到一個指定的容器IP段。容器調度到節點上時,Flannel會從節點所屬的容器IP段中擷取一個未被佔用的IP分配給容器。當Pod提示failed to allocate for range 0: no IP addresses available in range set: 172.30.34.129-172.30.34.190錯誤資訊時,說明沒有IP可以分配給Pod。該種情況有可能是發生了IP地址泄露,存在以下兩個原因:

  • ACK低於1.20版本時,如果發生Pod反覆重啟、CronJob中Pod短時間內退出等事件,可能會導致IP地址泄漏。詳情請參見Issues 75665Issues 92614

  • Flannel低於v0.15.1.11-7e95fe23-aliyun版本時,如果發生節點重啟或突然關機的事件,可能會導致Pod直接銷毀,從而導致IP地址泄漏。詳情請參見Issues 332

解決方案

  • 針對低版本ACK導致的IP地址泄露,您可以升級叢集至1.20及以上版本。具體操作,請參見手動升級叢集

  • 針對低版本Fannel導致的IP地址泄露,您可以升級Flannel至v0.15.1.11-7e95fe23-aliyun及以上版本。操作如下:

    Flannel只要在v0.15.1.11-7e95fe23-aliyun及以上版本,ACK會在Flannel中將預設IP段分配資料庫遷移至臨時目錄 /var/run中,重啟時系統會自動清空,避免IP地址泄露。

    1. 升級Flannel組件至v0.15.1.11-7e95fe23-aliyun及以上版本。具體操作,請參見管理組件

    2. 執行以下命令,編輯kube-flannel-cfg檔案,然後在kube-flannel-cfg檔案中新增dataDiripam參數。

      kubectl -n kube-system edit cm kube-flannel-cfg

      kube-flannel-cfg檔案樣本如下。

      # 修改前
          {
            "name": "cb0",
            "cniVersion":"0.3.1",
            "plugins": [
              {
                "type": "flannel",
                "delegate": {
                  "isDefaultGateway": true,
                  "hairpinMode": true
                 },
              },
              # portmap # 低版本可能沒有,如不使用請忽略。
              {
                "type": "portmap",
                "capabilities": {
                  "portMappings": true
                },
                "externalSetMarkChain": "KUBE-MARK-MASQ"
              }
            ]
          }
      
      # 修改後
          {
            "name": "cb0",
            "cniVersion":"0.3.1",
            "plugins": [
              {
                "type": "flannel",
                "delegate": {
                  "isDefaultGateway": true,
                  "hairpinMode": true
                 },
                # 注意逗號。
                "dataDir": "/var/run/cni/flannel",
                "ipam": {
                  "type": "host-local",
                  "dataDir": "/var/run/cni/networks"
                 }
              },
              {
                "type": "portmap",
                "capabilities": {
                  "portMappings": true
                },
                "externalSetMarkChain": "KUBE-MARK-MASQ"
              }
            ]
          }
    3. 執行以下命令,重啟Flannel Pod。

      重啟Flannel Pod不會影響運行中的業務。

      kubectl -n kube-system delete pod -l app=flannel
    4. 刪除節點上的IP目錄,重啟節點。

      1. 排空節點上的已有Pod。具體操作,請參見設定節點調度狀態

      2. 登入節點,執行以下命令,刪除IP目錄。

        rm -rf /etc/cni/
        rm -rf /var/lib/cni/
      3. 重啟節點。具體操作,請參見重啟執行個體

      4. 重複執行以上步驟,刪除所有節點上的IP目錄。

    5. 在節點上執行以下命令,驗證節點是否啟用臨時目錄。

      if [ -d /var/lib/cni/networks/cb0 ]; then echo "not using tmpfs"; fi
      if [ -d /var/run/cni/networks/cb0 ]; then echo "using tmpfs"; fi
      cat /etc/cni/net.d/10-flannel.conf*

      返回using tmpfs,說明當前節點已經啟用臨時目錄/var/run作為IP段分配資料庫,變更成功。

  • 如果短時間內無法升級ACK或Flannel,您可以按照以下方法臨時緊急處理。臨時緊急處理適用於以上兩種原因導致的泄漏。

    臨時緊急處理操作只是協助您清理泄露的IP地址,IP地址泄露的情況仍然有可能發生,因此您還是需要升級Flannel或叢集的版本。

    說明
    • 以下命令不適用於v0.15.1.11-7e95fe23-aliyun及以上版本的Flannel,並且已經切換使用/var/run儲存IP地址分配資訊的節點。

    • 以下指令碼僅供參考,如果節點曾有過自訂修改,指令碼可能無法正常工作。

    1. 將問題節點設定為不可調度狀態。具體操作,請參見設定節點調度狀態

    2. 使用以下指令碼,按照運行時引擎清理節點。

      • 如果您使用的是Docker運行時,請使用以下指令碼清理節點。

        #!/bin/bash
        cd /var/lib/cni/networks/cb0;
        docker ps -q > /tmp/running_container_ids
        find /var/lib/cni/networks/cb0 -regex ".*/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" -printf '%f\n' > /tmp/allocated_ips
        for ip in $(cat /tmp/allocated_ips); do
          cid=$(head -1 $ip | sed 's/\r#g' | cut -c-12)
          grep $cid /tmp/running_container_ids > /dev/null || (echo removing leaked ip $ip && rm $ip)
        done
      • 如果您使用的是Containerd運行時,請使用以下指令碼清理節點。

        #!/bin/bash
        # install jq
        yum install -y jq
        
        # export all running pod's configs
        crictl -r /run/containerd/containerd.sock pods -s ready -q | xargs -n1 crictl -r /run/containerd/containerd.sock inspectp > /tmp/flannel_ip_gc_all_pods
        
        # export and sort pod ip
        cat /tmp/flannel_ip_gc_all_pods | jq -r '.info.cniResult.Interfaces.eth0.IPConfigs[0].IP' | sort > /tmp/flannel_ip_gc_all_pods_ips
        
        # export flannel's all allocated pod ip
        ls -alh /var/lib/cni/networks/cb0/1* | cut -f7 -d"/" | sort > /tmp/flannel_ip_gc_all_allocated_pod_ips
        
        # print leaked pod ip
        comm -13 /tmp/flannel_ip_gc_all_pods_ips /tmp/flannel_ip_gc_all_allocated_pod_ips > /tmp/flannel_ip_gc_leaked_pod_ip
        
        # clean leaked pod ip
        echo "Found $(cat /tmp/flannel_ip_gc_leaked_pod_ip | wc -l) leaked Pod IP, press <Enter> to clean."
        read sure
        
        # delete leaked pod ip
        for pod_ip in $(cat /tmp/flannel_ip_gc_leaked_pod_ip); do
            rm /var/lib/cni/networks/cb0/${pod_ip}
        done
        
        echo "Leaked Pod IP cleaned, removing temp file."
        rm /tmp/flannel_ip_gc_all_pods_ips /tmp/flannel_ip_gc_all_pods /tmp/flannel_ip_gc_leaked_pod_ip /tmp/flannel_ip_gc_all_allocated_pod_ips
    3. 將問題節點設定為可調度狀態。具體操作,請參見設定節點調度狀態

如何修改節點IP數量、Pod IP網段、Service IP網段?

節點IP數量、Pod IP網段、Service IP網段在叢集建立後一律不支援修改,請在建立叢集時合理規劃您的網段。

什麼情境下需要為叢集配置多個路由表?

在Flannel網路模式下,以下是需要為cloud-controller-manager配置多路由表的常見情境。關於如何為叢集配置多路由表,請參見使用VPC的多路由表功能

問題情境

  • 情境一:

    系統診斷中提示“節點Pod網段不在VPC路由表條目中,請參考添加自訂路由條目到自訂路由表添加Pod網段的下一跳路由到當前節點”。

    原因:叢集中建立自訂路由表時,需要給CCM配置支援多路由表功能。

  • 情境二:

    cloud-controller-manager組件報錯,提示網路異常multiple route tables found

    原因:叢集中存在多個路由表時,需要給CCM配置支援多路由表功能。

  • 情境三:

    Flannel網路模式下,新增的叢集節點上有NodeNetworkUnavailable汙點,而cloud-controller-manager組件沒有及時刪除該節點汙點,導致Pod無法調度。詳情請參見為什麼叢集節點有NodeNetworkUnavailable汙點?

是否支援安裝和配置第三方網路外掛程式?

ACK叢集不支援安裝和配置第三方網路外掛程式,如果安裝了可能會導致叢集網路不可用。

為什麼會報no IP addresses available in range set

可能您的ACK叢集使用的是早期版本的Terway網路外掛程式或者Flannel網路外掛程式,這兩種情況定義了Pod網路CIDR,即為每個節點提供一組有限的IP地址用於分配給Pod。一旦這個範圍內的IP地址都被用完,新的Pod就不能被建立在這個節點上,除非釋放一些IP地址或對叢集的網路進行重構或擴充。Terway網路模式下您可能需要考慮升級Terway到最新版本以解決該問題。

Terway網路模式支援的Pod數量是多少?

Terway網路模式的叢集支援的Pod數量是ECS支援的IP數量。詳細資料,請參見使用Terway網路外掛程式

Terway DataPath V2資料面模式

  • 從Terway v1.8.0版本起,建立叢集時選擇IPvlan選項將預設啟用DataPath V2模式。對於已經啟用 IPvlan功能的現有叢集,資料面維持原有的IPvlan方式。

  • DataPath V2是新一代的資料面路徑,與原有的IPvlan模式相比,DataPath V2模式具有更好的相容性。詳細資料,請參見使用Terway網路外掛程式

如何查看Terway網路Pod生命週期?

  1. 登入Container Service管理主控台,在左側導覽列選擇叢集

  2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇工作負載 > 守護進程集

  3. 守護進程集頁面頂部,單擊image選擇kube-system命名空間。

  4. 守護進程集頁面搜尋terway-eniip,單擊名稱列表下的terway-eniip

    以下為容器組現狀詳情的說明:

    類型

    說明

    Ready

    Pod內的所有容器都已經啟動並運行正常。

    Pending

    Pod正在等待Terway為其配置網路資源。

    Pod因節點資源不足未調度到節點上。詳細資料,請參見Pod狀態為Pending

    ContainerCreating

    Pod已調度至節點,表明Pod正在等待網路初始化完成。

    更多資訊,請參見Pod的生命週期

Terway組件升級失敗常見問題

問題現象

處理辦法

升級時提示錯誤碼eip pool is not supported

EIP功能在Terway組件中已不再支援,如需繼續使用此功能,請參見將EIP從Terway遷移至ack-extend-network-controller

Terway網路模式下,建立Pod提示找不到mac地址

問題現象

建立Pod失敗,提示mac地址找不到。

 failed to do add; error parse config, can't found dev by mac 00:16:3e:xx:xx:xx: not found

解決辦法

  1. 網卡在系統中載入是非同步,在CNI配置時,可能網卡還沒有載入成功。這種情況下CNI會自動重試,並不會有影響。請通過Pod最終狀態判斷是否成功。

  2. 如果Pod長時間沒有建立成功,並提示上述錯誤,通常是由於在彈性網卡掛載時,由於高階記憶體不足導致驅動載入失敗。您可以通過重啟執行個體解決。