全部產品
Search
文件中心

Container Service for Kubernetes:節點與節點池FAQ

更新時間:Oct 25, 2024

本文為您介紹節點與節點池常見問題。例如,如何更改節點的Pod數量,如何更換節點池的OS鏡像,如何解決節點相關timeout問題等。

如何更換節點池OS鏡像?

更換節點池OS鏡像的方法與升級節點池的方法一致,以下為詳細操作步驟。

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

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

  3. 在目標節點池所在行,單擊操作列的更多 > 升級

  4. 選中更換作業系統,選擇要替換的鏡像,然後單擊開始升級

    說明

    更換作業系統時,預設選中Kubelet升級通過替換節點系統硬碟的方式升級節點池。請根據實際情況,確認是否選中升級前為節點建立快照

是否支援關閉期望節點數功能?

不支援。

如果您想移除、釋放指定節點,請參見移除節點。如果您想添加指定節點,請參見添加已有節點移除節點添加已有節點後,期望節點數自動適配為調整後的節點數,無需人為修改。

開啟期望節點數與未開啟期望節點數的節點池有什麼不同?

期望節點數是指節點池應該維持的節點數量。您可以通過調整期望節點數,達到擴容或縮容節點池的目的。但部分老節點池沒有設定到期望節點數,從而未開啟期望節點數功能。

開啟或未開啟期望節點數的節點池對於移除節點、釋放ECS等不同的操作方式,會有不同感知,具體如下表。

操作

開啟期望節點數節點池

未開啟期望節點數節點池

建議

通過ACK的OpenAPI或者控制台縮小期望節點數進行縮容。

縮小期望節點數後,將縮容節點池內節點,直到滿足指定的期望節點數量。

如果節點池內當前節點數大於期望節點數,將縮容節點,直到滿足終態期望節點數量,並將開啟期望節點數功能。

無。

通過ACK的OpenAPI或者控制台移除指定節點。

移除指定節點,期望節點數減少移除節點的數目。例如節點池移除指定節點前,期望節點數為10。移除3個節點後,期望節點數更新為7。

移除指定節點。

無。

通過kubectl delete node方式移除節點。

期望節點數不會改變,沒有變化。

無變化。

不推薦。

手動通過ECS控制台或者OpenAPI釋放ECS。

產生新ECS執行個體,補充到設定的期望節點數中。

節點池不感知。不會有新ECS執行個體產生。節點池節點列表被刪除的節點會顯示狀態為“未知”一段時間。

不推薦,會導致ACK、ESS資料與實際情況不一致,請使用推薦方式移除節點。具體操作,請參見移除節點

訂用帳戶ECS執行個體到期。

產生新的ECS執行個體,補充到設定的期望節點數。

節點池不感知。不會有新ECS執行個體產生。節點池節點列表中被刪除的節點會顯示狀態為“未知”一段時間。

不推薦,會導致ACK、ESS資料與實際情況不一致,請使用推薦方式移除節點。具體操作,請參見移除節點

ESS伸縮組手動開啟“執行個體的健全狀態檢查”,並且ECS執行個體無法通過ESS健全狀態檢查(如停機)。

產生新ECS執行個體,補充到設定的期望節點數。

產生新ECS執行個體,替換停機執行個體。

不推薦,請不要直接動作節點池相關的伸縮組。

通過ESS將ECS執行個體從伸縮組中移除,並且不修改期望執行個體數。

產生新ECS執行個體,補充到設定的期望節點數。

不會產生新的ECS執行個體。

不推薦,請不要直接動作節點池相關的伸縮組。

如何將游離節點(沒有節點池納管的節點)添加到節點池?

ACK節點池功能推出前建立的老叢集中,可能存在未被節點池管理的游離Worker節點。如不再需要這些節點,您可以直接釋放對應的ECS執行個體。如仍需要保留這些節點,推薦您將這些節點納入節點池進行管理,實現節點的分組管理和營運。

您可以建立並擴容一個節點池,將游離節點移除後添加到節點池中。具體操作,請參見遷移游離節點至節點池

如何在節點池中選用搶佔性執行個體?

可以通過建立節點池或者spot-instance-advisor命令列的方式使用搶佔性執行個體。詳細資料請參見搶佔式執行個體節點池最佳實務

說明

不支援在建立叢集的節點池配置中選擇搶佔性執行個體。

Pod數量達到上限時,如何調整可使用的節點Pod數量?

單Worker節點支援的最大Pod數受網路外掛程式類型影響,在大部分情境下不支援變更。在Terway模式下,單節點支援的最大Pod數依賴於ECS執行個體所提供的彈性網卡數量;在Flannel模式下,單節點最大Pod數在建立叢集時指定。指定後不支援修改。Pod數量達到上限時,推薦您通過擴容節點池增加節點,提升可使用的Pod數量。

更多資訊,請參見調整可使用的節點Pod數量

如何更改節點配置?

為了業務的平穩運行及方便節點管理:

  • 部分節點配置項,在節點池建立完成後不支援修改,例如容器運行時、節點所屬的專用網路等。

  • 部分節點配置項,在節點池建立完成後修改是受限的,例如,作業系統僅允許修改為同類型鏡像的最新版本,不支援更改鏡像類型。

  • 部分節點配置項,在節點池建立完成後支援修改。例如虛擬交換器、付費類型、執行個體規格等。

另外,部分支援修改的配置項,僅對節點池新增節點生效,對節點池已有節點無效。例如公網IP、CloudMonitor外掛程式等。關於節點配置項是否支援修改以及對節點的生效資訊,請參見編輯節點池

綜上,如果您想運行一個新配置的節點,建議您按照新配置建立節點池,將舊節點池中的節點設定為不可調度,然後對其進行排水操作。將業務運行到新節點以後,釋放舊的節點即可。

如何釋放指定的ECS執行個體?

請通過移除節點,釋放指定的ECS執行個體。釋放ECS執行個體後,期望節點數自動適配到釋放後的節點數量,無需人為修改。另外,修改期望節點數並不能釋放指定的ECS執行個體。

對於不屬於任何節點池的Worker節點,如何升級它的容器運行時?

按照如下步驟進行操作:

  1. 移除節點。移除Worker節點的過程中,系統會將節點置為不可調度,並對節點進行排水。如果排水失敗,系統將停止移除節點,如果成功,則將節點繼續移出叢集。

  2. 添加已有節點。可以將目標節點加入已有節點池,也可以建立0節點的節點池,然後將目標節點添加到節點池中。節點添加完成後,已有節點的容器運行時自動變成與節點池相同的容器運行時。

    說明

    節點池本身不收費,但節點池使用的ECS執行個體等雲資源由對應的雲產品計費。詳細資料,請參見雲產品資源計費

添加已有節點後報錯,提示timeout,怎麼辦?

請排查節點與APIServer CLB的網路是否可以連通,請先排查安全性群組是否符合要求。添加已有節點時安全性群組的使用限制,請參見安全性群組限制。關於網路不通的其他問題,請參見網路管理FAQ

如何更改ACK叢集中Worker節點的主機名稱?

叢集建立完成後,不支援自訂Worker節點的主機名稱,但是您可以通過節點池的節點命名規則來修改Worker節點的主機名稱。

說明

建立叢集時,您可以在自訂節點名稱參數中定義Worker節點的主機名稱。具體操作,請參見建立ACK託管叢集

  1. 移除節點。

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

    2. 在叢集管理頁左側導覽列,選擇節點管理 > 節點

    3. 節點頁面單擊目標節點右側操作列下的更多 > 移除

    4. 在彈出的對話方塊中選中我已瞭解上述說明,確認移除節點,然後單擊確定

  2. 將移除的節點再添加到節點池。具體操作,請參見手動添加節點

    添加的節點將根據節點池的節點命名規則進行命名。

如何在已有叢集的GPU節點上手動升級Kernel?

下面為您介紹如何在已有叢集的GPU節點上手動升級Kernel。

說明

當前kernel版本低於3.10.0-957.21.3

請確認需要升級的目標kernel版本,並謹慎操作。

本文提供方案並不涉及kernel升級,僅針對在kernel升級的前提下對應的Nvidia驅動升級。

  1. 擷取叢集KubeConfig並通過kubectl工具串連叢集

  2. 將GPU節點設定為不可調度(本例以節點 cn-beijing.i-2ze19qyi8votgjz12345為例)。

    kubectl cordon cn-beijing.i-2ze19qyi8votgjz12345
    
    node/cn-beijing.i-2ze19qyi8votgjz12345 already cordoned
  3. 將要升級驅動的GPU節點進行排水。

    kubectl drain cn-beijing.i-2ze19qyi8votgjz12345 --grace-period=120 --ignore-daemonsets=true
    
    node/cn-beijing.i-2ze19qyi8votgjz12345 cordoned
    WARNING: Ignoring DaemonSet-managed pods: flexvolume-9scb4, kube-flannel-ds-r2qmh, kube-proxy-worker-l62sf, logtail-ds-f9vbg
    pod/nginx-ingress-controller-78d847fb96-5fkkw evicted
  4. 卸載當前的nvidia-driver。

    說明

    本步驟中卸載的是版本為384.111的驅動包,如果您的驅動版本不是384.111,則需要在Nvidia官網下載對應的驅動安裝包,並將本步驟中的384.111替換成您實際的版本。

    1. 登入到該GPU節點,通過nvidia-smi查看驅動版本。

      sudo nvidia-smi -a | grep 'Driver Version'
      Driver Version                      : 384.111
    2. 下載Nvidia驅動安裝包。

      sudo cd /tmp/
      sudo curl -O https://cn.download.nvidia.cn/tesla/384.111/NVIDIA-Linux-x86_64-384.111.run
      說明

      需要在安裝包中卸載Nvidia。

    3. 卸載當前Nvidia驅動。

      sudo chmod u+x NVIDIA-Linux-x86_64-384.111.run
      sudo sh ./NVIDIA-Linux-x86_64-384.111.run --uninstall -a -s -q
  5. 升級Kernel。

    您可以根據需要升級Kernel。

  6. 重啟GPU機器。

    sudo reboot
  7. 重新登入GPU節點,安裝對應的kernel devel。

    sudo yum install -y kernel-devel-$(uname -r)
  8. 請到Nvidia官網下載和安裝您需要的Nvidia驅動, 本文以410.79為例。

    sudo cd /tmp/
    sudo curl -O https://cn.download.nvidia.cn/tesla/410.79/NVIDIA-Linux-x86_64-410.79.run
    sudo chmod u+x NVIDIA-Linux-x86_64-410.79.run
    sudo sh ./NVIDIA-Linux-x86_64-410.79.run -a -s -q
    
    warm up GPU
    sudo nvidia-smi -pm 1 || true
    sudo nvidia-smi -acp 0 || true
    sudo nvidia-smi --auto-boost-default=0 || true
    sudo nvidia-smi --auto-boost-permission=0 || true
    sudo nvidia-modprobe -u -c=0 -m || true
  9. 查看 /etc/rc.d/rc.local,確認其中是否包含以下配置,如果沒有請手動添加。

    sudo nvidia-smi -pm 1 || true
    sudo nvidia-smi -acp 0 || true
    sudo nvidia-smi --auto-boost-default=0 || true
    sudo nvidia-smi --auto-boost-permission=0 || true
    sudo nvidia-modprobe -u -c=0 -m || true
  10. 重啟kubelet和Docker。

    sudo service kubelet stop
    sudo service docker restart
    sudo service kubelet start
  11. 將此GPU節點重新設定為可調度。

    kubectl uncordon cn-beijing.i-2ze19qyi8votgjz12345
    
    node/cn-beijing.i-2ze19qyi8votgjz12345 already uncordoned
  12. 在GPU節點上的device plugin pod驗證版本。

    kubectl exec -n kube-system -t nvidia-device-plugin-cn-beijing.i-2ze19qyi8votgjz12345 nvidia-smi
    Thu Jan 17 00:33:27 2019
    +-----------------------------------------------------------------------------+
    | NVIDIA-SMI 410.79       Driver Version: 410.79       CUDA Version: N/A      |
    |-------------------------------+----------------------+----------------------+
    | GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
    | Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
    |===============================+======================+======================|
    |   0  Tesla P100-PCIE...  On   | 00000000:00:09.0 Off |                    0 |
    | N/A   27C    P0    28W / 250W |      0MiB / 16280MiB |      0%      Default |
    +-------------------------------+----------------------+----------------------+
    
    +-----------------------------------------------------------------------------+
    | Processes:                                                       GPU Memory |
    |  GPU       PID   Type   Process name                             Usage      |
    |=============================================================================|
    |  No running processes found                                                 |
    +-----------------------------------------------------------------------------+
    說明

    如果通過docker ps命令,發現GPU節點沒有容器被啟動,請參見修複GPU節點容器啟動問題

修複GPU節點容器啟動問題

在某些特定Kubernetes版本中的GPU節點上,重啟Kubelet和Docker時,發現沒有容器被啟動。

sudo service kubelet stop
Redirecting to /bin/systemctl stop kubelet.service
sudo service docker stop
Redirecting to /bin/systemctl stop docker.service
sudo service docker start
Redirecting to /bin/systemctl start docker.service
sudo service kubelet start
Redirecting to /bin/systemctl start kubelet.service

sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

執行以下命令,查看Docker的Cgroup Driver。

sudo docker info | grep -i cgroup
Cgroup Driver: cgroupfs

此時發現的Cgroup Driver類型是cgroupfs。

您可以按照以下操作,修複該問題。

  1. 備份/etc/docker/daemon.json,完成後,執行以下命令更新/etc/docker/daemon.json

    sudo cat >/etc/docker/daemon.json <<-EOF
    {
        "default-runtime": "nvidia",
        "runtimes": {
            "nvidia": {
                "path": "/usr/bin/nvidia-container-runtime",
                "runtimeArgs": []
            }
        },
        "exec-opts": ["native.cgroupdriver=systemd"],
        "log-driver": "json-file",
        "log-opts": {
            "max-size": "100m",
            "max-file": "10"
        },
        "oom-score-adjust": -1000,
        "storage-driver": "overlay2",
        "storage-opts":["overlay2.override_kernel_check=true"],
        "live-restore": true
    }
    EOF
  2. 執行以下命令,重啟Docker和Kubelet。

    sudo service kubelet stop
    Redirecting to /bin/systemctl stop kubelet.service
    sudo service docker restart
    Redirecting to /bin/systemctl restart docker.service
    sudo service kubelet start
    Redirecting to /bin/systemctl start kubelet.service
  3. 執行以下命令,確認Docker的Cgroup Driver的類型為systemd。

    sudo docker info | grep -i cgroup
    Cgroup Driver: systemd

節點故障時,如何將節點Pod批量轉移到其他節點上重新部署?

您可以將故障節點設定為不可調度並進行排水,將故障節點的應用Pod逐步遷移至新節點。

  1. 登入Container Service管理主控台,在節點頁面的操作列,選擇更多>節點排水。此操作會將舊節點設定為不可調度狀態,將舊節點池的應用逐步遷移至新節點池。

  2. 排查故障節點問題。關於故障排查的思路,請參見節點異常問題排查

    您也可以提交工單聯絡Container Service技術團隊。

有跨可用性區域節點的叢集發生故障時,叢集會如何決定節點驅逐策略?

通常情況下,當節點發生故障時,節點Controller會驅逐不健康的節點,驅逐速率--node-eviction-rate預設為0.1個/秒,即每10秒鐘內至多從一個節點驅逐Pod。

而一個存在多個可用性區域節點的ACK叢集發生故障時,節點Controller會根據可用性區域的狀態以及叢集大小來決定如何驅逐。

可用性區域故障分為三種情況。

  • FullDisruption:該可用性區域不存在正常節點,且至少有1個異常節點。

  • PartialDisruption:該可用性區域至少有2個異常節點,並且異常節點的比例,即(異常節點/(異常節點+正常節點)),大於0.55。

  • Normal:除FullDisruption和PartialDisruption兩種情況外,其餘均為Normal狀態。

在此情境下,叢集大小分為兩種情況:

  • 大叢集:大於50個節點的叢集。

  • 小叢集:小於等於50個節點的叢集。

在三種故障狀態下,節點Controller的驅逐速率計算方式如下:

  • 如果所有可用性區域都處於FullDisruption狀態時,則關閉系統所有可用性區域的驅逐功能。

  • 如果不是所有可用性區域都處於FullDisruption狀態,驅逐速率通過以下方式確定。

    • 如果某個可用性區域處於FullDisruption狀態,那麼驅逐速率設定為正常值(0.1),不受叢集大小影響。

    • 如果某個可用性區域處於PartialDisruption狀態,那麼驅逐速率受叢集大小因素影響。在大叢集中,該可用性區域的驅逐速率為0.01;在小叢集中,該可用性區域的驅逐速率為0,即不進行驅逐。

    • 如果某個可用性區域處於Normal狀態,那麼驅逐速率設定為正常值(0.1),不受叢集大小因素影響。

更多資訊,請參見逐出速率限制

ACK叢集中kubelet目錄路徑是什嗎?支援自訂嗎?

ACK不支援自定kubelet路徑。kubelet路徑預設為/var/lib/kubelet,請勿更改。

ACK節點池中資料盤可以自訂目錄掛載嗎?

自訂目錄掛載功能目前處於灰階發布中,請提交工單申請。開啟此功能後,可自動將節點池中添加的資料盤格式化並掛載到作業系統中的指定目錄上。但掛載目錄存在以下限制。

  • 請勿掛載到以下作業系統重要目錄上:

    • /

    • /etc

    • /var/run

    • /run

    • /boot

  • 請勿掛載到以下系統及容器運行時所使用的目錄及其子目錄:

    • /usr

    • /bin

    • /sbin

    • /lib

    • /lib64

    • /ostree

    • /sysroot

    • /proc

    • /sys

    • /dev

    • /var/lib/kubelet

    • /var/lib/docker

    • /var/lib/containerd

    • /var/lib/container

  • 不同資料盤的掛載目錄不可重複。

  • 掛載目錄必須是以/開頭的絕對路徑。

  • 掛載目錄中不能包含斷行符號和換行字元(C語言逸出字元\r\n),不能以反斜線字元\結尾。

如何修改最大檔案控制代碼數?

最大檔案控制代碼數即開啟檔案數的最大限制,Alibaba Cloud Linux和CentOS系統中包含兩個維度檔案控制代碼限制:

  • 系統層級:所有使用者的進程能夠同時開啟檔案數的上限。

  • 使用者層級:單個使用者進程能夠開啟檔案數的上限。

在容器環境中,還有另一個檔案控制代碼限制,即容器內部單進程的最大檔案控制代碼數。

說明

在節點池升級情境下,通過黑屏命令自訂修改的最大檔案控制代碼數配置可能會被覆蓋。推薦使用執行個體自訂資料進行配置。

修改節點系統級最大檔案控制代碼數

請參見自訂節點池OS參數瞭解操作的注意事項以及操作入口

修改節點單進程最大檔案控制代碼數

  1. 登入節點,查看/etc/security/limits.conf檔案。

    cat /etc/security/limits.conf

    通過以下參數配置節點單進程最大檔案控制代碼數:

    ...
    root soft nofile 65535
    root hard nofile 65535
    * soft nofile 65535
    * hard nofile 65535
  2. 執行sed命令,修改最大檔案控制代碼數(其中65535為最大檔案控制代碼數的建議取值)。

    sed -i "s/nofile.[0-9]*$/nofile 65535/g" /etc/security/limits.conf
  3. 重新登入節點,執行以下命令檢查修改是否生效。

    當返回與修改值一致時,表明修改正確。

    # ulimit -n
    65535

修改容器最大檔案控制代碼數

重要

修改容器最大檔案控制代碼數將會重啟Docker或containerd進程。請在業務低峰期謹慎操作。

  1. 登入節點,執行以下命令查看設定檔。

    • containerd節點:cat /etc/systemd/system/containerd.service

    • Docker節點:cat /etc/systemd/system/docker.service

    容器單進程最大檔案控制代碼數通過以下參數設定:

    ...
    LimitNOFILE=1048576   ******單進程最大檔案控制代碼數
    LimitNPROC=1048576    ******最大進程數
    ...
  2. 執行如下命令,修改對應參數取值(其中1048576為最大檔案控制代碼數的建議取值)。

    • containerd節點:

       sed -i "s/LimitNOFILE=[0-9a-Z]*$/LimitNOFILE=65536/g" /etc/systemd/system/containerd.service;sed -i "s/LimitNPROC=[0-9a-Z]*$/LimitNPROC=65537/g" /etc/systemd/system/containerd.service && systemctl daemon-reload && systemctl restart containerd
    • Docker節點:

      sed -i "s/LimitNOFILE=[0-9a-Z]*$/LimitNOFILE=1048576/g" /etc/systemd/system/docker.service;sed -i "s/LimitNPROC=[0-9a-Z]*$/LimitNPROC=1048576/g" /etc/systemd/system/docker.service && systemctl daemon-reload && systemctl restart docker
  3. 執行以下命令,查看容器單進程最大檔案控制代碼數。

    當返回與修改值一致時,表明修改正確。

    • containerd節點:

      # cat /proc/`pidof containerd`/limits | grep files
      Max open files            1048576              1048576              files
    • Docker節點:

      # cat /proc/`pidof dockerd`/limits | grep files
      Max open files            1048576              1048576              files