掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢(xún)/運(yùn)營(yíng)咨詢(xún)/技術(shù)建議/互聯(lián)網(wǎng)交流
StatefulSet 是用來(lái)管理有狀態(tài)應(yīng)用的工作負(fù)載 API 對(duì)象。

廣陽(yáng)網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、APP開(kāi)發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)公司等網(wǎng)站項(xiàng)目制作,到程序開(kāi)發(fā),運(yùn)營(yíng)維護(hù)。成都創(chuàng)新互聯(lián)于2013年成立到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專(zhuān)注于網(wǎng)站建設(shè)就選成都創(chuàng)新互聯(lián)。
StatefulSet 用來(lái)管理某 Pod 集合的部署和擴(kuò)縮, 并為這些 Pod 提供持久存儲(chǔ)和持久標(biāo)識(shí)符。
和 Deployment 類(lèi)似, StatefulSet 管理基于相同容器規(guī)約的一組 Pod。但和 Deployment 不同的是, StatefulSet 為它們的每個(gè) Pod 維護(hù)了一個(gè)有粘性的 ID。這些 Pod 是基于相同的規(guī)約來(lái)創(chuàng)建的, 但是不能相互替換:無(wú)論怎么調(diào)度,每個(gè) Pod 都有一個(gè)永久不變的 ID。
如果希望使用存儲(chǔ)卷為工作負(fù)載提供持久存儲(chǔ),可以使用 StatefulSet 作為解決方案的一部分。 盡管 StatefulSet 中的單個(gè) Pod 仍可能出現(xiàn)故障, 但持久的 Pod 標(biāo)識(shí)符使得將現(xiàn)有卷與替換已失敗 Pod 的新 Pod 相匹配變得更加容易。
StatefulSets 對(duì)于需要滿(mǎn)足以下一個(gè)或多個(gè)需求的應(yīng)用程序很有價(jià)值:
在上面描述中,“穩(wěn)定的”意味著 Pod 調(diào)度或重調(diào)度的整個(gè)過(guò)程是有持久性的。 如果應(yīng)用程序不需要任何穩(wěn)定的標(biāo)識(shí)符或有序的部署、刪除或伸縮,則應(yīng)該使用 由一組無(wú)狀態(tài)的副本控制器提供的工作負(fù)載來(lái)部署應(yīng)用程序,比如 Deployment 或者 ReplicaSet 可能更適用于你的無(wú)狀態(tài)應(yīng)用部署需要。
storage class? 來(lái)提供,或者由管理員預(yù)先提供。OrderedReady?) 時(shí)使用 滾動(dòng)更新,可能進(jìn)入需要人工干預(yù) 才能修復(fù)的損壞狀態(tài)。下面的示例演示了 StatefulSet 的組件。
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx # has to match .spec.template.metadata.labels
serviceName: "nginx"
replicas: 3 # by default is 1
template:
metadata:
labels:
app: nginx # has to match .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: K8S.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "my-storage-class"
resources:
requests:
storage: 1Gi上述例子中:
nginx ?的 Headless Service 用來(lái)控制網(wǎng)絡(luò)域名。web ?的 StatefulSet 有一個(gè) Spec,它表明將在獨(dú)立的 3 個(gè) Pod 副本中啟動(dòng) nginx 容器。volumeClaimTemplates ?將通過(guò) PersistentVolumes 驅(qū)動(dòng)提供的 PersistentVolumes 來(lái)提供穩(wěn)定的存儲(chǔ)。StatefulSet 的命名需要遵循DNS 子域名規(guī)范。
你必須設(shè)置 StatefulSet 的 ?.spec.selector? 字段,使之匹配其在 ?.spec.template.metadata.labels? 中設(shè)置的標(biāo)簽。在 Kubernetes 1.8 版本之前, 被忽略 ?.spec.selector? 字段會(huì)獲得默認(rèn)設(shè)置值。 在 1.8 和以后的版本中,未指定匹配的 Pod 選擇器將在創(chuàng)建 StatefulSet 期間導(dǎo)致驗(yàn)證錯(cuò)誤。
StatefulSet Pod 具有唯一的標(biāo)識(shí),該標(biāo)識(shí)包括順序標(biāo)識(shí)、穩(wěn)定的網(wǎng)絡(luò)標(biāo)識(shí)和穩(wěn)定的存儲(chǔ)。 該標(biāo)識(shí)和 Pod 是綁定的,不管它被調(diào)度在哪個(gè)節(jié)點(diǎn)上。
對(duì)于具有 N 個(gè)副本的 StatefulSet,StatefulSet 中的每個(gè) Pod 將被分配一個(gè)整數(shù)序號(hào), 從 0 到 N-1,該序號(hào)在 StatefulSet 上是唯一的。
StatefulSet 中的每個(gè) Pod 根據(jù) StatefulSet 的名稱(chēng)和 Pod 的序號(hào)派生出它的主機(jī)名。 組合主機(jī)名的格式為?$(StatefulSet 名稱(chēng))-$(序號(hào))?。 上例將會(huì)創(chuàng)建三個(gè)名稱(chēng)分別為 ?web-0、web-1、web-2? 的 Pod。 StatefulSet 可以使用 無(wú)頭服務(wù) 控制它的 Pod 的網(wǎng)絡(luò)域。管理域的這個(gè)服務(wù)的格式為: ?$(服務(wù)名稱(chēng)).$(命名空間).svc.cluster.local?,其中 ?cluster.local? 是集群域。 一旦每個(gè) Pod 創(chuàng)建成功,就會(huì)得到一個(gè)匹配的 DNS 子域,格式為: ?$(pod 名稱(chēng)).$(所屬服務(wù)的 DNS 域名)?,其中所屬服務(wù)由 StatefulSet 的 ?serviceName ?域來(lái)設(shè)定。
取決于集群域內(nèi)部 DNS 的配置,有可能無(wú)法查詢(xún)一個(gè)剛剛啟動(dòng)的 Pod 的 DNS 命名。 當(dāng)集群內(nèi)其他客戶(hù)端在 Pod 創(chuàng)建完成前發(fā)出 Pod 主機(jī)名查詢(xún)時(shí),就會(huì)發(fā)生這種情況。 負(fù)緩存 (在 DNS 中較為常見(jiàn)) 意味著之前失敗的查詢(xún)結(jié)果會(huì)被記錄和重用至少若干秒鐘, 即使 Pod 已經(jīng)正常運(yùn)行了也是如此。
如果需要在 Pod 被創(chuàng)建之后及時(shí)發(fā)現(xiàn)它們,有以下選項(xiàng):
正如限制中所述,你需要負(fù)責(zé)創(chuàng)建無(wú)頭服務(wù) 以便為 Pod 提供網(wǎng)絡(luò)標(biāo)識(shí)。
下面給出一些選擇集群域、服務(wù)名、StatefulSet 名、及其怎樣影響 StatefulSet 的 Pod 上的 DNS 名稱(chēng)的示例:
| 集群域名 | 服務(wù)(名字空間/名字) | StatefulSet(名字空間/名字) | StatefulSet 域名 | Pod DNS | Pod 主機(jī)名 |
|---|---|---|---|---|---|
| cluster.local | default/nginx | default/web | nginx.default.svc.cluster.local | web-{0..N-1}.nginx.default.svc.cluster.local | web-{0..N-1} |
| cluster.local | foo/nginx | foo/web | nginx.foo.svc.cluster.local | web-{0..N-1}.nginx.foo.svc.cluster.local | web-{0..N-1} |
| kube.local | foo/nginx | foo/web | nginx.foo.svc.kube.local | web-{0..N-1}.nginx.foo.svc.kube.local | web-{0..N-1} |
集群域會(huì)被設(shè)置為 ?
cluster.local?,除非有其他配置。
對(duì)于 StatefulSet 中定義的每個(gè) VolumeClaimTemplate,每個(gè) Pod 接收到一個(gè) PersistentVolumeClaim。在上面的 nginx 示例中,每個(gè) Pod 將會(huì)得到基于 StorageClass ?my-storage-class? 提供的 1 Gib 的 PersistentVolume。 如果沒(méi)有聲明 StorageClass,就會(huì)使用默認(rèn)的 StorageClass。 當(dāng)一個(gè) Pod 被調(diào)度(重新調(diào)度)到節(jié)點(diǎn)上時(shí),它的 ?volumeMounts ?會(huì)掛載與其 PersistentVolumeClaims 相關(guān)聯(lián)的 PersistentVolume。 請(qǐng)注意,當(dāng) Pod 或者 StatefulSet 被刪除時(shí),與 PersistentVolumeClaims 相關(guān)聯(lián)的 PersistentVolume 并不會(huì)被刪除。要?jiǎng)h除它必須通過(guò)手動(dòng)方式來(lái)完成。
當(dāng) StatefulSet 控制器(Controller) 創(chuàng)建 Pod 時(shí), 它會(huì)添加一個(gè)標(biāo)簽 ?statefulset.kubernetes.io/pod-name?,該標(biāo)簽值設(shè)置為 Pod 名稱(chēng)。 這個(gè)標(biāo)簽允許你給 StatefulSet 中的特定 Pod 綁定一個(gè) Service。
0..N-1?。N-1..0?。StatefulSet 不應(yīng)將 ?pod.Spec.TerminationGracePeriodSeconds? 設(shè)置為 0。 這種做法是不安全的,要強(qiáng)烈阻止。
在上面的 nginx 示例被創(chuàng)建后,會(huì)按照 web-0、web-1、web-2 的順序部署三個(gè) Pod。 在 web-0 進(jìn)入 Running 和 Ready 狀態(tài)前不會(huì)部署 web-1。在 web-1 進(jìn)入 Running 和 Ready 狀態(tài)前不會(huì)部署 web-2。 如果 web-1 已經(jīng)處于 Running 和 Ready 狀態(tài),而 web-2 尚未部署,在此期間發(fā)生了 web-0 運(yùn)行失敗,那么 web-2 將不會(huì)被部署,要等到 web-0 部署完成并進(jìn)入 Running 和 Ready 狀態(tài)后,才會(huì)部署 web-2。
如果用戶(hù)想將示例中的 StatefulSet 收縮為 ?replicas=1?,首先被終止的是 web-2。 在 web-2 沒(méi)有被完全停止和刪除前,web-1 不會(huì)被終止。 當(dāng) web-2 已被終止和刪除、web-1 尚未被終止,如果在此期間發(fā)生 web-0 運(yùn)行失敗, 那么就不會(huì)終止 web-1,必須等到 web-0 進(jìn)入 Running 和 Ready 狀態(tài)后才會(huì)終止 web-1。
在 Kubernetes 1.7 及以后的版本中,StatefulSet 允許你放寬其排序保證, 同時(shí)通過(guò)它的 ?.spec.podManagementPolicy? 域保持其唯一性和身份保證。
?OrderedReady ?Pod 管理是 StatefulSet 的默認(rèn)設(shè)置。它實(shí)現(xiàn)了 上面描述的功能。
?Parallel ?Pod 管理讓 StatefulSet 控制器并行的啟動(dòng)或終止所有的 Pod, 啟動(dòng)或者終止其他 Pod 前,無(wú)需等待 Pod 進(jìn)入 Running 和 ready 或者完全停止?fàn)顟B(tài)。 這個(gè)選項(xiàng)只會(huì)影響伸縮操作的行為,更新則不會(huì)被影響。
StatefulSet 的 ?.spec.updateStrategy? 字段讓 你可以配置和禁用掉自動(dòng)滾動(dòng)更新 Pod 的容器、標(biāo)簽、資源請(qǐng)求或限制、以及注解。 有兩個(gè)允許的值:
.spec.updateStrategy.type? 設(shè)置為 ?OnDelete ?時(shí), 它的控制器將不會(huì)自動(dòng)更新 StatefulSet 中的 Pod。 用戶(hù)必須手動(dòng)刪除 Pod 以便讓控制器創(chuàng)建新的 Pod,以此來(lái)對(duì) StatefulSet 的 ?.spec.template? 的變動(dòng)作出反應(yīng)。RollingUpdate ?更新策略對(duì) StatefulSet 中的 Pod 執(zhí)行自動(dòng)的滾動(dòng)更新。這是默認(rèn)的更新策略。當(dāng) StatefulSet 的 ?.spec.updateStrategy.type? 被設(shè)置為 ?RollingUpdate ?時(shí), StatefulSet 控制器會(huì)刪除和重建 StatefulSet 中的每個(gè) Pod。 它將按照與 Pod 終止相同的順序(從最大序號(hào)到最小序號(hào))進(jìn)行,每次更新一個(gè) Pod。
Kubernetes 控制面會(huì)等到被更新的 Pod 進(jìn)入 Running 和 Ready 狀態(tài),然后再更新其前身。 如果你設(shè)置了 ?.spec.minReadySeconds?(查看最短就緒秒數(shù)),控制面在 Pod 就緒后會(huì)額外等待一定的時(shí)間再執(zhí)行下一步。
通過(guò)聲明 ?.spec.updateStrategy.rollingUpdate.partition? 的方式,?RollingUpdate ?更新策略可以實(shí)現(xiàn)分區(qū)。 如果聲明了一個(gè)分區(qū),當(dāng) StatefulSet 的 ?.spec.template? 被更新時(shí), 所有序號(hào)大于等于該分區(qū)序號(hào)的 Pod 都會(huì)被更新。 所有序號(hào)小于該分區(qū)序號(hào)的 Pod 都不會(huì)被更新,并且,即使他們被刪除也會(huì)依據(jù)之前的版本進(jìn)行重建。 如果 StatefulSet 的 ?.spec.updateStrategy.rollingUpdate.partition? 大于它的 ?.spec.replicas?,對(duì)它的 ?.spec.template? 的更新將不會(huì)傳遞到它的 Pod。 在大多數(shù)情況下,你不需要使用分區(qū),但如果你希望進(jìn)行階段更新、執(zhí)行金絲雀或執(zhí)行 分階段上線(xiàn),則這些分區(qū)會(huì)非常有用。
在默認(rèn) Pod 管理策略(?OrderedReady?) 下使用 滾動(dòng)更新 ,可能進(jìn)入需要人工干預(yù)才能修復(fù)的損壞狀態(tài)。
如果更新后 Pod 模板配置進(jìn)入無(wú)法運(yùn)行或就緒的狀態(tài)(例如,由于錯(cuò)誤的二進(jìn)制文件 或應(yīng)用程序級(jí)配置錯(cuò)誤),StatefulSet 將停止回滾并等待。
在這種狀態(tài)下,僅將 Pod 模板還原為正確的配置是不夠的。由于 已知問(wèn)題,StatefulSet 將繼續(xù)等待損壞狀態(tài)的 Pod 準(zhǔn)備就緒(永遠(yuǎn)不會(huì)發(fā)生),然后再?lài)L試將其恢復(fù)為正常工作配置。
恢復(fù)模板后,還必須刪除 StatefulSet 嘗試使用錯(cuò)誤的配置來(lái)運(yùn)行的 Pod。這樣, StatefulSet 才會(huì)開(kāi)始使用被還原的模板來(lái)重新創(chuàng)建 Pod。
FEATURE STATE: Kubernetes v1.22 [alpha]
?.spec.minReadySeconds? 是一個(gè)可選字段,用于指定新創(chuàng)建的 Pod 就緒(沒(méi)有任何容器崩潰)后被認(rèn)為可用的最小秒數(shù)。 默認(rèn)值是 0(Pod 就緒時(shí)就被認(rèn)為可用)。
請(qǐng)注意只有當(dāng)你啟用 ?StatefulSetMinReadySeconds ?特性門(mén)控時(shí),該字段才會(huì)生效。

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢(xún)/運(yùn)營(yíng)咨詢(xún)/技術(shù)建議/互聯(lián)網(wǎng)交流