StatefulSet

StatefulSet 是爲了解決有狀態服務的問題(對應 Deployments 和 ReplicaSets 是爲無狀態服務而設計),其應用場景包括

  • 穩定的持久化存儲,即 Pod 重新調度後還是能訪問到相同的持久化數據,基於 PVC 來實現

  • 穩定的網絡標誌,即 Pod 重新調度後其 PodName 和 HostName 不變,基於 Headless Service(即沒有 Cluster IP 的 Service)來實現

  • 有序部署,有序擴展,即 Pod 是有順序的,在部署或者擴展的時候要依據定義的順序依次依序進行(即從 0 到 N-1,在下一個 Pod 運行之前所有之前的 Pod 必須都是 Running 和 Ready 狀態),基於 init containers 來實現

  • 有序收縮,有序刪除(即從 N-1 到 0)

從上面的應用場景可以發現,StatefulSet 由以下幾個部分組成:

  • 用於定義網絡標誌(DNS domain)的 Headless Service

  • 用於創建 PersistentVolumes 的 volumeClaimTemplates

  • 定義具體應用的 StatefulSet

StatefulSet 中每個 Pod 的 DNS 格式爲 statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local,其中

  • serviceName 爲 Headless Service 的名字

  • 0..N-1 爲 Pod 所在的序號,從 0 開始到 N-1

  • statefulSetName 爲 StatefulSet 的名字

  • namespace 爲服務所在的 namespace,Headless Service 和 StatefulSet 必須在相同的 namespace

  • .cluster.local 爲 Cluster Domain

API 版本對照表

Kubernetes 版本
Deployment 版本

v1.5-v1.6

extensions/v1beta1

v1.7-v1.15

apps/v1beta1

v1.8-v1.15

apps/v1beta2

v1.9+

apps/v1

簡單示例

以一個簡單的 nginx 服務 web.yaml 爲例:

還可以進行其他的操作

更新 StatefulSet

v1.7 + 支持 StatefulSet 的自動更新,通過 spec.updateStrategy 設置更新策略。目前支持兩種策略

  • OnDelete:當 .spec.template 更新時,並不立即刪除舊的 Pod,而是等待用戶手動刪除這些舊 Pod 後自動創建新 Pod。這是默認的更新策略,兼容 v1.6 版本的行爲

  • RollingUpdate:當 .spec.template 更新時,自動刪除舊的 Pod 並創建新 Pod 替換。在更新時,這些 Pod 是按逆序的方式進行,依次刪除、創建並等待 Pod 變成 Ready 狀態才進行下一個 Pod 的更新。

Partitions

RollingUpdate 還支持 Partitions,通過 .spec.updateStrategy.rollingUpdate.partition 來設置。當 partition 設置後,只有序號大於或等於 partition 的 Pod 會在 .spec.template 更新的時候滾動更新,而其餘的 Pod 則保持不變(即便是刪除後也是用以前的版本重新創建)。

Pod 管理策略

v1.7 + 可以通過 .spec.podManagementPolicy 設置 Pod 管理策略,支持兩種方式

  • OrderedReady:默認的策略,按照 Pod 的次序依次創建每個 Pod 並等待 Ready 之後才創建後面的 Pod

  • Parallel:並行創建或刪除 Pod(不等待前面的 Pod Ready 就開始創建所有的 Pod)

Parallel 示例

可以看到,所有 Pod 是並行創建的

zookeeper

另外一個更能說明 StatefulSet 強大功能的示例爲 zookeeper.yaml

詳細的使用說明見 zookeeper stateful application

StatefulSet 注意事項

  1. 推薦在 Kubernetes v1.9 或以後的版本中使用

  2. 所有 Pod 的 Volume 必須使用 PersistentVolume 或者是管理員事先創建好

  3. 爲了保證數據安全,刪除 StatefulSet 時不會刪除 Volume

  4. StatefulSet 需要一個 Headless Service 來定義 DNS domain,需要在 StatefulSet 之前創建好

Last updated