StatefulSet主要是用來管理需要穩定身分的Pod,這對於需要持久儲存資料、網路身分識別等需求的應用程式非常有用,待會會示範使用一個StatefulSet佈署SQL資料庫。
在開始之前先將下面的yaml檔案套用到Kubernetes
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- port: 3306
selector:
app: mysql
clusterIP: None
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
ports:
- containerPort: 3306
(注:這裡將資料庫密碼寫死只是為了方便演示,正式環境中是不建議這樣操作的)
在開始之前要先來介紹一下目前yaml檔案用到的Headless Services,之後會再介紹Services的所有類型。
Headless Service是一種不配置ClusterIP的Service,客戶端可以透過DNS取得後端Pod的IP,進而直接連線到Pod。Kubernetes不會為Headless Service建立虛擬IP,也不會像一般Service一樣進行負載均衡。
輸入kubectl get service
會看到mysql中的CLUSTER-IP為None這就是Headless Services。
輸入kubectl get pod來查看pod
你會發現這pod的命名規則好像和我們前面Deployment建立的pod不一樣。
這是因為前面提到的StatefulSet的目的是管理需要穩定身分的Pod,所以在命名上是按照順序進行命名的,像這裡mysql-0的0指的就是第一個Pod,如果將replicas:改成3則會有mysql-1、mysql-2出現。
(注:如果使用StatefulSet來建立多個資料庫,這些資料庫是不會互相同步資料的,這要另外做設定)
這裡我們將mysql-0刪除掉
我們再取得同一個名字的pod會發現StatefulSet重新建立了一個名稱相同的Pod。

這就是StatefulSet提供的穩定識別,即使Pod被刪除並重新建立,也會保留原本的名稱與序號。
而Deployment的命名與刪除後的反應則完全不同,Deployment所管理的Pod被刪除後,通常會重新建立一個不同名稱的Pod,且後綴名稱也不像StatefulSet一樣是有順序的。
| Deployment | StatefulSet | |
|---|---|---|
| pod名稱 | 不固定 | 固定且有序 |
| pod建立順序 | 不固定 | 有順序 |
| 儲存 | 可使用PVC | 可使用PVC,也可使用volumeClaimTemplates 為Pod建立個別PVC |
| 網路識別 | 主要使用Service | 可使用Headless Services提供個別Pod的DNS |
| 主要用途 | 無狀態應用部屬 例如:WEB | 有狀態應用部屬 例如:資料庫 |