【本文目標(biāo)】
-
StatefulSet
介紹 -
Deployment
和StatefulSet
組件的區(qū)別
【前置文章】
- 【k8s學(xué)習(xí)】Kubernetes學(xué)習(xí)——核心組件和架構(gòu)
- 【k8s學(xué)習(xí)】minikube卢鹦、kubectl陡蝇、yaml配置文件的介紹
- 【k8s學(xué)習(xí)】在minikube上布署MongoDB和MongoExpress
- 【k8s學(xué)習(xí)】kubernetes namespace介紹
- 【k8s學(xué)習(xí)】Kubernetes Ingress介紹
- 【k8s學(xué)習(xí)】Kubernetes打包工具Helm介紹
- 【k8s學(xué)習(xí)】Kubernetes Volume介紹
1. StatefulSet介紹
官網(wǎng):https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/statefulset/
StatefulSet
組件是用來管理stateful applications的(有狀態(tài)的應(yīng)用)丑念,如:MySQL吃嘿,elasticsearch贱迟,mongoDB等娜氏〔霰玻或者別的需要存儲數(shù)據(jù)的應(yīng)用。
對應(yīng)的stateless applications即無狀態(tài)的應(yīng)用率拒,比如普通的前端UI項目或是后臺java項目(自身不存儲數(shù)據(jù))崩泡。
2. Deployment vs. StatefulSet
StatefulSet
組件和Deployment
組件都可以使用Storage
。
- 針對
無狀態(tài)的服務(wù)
猬膨,Kubernetes使用Deployment
組件來管理角撞。 - 針對
有狀態(tài)的服務(wù)
,Kubernetes使用StatefulSet
組件來管理勃痴。
具體來說谒所,假設(shè)我們需要部署my-app項目(目標(biāo)3個Pod),以及數(shù)據(jù)庫mysql(目標(biāo)也是3個Pod)沛申。
2.1 Deployment
對于my-app Pod劣领,我們會寫一個Deployment的yaml配置文件,在里面配上ReplicaSet=3铁材,表示需要創(chuàng)建3個Pod尖淘,以及my-app Container的鏡像,用來創(chuàng)建Pod時用著觉。創(chuàng)建出來的my-app會是:
-
identical and interchangeable
:即創(chuàng)建的三個my-app Pod是相同的村生,以及如果一個掛了,很容易再新創(chuàng)建一個饼丘。 -
created in random order with random hashes
:三個my-app Pod啟動也沒有先后順序梆造,可以隨意。 -
one Service that load balances to any Pod
:一個Service組件可以幫助做負(fù)載均衡葬毫。
2.2 StatefulSet
而對于mysql Pod,會使用StatefulSet
組件來創(chuàng)建:
-
can't be created/deleted at same time
:創(chuàng)建的時候是有順序的 -
can't be randomly addressed
:并不是隨機訪問的 -
replica Pods are not identical
:主要原因是創(chuàng)建的Pod之間屡穗,并不是完全相同的贴捡,相反的,每個創(chuàng)建的Pod都有自己額外的標(biāo)志(這個標(biāo)志是唯一的)村砂。
2.2.1 Pod Identity(Pod標(biāo)志)
-
sticky identity for each pod
:即上述說的針對有狀態(tài)的服務(wù)烂斋,Pod除了id外,還有額外的唯一標(biāo)志础废,比如創(chuàng)建的3個mysql Pod汛骂,Pod標(biāo)志可以是:mysql-0
,mysql-1
,mysql-2
,一般為${statefulset name}-${order}
评腺。 -
created from same specification, but not interchangeable!
:雖然都是從同一個StatefulSet配置中創(chuàng)建的帘瞭,但有狀態(tài)的Pod并不像無狀態(tài)的Pod一樣是可交換的。 -
persistent identifier across any re-scheduling
:比如ID-2 down了蒿讥,并不是會再生成一個ID-3或是別的蝶念,而是會新生成一個Pod來代替這個ID-2抛腕,即Identity不變。
聽上去很繞媒殉,以及有狀態(tài)的服務(wù)為啥需要額外的Pod Identity呢担敌?
主要原因是如下的架構(gòu),會導(dǎo)致數(shù)據(jù)的不一致廷蓉,多個Pod全封,都有讀寫,數(shù)據(jù)就會變的不同步桃犬。
通常情況下刹悴,只會有一臺負(fù)責(zé)寫,負(fù)責(zé)寫的這臺叫MASTER
疫萤,其余的叫WORKER
:
這也是為什么會就StatefulSet創(chuàng)建的Pod并不是完全相同的Pod颂跨,因為只有一臺是Master。
-
They do not use the same physical storage扯饶!
臼疫,即上述的三個volume,并不是相同的地址落萎,可以是:/data/vol/pv-0
,/data/vol/pv-1
,data/vol/pv-2
迷郑,相當(dāng)于是有數(shù)據(jù)的備份。 -
Continuously synchronizing of the data
:這意味著Master和Worker節(jié)點間有數(shù)據(jù)的同步每币。Master是唯一有寫權(quán)限的携丁,所以Worker需要及時知道數(shù)據(jù)的改動,以及它自己的pv中的數(shù)據(jù)得到更新兰怠。 -
the first one is the Master
:最先啟動的Pod為Master梦鉴。 -
Next Pod is only created, if previous is up and running!
:即有狀態(tài)的Pod是安順序啟動的,并且要等前面的Pod啟動好了再啟動新的Pod揭保。 -
Deletion in reverse order, starting from the last one
:如果刪除該StatefulSet肥橙,那么Pod的刪除是啟動順序的倒序,即最先刪除最后啟動的那個Pod秸侣,刪除成功后再接著刪除倒數(shù)第2存筏,以此類推。
【整個過程】
Master修改了數(shù)據(jù)
--> 所有的Worker感知到了數(shù)據(jù)的變動味榛,開始修改自己的pv
--> 這時候要是新加入一個Pod椭坚,叫mysql-3,它會創(chuàng)建自己的Storage搏色,然后會先從它順序的前一個的Pod中clone數(shù)據(jù)善茎。
--> mysql-3完成了clone數(shù)據(jù)后,也會開始監(jiān)聽數(shù)據(jù)的改動频轿,以便及時更新到它自己的Storage中
Pod state
有狀態(tài)的服務(wù)巾表,它的Storage存放的不僅是Pod的數(shù)據(jù)汁掠,還會存Pod的狀態(tài)
,如它所連的Pod是Master Pod還是Worker Pod等集币。當(dāng)這個Storage所連的Pod掛了考阱,如上述說的,并不是新起一個Pod鞠苟,Pod標(biāo)志什么的都變了乞榨,而是新起的這個Pod會替換掉原來的Pod,即Pod Identity都不會變当娱,這時候之前的Storage會re-attached(重新連接)上這個Pod吃既,這樣就可以避免新起的Pod上來就先clone數(shù)據(jù)。--> 當(dāng)然這里需要使用的是Remote storage跨细!因為Local storage可能會跟隨著舊的Node一起掛掉鹦倚。
Pod endpoints
有服務(wù)狀態(tài)的Service會有自己的DNS name,名字格式:${pod name}.${governing service domain}
冀惭,如mysql-0.svc2
震叙,mysql-1.svc2
,mysql-2.svc2
散休。
這意味著如果Pod重啟了媒楼,那么IP地址可以變了,但是name以及endpoint不會變戚丸。
3. 總結(jié)
關(guān)于有狀態(tài)服務(wù)的部署划址,并沒有像無狀態(tài)服務(wù)部署來的容易。需要額外做很多事:
- 需要關(guān)心數(shù)據(jù)的sync同步問題限府。
- 需要Remote Storage(假使集群down了數(shù)據(jù)仍然在)
- 數(shù)據(jù)備份問題夺颤。