節(jié)點(diǎn)
Kubernetes 通過(guò)將容器放入在節(jié)點(diǎn)(Node)上運(yùn)行的 Pod 中來(lái)執(zhí)行你的工作負(fù)載荐操。 節(jié)點(diǎn)可以是一個(gè)虛擬機(jī)或者物理機(jī)器剩蟀,取決于所在的集群配置。每個(gè)節(jié)點(diǎn)都包含用于運(yùn)行 Pod 所需要的服務(wù),這些服務(wù)由 控制面 負(fù)責(zé)管理踢关。
通常集群中會(huì)有若干個(gè)節(jié)點(diǎn);而在一個(gè)學(xué)習(xí)用或者資源受限的環(huán)境中粘茄,你的集群中也可能 只有一個(gè)節(jié)點(diǎn)签舞。
節(jié)點(diǎn)上的組件包括 kubelet 秕脓、 容器運(yùn)行時(shí) 以及 kube-proxy 。
管理
向 API 服務(wù)器 添加節(jié)點(diǎn)的方式主要有兩種:
節(jié)點(diǎn)上的 kubelet 向控制面執(zhí)行自注冊(cè)儒搭;
你吠架,或者別的什么人,手動(dòng)添加一個(gè) Node 對(duì)象师妙。
在你創(chuàng)建了 Node 對(duì)象或者節(jié)點(diǎn)上的 kubelet 執(zhí)行了自注冊(cè)操作之后诵肛, 控制面會(huì)檢查新的 Node 對(duì)象是否合法。例如默穴,如果你使用下面的 JSON 對(duì)象來(lái)創(chuàng)建 Node 對(duì)象:
{
? "kind": "Node",
? "apiVersion": "v1",
? "metadata": {
? ? "name": "10.240.79.157",
? ? "labels": {
? ? ? "name": "my-first-k8s-node"
? ? }
? }
}
Kubernetes 會(huì)在內(nèi)部創(chuàng)建一個(gè) Node 對(duì)象作為節(jié)點(diǎn)的表示怔檩。Kubernetes 檢查 kubelet 向 API 服務(wù)器注冊(cè)節(jié)點(diǎn)時(shí)使用的 metadata.name 字段是否匹配。 如果節(jié)點(diǎn)是健康的(即所有必要的服務(wù)都在運(yùn)行中)蓄诽,則該節(jié)點(diǎn)可以用來(lái)運(yùn)行 Pod薛训。 否則,直到該節(jié)點(diǎn)變?yōu)榻】抵奥胤眨械募夯顒?dòng)都會(huì)忽略該節(jié)點(diǎn)乙埃。
說(shuō)明: Kubernetes 會(huì)一直保存著非法節(jié)點(diǎn)對(duì)應(yīng)的對(duì)象,并持續(xù)檢查該節(jié)點(diǎn)是否已經(jīng) 變得健康锯岖。 你介袜,或者某個(gè)控制器 必需顯式地 刪除該 Node 對(duì)象以停止健康檢查操作。
Node 對(duì)象的名稱必須是合法的 DNS 子域名出吹。
節(jié)點(diǎn)自注冊(cè)
當(dāng) kubelet 標(biāo)志 --register-node 為 true(默認(rèn))時(shí)遇伞,它會(huì)嘗試向 API 服務(wù)注冊(cè)自己。 這是首選模式捶牢,被絕大多數(shù)發(fā)行版選用鸠珠。
對(duì)于自注冊(cè)模式,kubelet 使用下列參數(shù)啟動(dòng):
--kubeconfig - 用于向 API 服務(wù)器表明身份的憑據(jù)路徑秋麸。
--cloud-provider - 與某云驅(qū)動(dòng) 進(jìn)行通信以讀取與自身相關(guān)的元數(shù)據(jù)的方式渐排。
--register-node - 自動(dòng)向 API 服務(wù)注冊(cè)。
--register-with-taints - 使用所給的污點(diǎn)列表(逗號(hào)分隔的 <key>=<value>:<effect>)注冊(cè)節(jié)點(diǎn)灸蟆。 當(dāng) register-node 為 false 時(shí)無(wú)效驯耻。
--node-ip - 節(jié)點(diǎn) IP 地址。
--node-labels - 在集群中注冊(cè)節(jié)點(diǎn)時(shí)要添加的 標(biāo)簽 炒考。 (參見(jiàn) NodeRestriction 準(zhǔn)入控制插件所實(shí)施的標(biāo)簽限制)吓歇。
--node-status-update-frequency - 指定 kubelet 向控制面發(fā)送狀態(tài)的頻率。
啟用節(jié)點(diǎn)授權(quán)模式和 NodeRestriction 準(zhǔn)入插件 時(shí)票腰,僅授權(quán) kubelet 創(chuàng)建或修改其自己的節(jié)點(diǎn)資源城看。
手動(dòng)節(jié)點(diǎn)管理
你可以使用 kubectl 來(lái)創(chuàng)建和修改 Node 對(duì)象。
如果你希望手動(dòng)創(chuàng)建節(jié)點(diǎn)對(duì)象時(shí)杏慰,請(qǐng)?jiān)O(shè)置 kubelet 標(biāo)志 --register-node=false测柠。
你可以修改 Node 對(duì)象(忽略 --register-node 設(shè)置)炼鞠。 例如,修改節(jié)點(diǎn)上的標(biāo)簽或標(biāo)記其為不可調(diào)度轰胁。
你可以結(jié)合使用節(jié)點(diǎn)上的標(biāo)簽和 Pod 上的選擇算符來(lái)控制調(diào)度谒主。 例如,你可以限制某 Pod 只能在符合要求的節(jié)點(diǎn)子集上運(yùn)行赃阀。
如果標(biāo)記節(jié)點(diǎn)為不可調(diào)度(unschedulable)霎肯,將阻止新 Pod 調(diào)度到該節(jié)點(diǎn)之上,但不會(huì) 影響任何已經(jīng)在其上的 Pod榛斯。 這是重啟節(jié)點(diǎn)或者執(zhí)行其他維護(hù)操作之前的一個(gè)有用的準(zhǔn)備步驟观游。
要標(biāo)記一個(gè)節(jié)點(diǎn)為不可調(diào)度,執(zhí)行以下命令:
kubectl cordon $NODENAME
說(shuō)明: 被 DaemonSet 控制器創(chuàng)建的 Pod 能夠容忍節(jié)點(diǎn)的不可調(diào)度屬性驮俗。 DaemonSet 通常提供節(jié)點(diǎn)本地的服務(wù)懂缕,即使節(jié)點(diǎn)上的負(fù)載應(yīng)用已經(jīng)被騰空,這些服務(wù)也仍需 運(yùn)行在節(jié)點(diǎn)之上王凑。
節(jié)點(diǎn)狀態(tài)
一個(gè)節(jié)點(diǎn)的狀態(tài)包含以下信息:
地址
狀況
容量與可分配
信息
你可以使用 kubectl 來(lái)查看節(jié)點(diǎn)狀態(tài)和其他細(xì)節(jié)信息:
kubectl describe node <節(jié)點(diǎn)名稱>
下面對(duì)每個(gè)部分進(jìn)行詳細(xì)描述搪柑。
地址
這些字段的用法取決于你的云服務(wù)商或者物理機(jī)配置。
HostName:由節(jié)點(diǎn)的內(nèi)核設(shè)置索烹」つ耄可以通過(guò) kubelet 的 --hostname-override 參數(shù)覆蓋。
ExternalIP:通常是節(jié)點(diǎn)的可外部路由(從集群外可訪問(wèn))的 IP 地址百姓。
InternalIP:通常是節(jié)點(diǎn)的僅可在集群內(nèi)部路由的 IP 地址倚喂。
狀況
conditions 字段描述了所有 Running 節(jié)點(diǎn)的狀態(tài)。狀況的示例包括:
說(shuō)明: 如果使用命令行工具來(lái)打印已保護(hù)(Cordoned)節(jié)點(diǎn)的細(xì)節(jié)瓣戚,其中的 Condition 字段可能 包括 SchedulingDisabled。SchedulingDisabled 不是 Kubernetes API 中定義的 Condition焦读,被保護(hù)起來(lái)的節(jié)點(diǎn)在其規(guī)約中被標(biāo)記為不可調(diào)度(Unschedulable)子库。
節(jié)點(diǎn)條件使用 JSON 對(duì)象表示。例如矗晃,下面的響應(yīng)描述了一個(gè)健康的節(jié)點(diǎn)仑嗅。
"conditions": [
? {
? ? "type": "Ready",
? ? "status": "True",
? ? "reason": "KubeletReady",
? ? "message": "kubelet is posting ready status",
? ? "lastHeartbeatTime": "2019-06-05T18:38:35Z",
? ? "lastTransitionTime": "2019-06-05T11:41:27Z"
? }
]
如果 Ready 條件處于 Unknown 或者 False 狀態(tài)的時(shí)間超過(guò)了 pod-eviction-timeout 值, (一個(gè)傳遞給 kube-controller-manager 的參數(shù))张症, 節(jié)點(diǎn)上的所有 Pod 都會(huì)被節(jié)點(diǎn)控制器計(jì)劃刪除仓技。默認(rèn)的逐出超時(shí)時(shí)長(zhǎng)為 5 分鐘。 某些情況下俗他,當(dāng)節(jié)點(diǎn)不可達(dá)時(shí)脖捻,API 服務(wù)器不能和其上的 kubelet 通信。 刪除 Pod 的決定不能傳達(dá)給 kubelet兆衅,直到它重新建立和 API 服務(wù)器的連接為止地沮。 與此同時(shí)嗜浮,被計(jì)劃刪除的 Pod 可能會(huì)繼續(xù)在游離的節(jié)點(diǎn)上運(yùn)行。
節(jié)點(diǎn)控制器在確認(rèn) Pod 在集群中已經(jīng)停止運(yùn)行前摩疑,不會(huì)強(qiáng)制刪除它們危融。 你可以看到這些可能在無(wú)法訪問(wèn)的節(jié)點(diǎn)上運(yùn)行的 Pod 處于 Terminating 或者 Unknown 狀態(tài)。 如果 kubernetes 不能基于下層基礎(chǔ)設(shè)施推斷出某節(jié)點(diǎn)是否已經(jīng)永久離開(kāi)了集群雷袋, 集群管理員可能需要手動(dòng)刪除該節(jié)點(diǎn)對(duì)象吉殃。 從 Kubernetes 刪除節(jié)點(diǎn)對(duì)象將導(dǎo)致 API 服務(wù)器刪除節(jié)點(diǎn)上所有運(yùn)行的 Pod 對(duì)象并釋放它們的名字。
節(jié)點(diǎn)生命周期控制器會(huì)自動(dòng)創(chuàng)建代表狀況的 污點(diǎn)楷怒。 當(dāng)調(diào)度器將 Pod 指派給某節(jié)點(diǎn)時(shí)蛋勺,會(huì)考慮節(jié)點(diǎn)上的污點(diǎn)。 Pod 則可以通過(guò)容忍度(Toleration)表達(dá)所能容忍的污點(diǎn)率寡。
capacity 塊中的字段標(biāo)示節(jié)點(diǎn)擁有的資源總量迫卢。 allocatable 塊指示節(jié)點(diǎn)上可供普通 Pod 消耗的資源量。
可以在學(xué)習(xí)如何在節(jié)點(diǎn)上預(yù)留計(jì)算資源 的時(shí)候了解有關(guān)容量和可分配資源的更多信息冶共。
第二個(gè)是保持節(jié)點(diǎn)控制器內(nèi)的節(jié)點(diǎn)列表與云服務(wù)商所提供的可用機(jī)器列表同步乾蛤。 如果在云環(huán)境下運(yùn)行,只要某節(jié)點(diǎn)不健康捅僵,節(jié)點(diǎn)控制器就會(huì)詢問(wèn)云服務(wù)是否節(jié)點(diǎn)的虛擬機(jī)仍可用家卖。 如果不可用,節(jié)點(diǎn)控制器會(huì)將該節(jié)點(diǎn)從它的節(jié)點(diǎn)列表刪除庙楚。
第三個(gè)是監(jiān)控節(jié)點(diǎn)的健康情況上荡。節(jié)點(diǎn)控制器負(fù)責(zé)在節(jié)點(diǎn)不可達(dá) (即,節(jié)點(diǎn)控制器因?yàn)槟承┰驔](méi)有收到心跳馒闷,例如節(jié)點(diǎn)宕機(jī))時(shí)酪捡, 將節(jié)點(diǎn)狀態(tài)的 NodeReady 狀況更新為 "Unknown"。 如果節(jié)點(diǎn)接下來(lái)持續(xù)處于不可達(dá)狀態(tài)纳账,節(jié)點(diǎn)控制器將逐出節(jié)點(diǎn)上的所有 Pod(使用體面終止)逛薇。 默認(rèn)情況下 40 秒后開(kāi)始報(bào)告 "Unknown",在那之后 5 分鐘開(kāi)始逐出 Pod疏虫。 節(jié)點(diǎn)控制器每隔 --node-monitor-period 秒檢查每個(gè)節(jié)點(diǎn)的狀態(tài)永罚。
kubelet 負(fù)責(zé)創(chuàng)建和更新 NodeStatus 和 Lease 對(duì)象。
當(dāng)一個(gè)可用區(qū)域(Availability Zone)中的節(jié)點(diǎn)變?yōu)椴唤】禃r(shí)卧秘,節(jié)點(diǎn)的驅(qū)逐行為將發(fā)生改變呢袱。 節(jié)點(diǎn)控制器會(huì)同時(shí)檢查可用區(qū)域中不健康(NodeReady 狀況為 Unknown 或 False) 的節(jié)點(diǎn)的百分比。如果不健康節(jié)點(diǎn)的比例超過(guò) --unhealthy-zone-threshold (默認(rèn)為 0.55)翅敌, 驅(qū)逐速率將會(huì)降低:如果集群較行吒!(意即小于等于 --large-cluster-size-threshold 個(gè)節(jié)點(diǎn) - 默認(rèn)為 50),驅(qū)逐操作將會(huì)停止蚯涮,否則驅(qū)逐速率將降為每秒 --secondary-node-eviction-rate 個(gè)(默認(rèn)為 0.01)坯临。 在單個(gè)可用區(qū)域?qū)嵤┻@些策略的原因是當(dāng)一個(gè)可用區(qū)域可能從控制面脫離時(shí)其它可用區(qū)域 可能仍然保持連接焊唬。 如果你的集群沒(méi)有跨越云服務(wù)商的多個(gè)可用區(qū)域,那(整個(gè)集群)就只有一個(gè)可用區(qū)域看靠。
跨多個(gè)可用區(qū)域部署你的節(jié)點(diǎn)的一個(gè)關(guān)鍵原因是當(dāng)某個(gè)可用區(qū)域整體出現(xiàn)故障時(shí)赶促, 工作負(fù)載可以轉(zhuǎn)移到健康的可用區(qū)域。 因此挟炬,如果一個(gè)可用區(qū)域中的所有節(jié)點(diǎn)都不健康時(shí)鸥滨,節(jié)點(diǎn)控制器會(huì)以正常的速率 --node-eviction-rate 進(jìn)行驅(qū)逐操作。 在所有的可用區(qū)域都不健康(也即集群中沒(méi)有健康節(jié)點(diǎn))的極端情況下谤祖, 節(jié)點(diǎn)控制器將假設(shè)控制面節(jié)點(diǎn)的連接出了某些問(wèn)題婿滓, 它將停止所有驅(qū)逐動(dòng)作直到一些連接恢復(fù)。
節(jié)點(diǎn)控制器還負(fù)責(zé)驅(qū)逐運(yùn)行在擁有 NoExecute 污點(diǎn)的節(jié)點(diǎn)上的 Pod粥喜, 除非這些 Pod 能夠容忍此污點(diǎn)凸主。 節(jié)點(diǎn)控制器還負(fù)責(zé)根據(jù)節(jié)點(diǎn)故障(例如節(jié)點(diǎn)不可訪問(wèn)或沒(méi)有就緒)為其添加 污點(diǎn) 。 這意味著調(diào)度器不會(huì)將 Pod 調(diào)度到不健康的節(jié)點(diǎn)上额湘。
注意: kubectl cordon 會(huì)將節(jié)點(diǎn)標(biāo)記為“不可調(diào)度(Unschedulable)”卿吐。 此操作的副作用是,服務(wù)控制器會(huì)將該節(jié)點(diǎn)從負(fù)載均衡器中之前的目標(biāo)節(jié)點(diǎn)列表中移除锋华, 從而使得來(lái)自負(fù)載均衡器的網(wǎng)絡(luò)請(qǐng)求不會(huì)到達(dá)被保護(hù)起來(lái)的節(jié)點(diǎn)嗡官。
Kubernetes 調(diào)度器 保證節(jié)點(diǎn)上 有足夠的資源供其上的所有 Pod 使用。它會(huì)檢查節(jié)點(diǎn)上所有容器的請(qǐng)求的總和不會(huì)超過(guò)節(jié)點(diǎn)的容量毯焕。 總的請(qǐng)求包括由 kubelet 啟動(dòng)的所有容器衍腥,但不包括由容器運(yùn)行時(shí)直接啟動(dòng)的容器, 也不包括不受 kubelet 控制的其他進(jìn)程纳猫。
說(shuō)明: 如果要為非 Pod 進(jìn)程顯式保留資源婆咸。請(qǐng)參考 為系統(tǒng)守護(hù)進(jìn)程預(yù)留資源。
節(jié)點(diǎn)拓?fù)?/p>
FEATURE STATE: Kubernetes v1.16 [alpha]
如果啟用了 TopologyManager 特性門控芜辕, kubelet 可以在作出資源分配決策時(shí)使用拓?fù)涮崾尽?參考控制節(jié)點(diǎn)上拓?fù)涔芾聿呗?了解詳細(xì)信息尚骄。