# K8s StatefulSet


# Introduction

StatefulSet 是在 K8s 建構 Stateful App 用的,StatefulSet 類似 Deployment,但 StatefulSet App 會在容器產生後,產生一組識別碼,
且不會因為 Pod reschedule 變動


# 使用情境

應用程式適合用 StatefulSet 的情況

  • 需要穩定 & 唯一的網路識別 (pod reschedule 後的 pod name & hostname 都不會變動)
  • 需要穩定的 persistent storage (pod reschedule 後還是能存取到相同的資料,基本上用 PVC 就可以解決)
  • 佈署 & scale out 的時後,每個 pod 的產生都是有其順序且逐一慢慢完成的
  • 進行更新操作時,也是與上面的需求相同

# 實作 StatefulSet

你必須要有

  • Application PVC
  • Headless Service
  • .spec.selector 所定義的內容 (matchLabels) 必須與 .spec.template.metadata.labels 相同

# 如何辨識 StateSet 裡面的 Pod

每一個 StatefulSet Pod 都有一個獨一無二的識別資訊,但這件事情在 k8s 中是如何被達成的?其實是分別由以下三種資訊所組成:

  • 表示順序的索引值 (Ordinal Index)
  • 穩定的網路識別資訊 (Stable Network ID)
  • 穩定的儲存空間 (Stable Storage)

Ordinal Index
若一個 statefulset 包含了 N 個 replica,那每一個 pod 都會被分配到一個獨一無二的索引,從 0 ~ N-1,即使 pod reschedule 也不會改變。

Stable Network ID
每個在 statefulset 中的 pod 都會有自己獨一無二的 hostname,命名的規則為 (statefulsetname)(statefulset name)-(ordinalindex)(ordinal index),因此在上面的例子中,3 個 pod 的 hostname 就會分別為 web-0、web-1、web-2。

此外,statefulset 還會透過 Headless Service 來維持 pod domain name 是固定指到 pod IP,並使用以下的標準格式存取 domain name:(以下稱為 governing service domain)

(servicename).(service name).(namespace).svc.cluster.local

其中 cluster.local 是當初安裝 k8s 所設定的 cluster domain,若安裝時有修改的話,上面的 domain name 也必須跟著調整。

因此存取每一個 pod 的完整 domain name 如下:

(podname).(podname).(governing service domain)