您好,登錄后才能下訂單哦!
1,什么是StatefulSet ?
StatefulSet又叫PetSet(之前的名稱),它和RS,RC,Deployment等一樣,都是pod控制器。
StatefulSet是為了解決有狀態服務的問題(對應于deoloyment和RS,RC,ReplicaSet都是為無狀態服務而設計的)。
什么是無狀態服務?
在生產環境中,pod的名稱是隨機的,擴縮容的是時候沒有規律,每一個pod都可以被新生成的pod代替。
2,StatefulSet的應用場景包括:
從上面的引用場景可以發現,statefulset由以下幾個部分組成:
1)headless Service:無頭服務。用來定義pod的網絡標識的(域名解析)。
2)statefulSet:定義具體的應用
3)volumeClaimTemplate:該模板自動為每一個pod創建pvc。
對比無狀態服務,總結StatefulSet特點:pod的名稱不變,每個副本啟停有順序,持久化存儲,每個pod中的數據不同,根據定義的模板自動創建pvc。
3,接下來通過例子來實踐statefulset資源的使用
部署nginx服務,通過storage class和statefulset實現有狀態服務的數據持久化及其他操作。
操作流程如下:
1)通過nfs服務部署storage class(創建pv)
2)創建statefulset資源對象(創建pvc)
3)測試數據持久化
4)replicas擴容與縮容
5)分區更新
1)通過nfs部署storage class
以下直接進行部署,具體信息及參數解釋請參考上章博文 k8s之StorageClass
#開啟nfs:
[root@master yaml]# yum -y install nfs-utils
[root@master yaml]# vim /etc/exports
/nfsdata *(rw,sync,no_root_squash)
[root@master yaml]# mkdir /nfsdata
[root@master yaml]# systemctl start rpcbind
[root@master yaml]# systemctl start nfs-server
[root@master yaml]# systemctl enable nfs-server
[root@master yaml]# showmount -e
Export list for master:
/nfsdata *
#創建rbac權限:
[root@master yaml]# vim rbac-rolebind.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-provisioner
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: nfs-provisioner-runner
namespace: default
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["services", "endpoints"]
verbs: ["get","create","list", "watch","update"]
- apiGroups: ["extensions"]
resources: ["podsecuritypolicies"]
resourceNames: ["nfs-provisioner"]
verbs: ["use"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-provisioner
subjects:
- kind: ServiceAccount
name: nfs-provisioner
namespace: default
roleRef:
kind: ClusterRole
name: nfs-provisioner-runner
apiGroup: rbac.authorization.k8s.io
運行yaml文件。
#創建nfs-Deployment:
[root@master yaml]# vim nfs-deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nfs-client-provisioner
namespace: default
spec:
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccount: nfs-provisioner
containers:
- name: nfs-client-provisioner
image: registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: nfs-deploy #供給方的名稱(自定義)
- name: NFS_SERVER
value: 172.16.1.30 #nfs服務器的ip地址
- name: NFS_PATH
value: /nfsdata #nfs共享的目錄
volumes:
- name: nfs-client-root
nfs:
server: 172.16.1.30
path: /nfsdata
#創建storage class:
[root@master yaml]# vim sc.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: statefu-nfs
namespace: default
provisioner: nfs-deploy
reclaimPolicy: Retain
//運行yaml文件后,查看sc的信息:
[root@master yaml]# kubectl get sc
NAME PROVISIONER AGE
statefu-nfs nfs-deploy 48s
2)創建statefulset資源:
[root@master yaml]# vim statefulset.yaml
apiVersion: v1
kind: Service
metadata:
name: headless-svc #定義無頭服務,需要定義標簽
labels:
app: headless-svc
spec:
ports:
- name: testweb
port: 80
clusterIP: None #需要將cluster ip定義為none
selector:
app: nginx #此處指定的標簽需要在后邊進行定義
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: sfs-web
spec:
serviceName: headless-svc #此處選擇的服務名為上邊定義的無頭服務名
replicas: 3
selector:
matchLabels:
app: nginx #選擇標簽
template:
metadata:
labels:
app: nginx #定義標簽
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
volumeMounts: #定義數據持久化
- name: test-nginx
mountPath: /usr/share/nginx/html #掛載到容器內的路徑
volumeClaimTemplates: #通過該字段(模板)為每個pod創建pvc
- metadata:
name: test-nginx
annotations:
volume.beta.kubernetes.io/storage-class: statefu-nfs #此處選擇之前創建的storage class,名稱要一致
spec:
accessModes:
- ReadWriteOnce #采用ReadWriteOnce的訪問模式
resources:
requests:
storage: 100Mi #請求100M的空間
[root@master yaml]# kubectl apply -f statefulset.yaml
service/headless-svc unchanged
statefulset.apps/sfs-web created
//運行成功后,查看創建的headless service和statefulset的狀態:
//查看svc的詳細信息:
//查看創建的pod:(確保正常運行)
可以看到每個pod都是有序的,它們的名稱(域名)會以0,1,2....依次排序。
#根據上面我們說到的,通過sc會創建pv,以及通過sts中的模板會自動創建pvc,我們進行查看集群中的pv和pvc:
我們可以看到pv和pvc創建成功,狀態已經是Bound了,訪問模式是RWO(在sc中定義的模式),回收策略Delete ,都是通過sc和sts動態創建的,而并不是我們手動創建。
3)測試數據持久化
#查看掛載到nfs服務器上是否會生成每個pvc的共享目錄:
#進入某個pod目錄下創建測試網頁文件:
[root@master yaml]# cd /nfsdata/default-test-nginx-sfs-web-0-pvc-4ef5e77e-1198-4ccc-81a7-db48d8a75023/
[root@master default-test-nginx-sfs-web-0-pvc-4ef5e77e-1198-4ccc-81a7-db48d8a75023]# echo "<h2>hello world</h2>" > index.html
[root@master default-test-nginx-sfs-web-0-pvc-4ef5e77e-1198-4ccc-81a7-db48d8a75023]# ll
total 4
-rw-r--r-- 1 root root 21 Jan 12 17:13 index.html
#我們進入到pod中,查看文件是否掛載成功:
#接下來我們將該pod刪除掉:
驗證重新生成的pod是否被替換,數據是否丟失?
通過上面的測試結果,我們可以得知有狀態的服務不同于無狀態服務,重新生成的pod名稱不會發生改變,即便刪除后也不會被新生成的pod覆蓋,且原有pod中的數據也一并會存在。
4)replicas的擴容與縮容:
(1)擴容操作:
[root@master yaml]# vim statefulset.yaml
//重新運行yaml文件,查看新生成的pod:
(2)縮容操作:(以倒序的方式依次縮減)
//重新運行服務,查看pod狀態:
通過上面的擴縮容操作,我們可以得知statefulset資源在生產環境中能夠實現有序部署,即有序擴展,有序收縮,且pod的啟停都是有一定順序的。
5)分區更新操作:分區更新的主要目的是為pod進行一個分區,為了使我們對某個應用所有pod中的某一部分或者有選擇性的pod進行更新操作。
#在更新之前,我們先來查看更新的參數:
[root@master yaml]# kubectl explain sts.spec.updateStrategy.rollingUpdate
KIND: StatefulSet
VERSION: apps/v1
RESOURCE: rollingUpdate <Object>
DESCRIPTION:
RollingUpdate is used to communicate parameters when Type is
RollingUpdateStatefulSetStrategyType.
RollingUpdateStatefulSetStrategy is used to communicate parameter for
RollingUpdateStatefulSetStrategyType.
FIELDS:
partition <integer>
Partition indicates the ordinal at which the StatefulSet should be
partitioned. Default value is 0.
#根據以上參數,我們對pod進行分區,并且對指定分區的pod進行版本升級:
我們將replicas的數量設置為8個,且定義分區更新,表示從第四個pod(分區)開始(包括第四個分區)進行更新,之前的pod是不會進行更新操作的。
注意:如果不指定分區,則默認分區從0開始。
#版本升級就不進行測試了,只需將鏡像更改為新的nginx版本,重新運行服務后,可以看到從第四個pod開始(包括第四個)之后的pod鏡像版本將會進行升級,而之前分區的pod,版本不會發生改變。
4,StatefulSet限制
1)該資源對象還在beta(測試)狀態,需要kubernetes v1.5版本以上才支持。
2)所有pod的volume必須使用pv或者是管理員事先創建好的。
3)為了保證數據安全,刪除statefulset時不會刪除volume。
4)statefulset需要一個Headless Service服務來定義DNS domin,需要在statefulset之前創建好。
5)目前statefulset功能還尚未完善,比如上面的更新操作還需要手動解決。
以上就是statefulset資源的理解與實踐,如果應用程序不需要任何穩定的標識符,有序部署,刪除和scale,則使用Deployment或RS等無狀態控制器來部署。反之在生產中使用statefulset控制器為保證pod與volume的關系不會斷開,即使pod掛了后還能使用之前掛載的磁盤
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。