前言
前文
【從入門到放棄-Kubernetes】Kubernetes入門-無狀态應用擴縮容中,我們學習了如何通過yaml檔案部署一個無狀态應用,并對其進行擴縮容。
無狀态應用,在出現故障、或者pod删除時,相關資源都會釋放,如果我們想保留pod中的資源,或者部署如MySQL等的資料相關的有狀态應用時,删除資源顯然是不合理的。本文我們來學習有狀态應用的部署和擴縮容。
StatefulSet
StatefulSet和Deployment類似,都是用來管理基于相同容器定義的一組pod,差別是StatefulSet為每個pod維護了一個固定的ID,這些pod是基于相同的聲明建立的,但是缺不能互相替換,每個POD都有一個固定不變的ID辨別。
在 StatefulSet 對象 中定義你期望的狀态,然後 StatefulSet 的 控制器 就會通過各種更新來達到那種你想要的狀态。
StatefulSets 對于需要滿足以下一個或多個需求的應用程式很有價值:
- 穩定的、唯一的網絡辨別符。
- 穩定的、持久的存儲。
- 有序的、優雅的部署和縮放。
- 有序的、自動的滾動更新。
建立
# web.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: registry.cn-hangzhou.aliyuncs.com/larswang/nginx:1.0
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
imagePullSecrets:
- name: registry-secret-aliyun
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
kubectl apply -f web.yaml
鏡像權限問題
直接執行指令建立,可能會因為倉庫權限的原因,拉不下來鏡像。
可以通過下面的方式解決。
kubectl create secret docker-registry registry-secret-aliyun --docker-server=registry.cn-hangzhou.aliyuncs.com [email protected] --docker-password=xxxx
//換成你自己的阿裡雲鏡像倉庫賬号密碼。
kubectl describe secret registry-secret-aliyun
//檢視secret
在yaml檔案中,containers同級位置添加
imagePullSecrets:
- name: registry-secret-aliyun
順序啟動
再次運作建立指令,在另一個終端使用下面指令檢視運作情況。
//檢視statefulset
kubectl get statefulset web
//檢視pod
kubectl get pods -l app=nginx
每個pod 會加順序辨別,且按順序啟動的,web-0啟動完,web-1再啟動。
網絡辨別
每個 Pod 都擁有一個基于其順序索引的穩定的主機名。使用kubectl exec在每個 Pod 中執行hostname。
for i in 0 1; do kubectl exec web-$i -- sh -c 'hostname'; done
使用 kubectl run 運作一個提供 nslookup 指令的容器,該指令來自于 dnsutils 包。通過對 Pod 的主機名執行 nslookup,可以檢查他們在叢集内部的 DNS 位址。
kubectl run -i --tty --image busybox:1.28 dns-test --restart=Never --rm
PersistentVolumeClaims
PersistentVolumes是持久化卷,屬于叢集中的資源。PVC 是對這些資源的請求,也作為對資源的請求的檢查
這是有狀态應用在pod被删除後,能保留資料的主要原因。
檢視pod使用的pvc
kubectl get pvc -l app=nginx
NGINX web 伺服器預設會加載位于 /usr/share/nginx/html/index.html 的 index 檔案。StatefulSets spec 中的 volumeMounts 字段保證了 /usr/share/nginx/html 檔案夾由一個 PersistentVolume 支援。
寫入檔案
for i in 0 1; do kubectl exec web-$i -- sh -c 'echo $(hostname) > /usr/share/nginx/html/index.html'; done
檢視檔案
for i in 0 1; do kubectl exec -it web-$i -- cat /usr/share/nginx/html/index.html; done
删除pod
kubectl delete pod -l app=nginx
pod删除後,statefulset 會自動拉起
可以另起一個終端 觀察pod情況
再次檢視
for i in 0 1; do kubectl exec -it web-$i -- cat /usr/share/nginx/html/index.html; done
可以看到,pod被删除後,再次建立新的pod,之前寫入的檔案沒有丢失。
擴縮容
擴容
kubectl scale sts web --replicas=5
縮容
kubectl scale sts web --replicas=2
可以看到 擴容是按pod順序,從小到大 依次擴容。
縮容是按照pod順序,從大到小,依次縮容。
檢視pvc
縮容後檢視StatefulSet的pvc
發現pvc還依然保留 不會被删除。
清理現場
清理statefulset
kubectl delete statefulset web
清理service
kubectl delete service nginx
清理pvc
k delete pvc www-web-0
k delete pv pvc-d52ff063-937c-4246-864a-c6fab808e2ff
總結
本文我們學習了如何建立一個有狀态應用,主要使用了StatefulSet的pod順序索引和PersistentVolumeClaims的持久性存儲的特性。
畫重點:
- 每個pod都有一個順序辨別
- 啟動&擴容時,按辨別從小到大依次啟動
- 停止&縮容時,按辨別從大到小依次停止
- pod節點挂掉後,存儲資源不會被删除,新建立的同名pod可以繼續使用相關資源
本文中用到的yaml檔案見我的GitHub倉庫
AloofJr更多文章
見我的部落格:
https://nc2era.comwritten by
,轉載請注明出處