StatefulSet是Kubernetes專為有狀態應用設計的控制器,核心功能包括:穩定的網絡標識(Pod名稱和DNS不變)、持久化存儲(PVC與PV綁定,數據不丟失)、有序部署/擴展/刪除(按序號依次執行)。適用于數據庫(MySQL、PostgreSQL)、消息隊列(Kafka、RabbitMQ)、分布式存儲(Ceph、GlusterFS)等需要狀態保持的場景。
yum -y install nfs-utils rpcbind
systemctl enable nfs rpcbind && systemctl start nfs rpcbind
/usr/local/kubernetes/redis/pv1
~/pv6
),并設置權限:echo "/usr/local/kubernetes/redis/pv1 *(rw,no_root_squash,sync)" >> /etc/exports
mkdir -p /usr/local/kubernetes/redis/pv{1..6}
chmod 777 /usr/local/kubernetes/redis/pv{1..6}
exportfs -a # 生效配置
```。
Headless Service(clusterIP: None
)是為StatefulSet提供穩定網絡標識的關鍵,它會為每個Pod生成可解析的DNS記錄(格式:<pod-name>.<service-name>.<namespace>.svc.cluster.local
)。
示例YAML(nginx-headless.yaml
):
apiVersion: v1
kind: Service
metadata:
name: nginx # Service名稱,需與StatefulSet的serviceName一致
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None # 關鍵:定義為Headless Service
selector:
app: nginx # 必須匹配StatefulSet模板的labels
創建命令:kubectl create -f nginx-headless.yaml
。
StatefulSet通過volumeClaimTemplates
自動為每個Pod創建PVC(持久化存儲),并通過serviceName
關聯Headless Service。
示例YAML(nginx-sts.yaml
):
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web # StatefulSet名稱,Pod名稱格式為<name>-<序號>(如web-0、web-1)
spec:
serviceName: "nginx" # 必須與Headless Service名稱一致
replicas: 3 # Pod副本數
selector:
matchLabels:
app: nginx # 必須匹配Pod模板的labels
template:
metadata:
labels:
app: nginx # 必須匹配serviceName的selector
spec:
terminationGracePeriodSeconds: 10 # Pod終止前的寬限期(秒)
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www # 卷名稱,需與volumeClaimTemplates中的metadata.name一致
mountPath: /usr/share/nginx/html # 容器內掛載路徑
volumeClaimTemplates: # 自動生成PVC的模板
- metadata:
name: www # PVC名稱,Pod中掛載的卷名稱
spec:
accessModes: ["ReadWriteOnce"] # 存儲訪問模式(單節點讀寫)
storageClassName: "managed-nfs-storage" # 存儲類(需提前創建)
resources:
requests:
storage: 100Mi # 存儲容量
創建命令:kubectl create -f nginx-sts.yaml
。
StatefulSet的Pod會按序號依次創建(從0開始),且每個Pod的STATUS
為Running
:
kubectl get pods -l app=nginx -owide
# 輸出示例:
# NAME READY STATUS RESTARTS AGE IP NODE
# web-0 1/1 Running 0 2m 10.244.1.61 node1
# web-1 1/1 Running 0 1m 10.244.2.80 node2
# web-2 1/1 Running 0 1m 10.244.3.91 node3
```。
### 2. 驗證網絡標識
每個Pod的DNS名稱遵循`<pod-name>.<service-name>.<namespace>.svc.cluster.local`格式,可通過`nslookup`解析:
```bash
# 在CentOS節點上執行(需安裝busybox工具):
kubectl run -i --tty --image busybox:dnsutils dns-test --restart=Never --rm /bin/sh
# 在容器內執行:
nslookup web-0.nginx
# 輸出示例:
# Server: 10.96.0.10
# Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
# Name: web-0.nginx
# Address 1: 10.244.1.61 web-0.nginx.default.svc.cluster.local
即使Pod重啟或重新調度,DNS名稱和主機名(web-0
)保持不變。
進入Pod并向掛載目錄寫入數據,刪除Pod后重新創建,數據仍存在:
# 向web-0寫入數據:
kubectl exec -it web-0 -- sh -c "echo 'web-0 data' > /usr/share/nginx/html/index.html"
# 查看web-0的數據:
kubectl exec -it web-0 -- cat /usr/share/nginx/html/index.html
# 輸出:web-0 data
# 刪除web-0:
kubectl delete pod web-0
# 等待web-0重新創建(NAME仍為web-0):
kubectl get pods -w
# 查看新web-0的數據:
kubectl exec -it web-0 -- cat /usr/share/nginx/html/index.html
# 輸出仍為:web-0 data(數據未丟失)
這是因為PVC與PV綁定,Pod重建后會重新掛載原PV。
若volumeClaimTemplates
未生成PVC,需檢查:
kubectl get storageclass
);volumeClaimTemplates
配置是否正確(如metadata.name
、spec.accessModes
)。若Pod無法調度,需檢查:
kubectl describe node <node-name>
);kubectl get storageclass
查看PROVISIONER
字段);systemctl status nfs
)。若Pod刪除后數據丟失,需檢查:
kubectl get pvc
);persistentVolumeReclaimPolicy
是否為Retain
(默認是Delete
,需修改為Retain
以保留數據)。通過以上步驟,可在CentOS環境下快速部署并使用StatefulSet管理有狀態應用,確保應用的穩定性和數據持久性。