K8S 節點不可用時快速遷移 Pods
當節點宕機或者節點網絡異常時,我們希望該節點上的 Pod 能夠快速遷移到其他節點,並提供服務。但是測試發現節點 Down 掉以後,Pod 並不會立即遷移到其他節點。使用不同的 Kubernetes 版本測試,在默認配置下,需要等待將近 6 到 10 分鐘節點上的 Pod 纔會開始遷移。
這個現象與 Kubelet 的狀態更新機制密切相關,下面我們來分析下 Kubelet 狀態更新的基本流程。
-
kubelet
kubelet 自身會定期更新狀態到 apiserver,通過參數
--node-status-update-frequency
配置上報頻率,默認 10s 上報一次。 -
kube-controller-manager
-
kube-controller-manager 會定時去檢查 kubelet 的狀態,可通過
--node-monitor-period
自定義這個時間 ,默認是 5s。 -
當 node 失聯一段時間後,kubernetes 判定 node 爲
notready
狀態,這段時長可通過--node-monitor-grace-period
參數配置,默認 40s。 -
當 node 狀態爲
notready
一段時間後,kubernetes 判定 node 爲unhealthy
狀態,這段時長可通過--node-startup-grace-period
參數配置,默認 1m0s。 -
當 node 狀態爲
unhealthy
一段時間後,kubernetes 開始刪除原 node 上的 Pod,這段時長可通過--pod-eviction-timeout
參數配置,默認 5m0s。
-
kube-apiserver (Kubernetes v1.13 版本及以後版本)
Kubernetes v1.13 及以後版本默認開啓了 基於污點的驅逐,默認 300 秒。節點不同狀態時會自動添加不同的污點,因而 Pod 的驅逐時間將受到節點狀態的影響。
-
default-not-ready-toleration-seconds
: 表示notReady:NoExecute
容忍的時間。notReady:NoExecute
默認添加到所有 Pod(默認 300 秒)。 -
default-unreachable-toleration-seconds
: 表示unreachable:NoExecute
容忍的時間。unreachable:NoExecute
默認添加到所有 Pod(默認 300 秒)。
Kubernetes 小於 v1.13
在 Kubernetes 小於 v1.13 版本之前,默認沒有啓用基於污點的驅逐,因此 Pod 最終遷移的時間由 node-monitor-period
、node-monitor-grace-period
、node-startup-grace-period
、pod-eviction-timeout
幾個參數同時決定。
rke 配置示例
services:
kube-controller:
<其他參數已省略>
extra_args:
node-monitor-period: "5s" # (默認 5s)
node-monitor-grace-period: "40s" # Node Notready (默認 40s)
node-startup-grace-period: "1m0s" # Node Unhealthy (默認 1m0s)
pod-eviction-timeout: "5m0s" # 開始驅逐 Pod (默認 5m0s)
Kubernetes 大於等於 v1.13 小於 v1.18
基於污點的驅逐
-
在 kubernetes 1.13 之前,基於污點的驅逐(TaintBasedEvictions)處於 Alpha 階段,默認是禁用狀態(TaintBasedEvictions=false)。所以在 kubernetes 1.13 之前的版本中只需要配置 kube-controller 的參數即可控制節點不可用時 Pod 的遷移時間。
-
從 kubernetes 1.13 開始,基於污點的驅逐(TaintBasedEvictions)處於 Beta 階段,默認是被開啓狀態(TaintBasedEvictions=true)。當修改 kube-controller 參數後手動停止一個節點,發現 Pod 還是需要等很久才能被遷移。
-
在 基於污點的驅逐(TaintBasedEvictions)開啓的狀態下,
node-startup-grace-period
和pod-eviction-timeout
參數配置的時間不再生效。相應的我們可以在 Pod 的 yaml 配置文件中看到如下的參數:
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
- 因爲 kubernetes 節點控制器根據 kubelet 的不同狀態,將自動爲節點添加不同的 污點。當節點具有
node.kubernetes.io/not-ready
或者node.kubernetes.io/unreachable
污點時,將會等待tolerationSeconds
所配置的時長。tolerations
是由 API SERVER 控制生成,從 Kubernetes v1.13 開始可以通過以下參數來配置tolerationSeconds
時間值。
-
kube-apiserver (Kubernetes v1.13 版本及以後)
注意:
notReady
和unreachable
兩個污點匹配到一個就會觸發驅逐,notReady
的時間可以適當設置長一點。
-
default-not-ready-toleration-seconds
: 表示notReady:NoExecute
容忍的時間。notReady:NoExecute
默認添加到所有 Pod。默認 300 秒) -
default-unreachable-toleration-seconds
: 表示unreachable:NoExecute
容忍的時間。unreachable:NoExecute
默認添加到所有 Pod。(默認 300 秒)
節點污點
從 kubernetes 1.6 開始,kubernetes 的節點控制器根據 kubelet 的不同狀態,將自動爲節點添加不同的污點。
這類污點有:
-
node.kubernetes.io/not-ready
:節點未就緒。對應着 NodeConditionReady
爲False
的情況。 -
node.kubernetes.io/unreachable
:節點不可觸達。對應着 NodeConditionReady
爲Unknown
的情況。 -
node.kubernetes.io/out-of-disk
:節點磁盤空間已滿。 -
node.kubernetes.io/memory-pressure
:節點內存喫緊。 -
node.kubernetes.io/disk-pressure
:節點磁盤喫緊。 -
node.kubernetes.io/network-unavailable
:節點網絡不可用。 -
node.kubernetes.io/unschedulable
:節點不可調度。 -
node.cloudprovider.kubernetes.io/uninitialized
:如果 kubelet 是由 “外部” 雲服務商啓動的,該污點用來標識某個節點當前爲不可用的狀態。在 “雲控制器”(cloud-controller-manager)初始化這個節點以後,kubelet 將此污點移除。
rke 配置示例
在 Kubernetes 大於等於 v1.13 小於 v1.18 的版本中,基於污點的驅逐(TaintBasedEvictions)處於 Beta 階段,可選擇以下兩種方式來配置。
- 禁用 基於污點的驅逐
services:
kube-controller:
<其他參數已省略>
extra_args:
node-monitor-period: "5s" # (默認 5s)
node-monitor-grace-period: "40s" # Node Notready (默認 40s)
node-startup-grace-period: "1m0s" # Node Unhealthy (默認 1m0s)
pod-eviction-timeout: "5m0s" # 開始驅逐 Pod (默認 5m0s)
feature-gates: "TaintBasedEvictions=false" # 禁用 基於污點的驅逐
- 啓用 基於污點的驅逐
services:
kube-api:
<其他參數已省略>
extra_args:
default-not-ready-toleration-seconds: '60' # 默認 300 秒
default-unreachable-toleration-seconds: '30' # 默認 300 秒
kube-controller:
<其他參數已省略>
extra_args:
node-monitor-period: "5s" # (默認 5s)
node-monitor-grace-period: "40s" # Node Notready (默認 40s)
Kubernetes 大於等於 v1.18
在 Kubernetes 1.18 及以上版本中,TaintBasedEvictions
默認設置爲 true
並且不能修改。如果強制在 rke 配置中指定 TaintBasedEvictions=false
,如下配置:
services:
kube-controller:
extra_args:
feature-gates: "TaintBasedEvictions=false"
那麼 kube-controller-manager
將無法正常運行,日誌中會看到如下的錯誤提示:
Error: invalid argument "TaintBasedEvictions=false" for "--feature-gates" flag: cannot set feature gate TaintBasedEvictions to false, feature is locked to true
rke 配置示例
services:
kube-api:
<其他參數已省略>
extra_args:
default-not-ready-toleration-seconds: '60' # 默認 300 秒
default-unreachable-toleration-seconds: '30' # 默認 300 秒
kube-controller:
<其他參數已省略>
extra_args:
node-monitor-period: "5s"
node-monitor-grace-period: "30s" # Unavailable
轉自:IT 老男孩
xtplayer.cn/kubernetes/fast-migration-pod-when-node-unavailable/
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/bl43jkbGN9GavQy_WuqFsw