iT邦幫忙

2021 iThome 鐵人賽

DAY 13
1
DevOps

k8s 入門學習 30天系列 第 13

IT 鐵人賽 k8s 入門30天 -- day13 Deploying Stateful Apps with StatefulSet

前言

今天主要會介紹 StatefulSet 以及比較其與 Deployment 的不同

StatefulSet

StatefulSet 是 k8s 叢集用來處理有狀態的應用佈署, 所謂 Stateful applications

舉例來說: 資料庫(MySql, mongoDB), ElasticSearch

這些應用都需要前面章節講到的 PersistentVolume 紀錄應用的狀態,當應用因為問題而重新啟動時, 需要透過儲存在 PersistentVolume 的資料來回復狀態

無狀態應用則不需要紀錄應用的狀態, 每個對應用發出的請求都與狀態無關

因為有狀態的應用與無狀態的應用有所不同, k8s 叢集也使用不同元件來做佈署

無狀態的應用佈署 k8s 叢集使用 Deployment 元件

用來複製佈署過無狀態的 Pod

有狀態的應用佈署 k8s 叢集使用 StatefulSet 元件

也可以用來複製佈署過的 Pod

StatefulSet vs Deployment

Deployment 所產生出來的 Pod, Pod Id 是隨機雜驟

當做 scale up 時, 每個 Pod 的 Pod Id 無順序性可以隨意掉換取代

StatefulSet 所產生出來的 Pod, Pod Id 具有一定順序性

當做了 scale up 時, 每個 Pod 的 Pod Id 具有一定順序性, 無法任意掉換順序

舉例來說:

假設有一個 mysql Pod 使用 StatefulSet 做 scale up

為了維持資料一致性

只會允許第一個 Pod 掛載的 Storage 可以做寫入

而第二個 Pod 掛載的 Storage 則慧跟第一個 Pod 的 Storage 做同步, 並且只能讀取

因為兩個 Pod Storage 可以同時寫入會造成資料不一致

除此之外, 每個 mysql Pod 讀取的 Storage 也不是相同的

假設另外有一個 my-app-java Pod 使用 Deployment 做 scale up 由於每個 Pod 都是相同且可以替換

所以只要用一個 Service 來做負載平衡然後掛載多個 my-app 的 Pod 在後面即可

Best Practice for StatefulSet

如前述, 因為 StatefulSet 會需要存儲應用狀態

因此最好的方式是設定 PersistentVolume 給 StatefulSet

讓 StatefulSet 可以把狀態相關則資訊存儲再 PersistentVolume 確保狀態不會因為 Pod 或 k8s 叢集不穩定而遺失狀態

而最好的 Storage 方式建議是使用 Remote Storage

因為 Local Storage 基本上會綁定在某一個結點, Pod 如果不是再同一個結點則無法存取的到

Pod Identity

參考自官網StatefulSet說明

對於 Deployment, Pod Identity 是採用 random hash

對於 StatefulSet, Pod Identity 則是有一組固定順序的名稱由以下模式組成

${statefulset name}-${ordinal}

ordinal 是由 0 開始遞增的數列

假設用建立名為 mysql 的 StatefulSet, replicas 設定為 3

則產生出來的 Pod 名稱則依序為 mysql-0, mysql-1, mysql-2

而第一個是 Master DB 可做讀寫, 其他則是 Slave DB 只能做讀取

重要的是, StatefulSet 的 replica 會依序建立 Pod

也就是當 mysql-0 還沒建立好, mysql-1 不會開始建立

相對的, 當刪除 Pod 時, 也是會從後面的序號往前刪除以維持資料狀態的正確性

StatefulSet 的 Pod endpoints

第1種, 當使用 Service 掛載 Pod 時使用 loadbalancer service

把所有 Pod 掛載到這個 loadbalancer service

Pod 的 endpoint 就是 loadbalancer service name

第2種, 當使用 Service 掛載 Pod 時使用個別掛載

每個 Pod 的 endpoint 就是以下這個模式

${Pod Name}.${governing Service domain}

重要特性

1 StatefulSet 的 Pod 名稱是可預測的

2 每個 Pod 的 DNS 名稱是固定的

每次當 Pod 重起

IP 會改變, 但是名稱跟 endpoints 不變

後記

當對於有狀態的應用做 Replicas 時

雖然 k8s 叢集有支援

但是仍然需要處理很多事情如下:

. 設定資料複製跟資料同步的機制
. 設定遠端存儲
. 建立管理備份機制


上一篇
IT 鐵人賽 k8s 入門30天 -- day12 Persisting Data in K8s with Volumes
下一篇
IT 鐵人賽 k8s 入門30天 -- day14 K8s Services explained
系列文
k8s 入門學習 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言