kubernetes——StatefulSet詳解

概述

RC玉罐、Deployment屈嗤、DaemonSet都是面向無狀態(tài)的服務(wù)潘拨,它們所管理的Pod的IP、名字恢共,啟停順序等都是隨機的战秋,而StatefulSet是什么?顧名思義讨韭,有狀態(tài)的集合脂信,管理所有有狀態(tài)的服務(wù),比如MySQL透硝、MongoDB集群等狰闪。
StatefulSet本質(zhì)上是Deployment的一種變體,在v1.9版本中已成為GA版本,它為了解決有狀態(tài)服務(wù)的問題,它所管理的Pod擁有固定的Pod名稱遂蛀,啟停順序,在StatefulSet中丽声,Pod名字稱為網(wǎng)絡(luò)標(biāo)識(hostname),還必須要用到共享存儲觉义。

在Deployment中雁社,與之對應(yīng)的服務(wù)是service,而在StatefulSet中與之對應(yīng)的headless service晒骇,headless service霉撵,即無頭服務(wù),與service的區(qū)別就是它沒有Cluster IP洪囤,解析它的名稱時將返回該Headless Service對應(yīng)的全部Pod的Endpoint列表徒坡。

除此之外,StatefulSet在Headless Service的基礎(chǔ)上又為StatefulSet控制的每個Pod副本創(chuàng)建了一個DNS域名瘤缩,這個域名的格式為:

$(podname).(headless server name)
FQDN: $(podname).(headless server name).namespace.svc.cluster.local

StatefulSet示例

接下來看一些示例喇完,演示下上面所說的特性,以加深理解

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:
  selector:
    matchLabels:
      app: nginx # has to match .spec.template.metadata.labels
  serviceName: "nginx"  #聲明它屬于哪個Headless Service.
  replicas: 3 # by default is 1
  template:
    metadata:
      labels:
        app: nginx # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: nginx:1.20.1
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:   #可看作pvc的模板
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "gluster-heketi"  #存儲類名剥啤,改為集群中已存在的
      resources:
        requests:
          storage: 1Gi

通過該配置文件何暮,可看出StatefulSet的三個組成部分:

  • Headless Service:名為nginx,用來定義Pod網(wǎng)絡(luò)標(biāo)識( DNS domain)铐殃。
  • StatefulSet:定義具體應(yīng)用,名為Nginx跨新,有三個Pod副本富腊,并為每個Pod定義了一個域名。
  • volumeClaimTemplates: 存儲卷申請模板域帐,創(chuàng)建PVC赘被,指定pvc名稱大小是整,將自動創(chuàng)建pvc,且pvc必須由存儲類供應(yīng)民假。

為什么需要 headless service 無頭服務(wù)浮入?
在用Deployment時,每一個Pod名稱是沒有順序的羊异,是隨機字符串事秀,因此是Pod名稱是無序的,但是在statefulset中要求必須是有序 野舶,每一個pod不能被隨意取代易迹,pod重建后pod名稱還是一樣的。而pod IP是變化的平道,所以是以Pod名稱來識別睹欲。pod名稱是pod唯一性的標(biāo)識符,必須持久穩(wěn)定有效一屋。這時候要用到無頭服務(wù)窘疮,它可以給每個Pod一個唯一的名稱 。

為什么需要volumeClaimTemplate冀墨?
對于有狀態(tài)的副本集都會用到持久存儲闸衫,對于分布式系統(tǒng)來講,它的最大特點是數(shù)據(jù)是不一樣的轧苫,所以各個節(jié)點不能使用同一存儲卷楚堤,每個節(jié)點有自已的專用存儲,但是如果在Deployment中的Pod template里定義的存儲卷含懊,是所有副本集共用一個存儲卷身冬,數(shù)據(jù)是相同的,因為是基于模板來的 岔乔,而statefulset中每個Pod都要自已的專有存儲卷酥筝,所以statefulset的存儲卷就不能再用Pod模板來創(chuàng)建了,于是statefulSet使用volumeClaimTemplate雏门,稱為卷申請模板嘿歌,它會為每個Pod生成不同的pvc,并綁定pv茁影, 從而實現(xiàn)各pod有專用存儲宙帝。這就是為什么要用volumeClaimTemplate的原因。

創(chuàng)建:

$ kubectl create -f nginx.yaml 
service "nginx" created
statefulset "web" created

看下這三個Pod創(chuàng)建過程:

#第一個是創(chuàng)建web-0
$ kubectl get pod
web-0                     1/1       ContainerCreating   0          51s

#待web-0 running且ready時募闲,創(chuàng)建web-1
$ kubectl get pod
web-0                     1/1       Running             0          51s
web-1                     0/1       ContainerCreating   0          42s

#待web-1 running且ready時步脓,創(chuàng)建web-2
$ kubectl get pod
web-0                     1/1       Running             0          1m
web-1                     1/1       Running             0          45s
web-2                     1/1       ContainerCreating   0          36s

#最后三個Pod全部running且ready
$ kubectl get pod
NAME                      READY     STATUS    RESTARTS   AGE
web-0                     1/1       Running   0          4m
web-1                     1/1       Running   0          3m
web-2                     1/1       Running   0          1m

根據(jù)volumeClaimTemplates自動創(chuàng)建的PVC

$ kubectl get pvc
NAME              STATUS    VOLUME                                  CAPACITY   ACCESS MODES   STORAGECLASS     AGE
www-web-0         Bound     pvc-ecf003f3-828d-11e8-8815-000c29774d39   2G        RWO          gluster-heketi   7m
www-web-1         Bound     pvc-0615e33e-828e-11e8-8815-000c29774d39   2G        RWO          gluster-heketi   6m
www-web-2         Bound     pvc-43a97acf-828e-11e8-8815-000c29774d39   2G        RWO          gluster-heketi   4m

如果集群中沒有StorageClass的動態(tài)供應(yīng)PVC的機制,也可以提前手動創(chuàng)建多個PV、PVC靴患,手動創(chuàng)建的PVC名稱必須符合之后創(chuàng)建的StatefulSet命名規(guī)則:(volumeClaimTemplates.name)-(pod_name)

Statefulset名稱為web 三個Pod副本: web-0仍侥,web-1,web-2,volumeClaimTemplates名稱為:www鸳君,那么自動創(chuàng)建出來的PVC名稱為www-web[0-2]农渊,為每個Pod創(chuàng)建一個PVC。

規(guī)律總結(jié):

匹配Pod name(網(wǎng)絡(luò)標(biāo)識)的模式為:(statefulset名稱)-(序號)或颊,比如上面的示例:web-0砸紊,web-1,web-2饭宾。

StatefulSet為每個Pod副本創(chuàng)建了一個DNS域名批糟,這個域名的格式為: $(podname).(headless server name),也就意味著服務(wù)間是通過Pod域名來通信而非Pod IP看铆,因為當(dāng)Pod所在Node發(fā)生故障時徽鼎,Pod會被飄移到其它Node上,Pod IP會發(fā)生變化弹惦,但是Pod域名不會有變化否淤。

StatefulSet使用Headless服務(wù)來控制Pod的域名,這個域名的FQDN為:(service name).(namespace).svc.cluster.local棠隐,其中石抡,“cluster.local”指的是集群的域名。

根據(jù)volumeClaimTemplates助泽,為每個Pod創(chuàng)建一個pvc啰扛,pvc的命名規(guī)則匹配模式:(volumeClaimTemplates.name)-(pod_name),比如上面的volumeMounts.name=www嗡贺, Pod name=web-[0-2]隐解,因此創(chuàng)建出來的PVC是www-web-0、www-web-1诫睬、www-web-2煞茫。

刪除Pod不會刪除其pvc,手動刪除pvc將自動釋放pv摄凡。
關(guān)于Cluster Domain续徽、headless service名稱、StatefulSet 名稱如何影響StatefulSet的Pod的DNS域名的示例:

Cluster Domain Service (ns/name) StatefulSet (ns/name) StatefulSet Domain Pod DNS Pod Hostname
cluster.local default/nginx default/web nginx.default.svc.cluster.local web-{0..N-1}.nginx.default.svc.cluster.local web-{0..N-1}
cluster.local foo/nginx foo/web nginx.foo.svc.cluster.local web-{0..N-1}.nginx.foo.svc.cluster.local web-{0..N-1}
kube.local foo/nginx foo/web nginx.foo.svc.kube.local web-{0..N-1}.nginx.foo.svc.kube.local web-{0..N-1}

Statefulset的啟停順序:

  • 有序部署:部署StatefulSet時亲澡,如果有多個Pod副本钦扭,它們會被順序地創(chuàng)建(從0到N-1)并且,在下一個Pod運行之前所有之前的Pod必須都是Running和Ready狀態(tài)床绪。

  • 有序刪除:當(dāng)Pod被刪除時土全,它們被終止的順序是從N-1到0捎琐。

  • 有序擴展:當(dāng)對Pod執(zhí)行擴展操作時,與部署一樣裹匙,它前面的Pod必須都處于Running和Ready狀態(tài)

Statefulset Pod管理策略:

在v1.7以后,通過允許修改Pod排序策略末秃,同時通過.spec.podManagementPolicy字段確保其身份的唯一性概页。

  • OrderedReady:上述的啟停順序,默認(rèn)設(shè)置练慕。
  • Parallel:告訴StatefulSet控制器并行啟動或終止所有Pod惰匙,并且在啟動或終止另一個Pod之前不等待前一個Pod變?yōu)镽unning and Ready或完全終止。

StatefulSet使用場景:

  • 穩(wěn)定的持久化存儲铃将,即Pod重新調(diào)度后還是能訪問到相同的持久化數(shù)據(jù)项鬼,基于PVC來實現(xiàn)。

  • 穩(wěn)定的網(wǎng)絡(luò)標(biāo)識符劲阎,即Pod重新調(diào)度后其PodName和HostName不變绘盟。

  • 有序部署,有序擴展悯仙,基于init containers來實現(xiàn)龄毡。

  • 有序收縮。

更新策略

在Kubernetes 1.7及更高版本中锡垄,通過.spec.updateStrategy字段允許配置或禁用Pod沦零、labels、source request/limits货岭、annotations自動滾動更新功能路操。

  • OnDelete:通過.spec.updateStrategy.type 字段設(shè)置為OnDelete,StatefulSet控制器不會自動更新StatefulSet中的Pod千贯。用戶必須手動刪除Pod屯仗,以使控制器創(chuàng)建新的Pod。

  • RollingUpdate:通過.spec.updateStrategy.type 字段設(shè)置為RollingUpdate丈牢,實現(xiàn)了Pod的自動滾動更新祭钉,如果.spec.updateStrategy未指定,則此為默認(rèn)策略己沛。

StatefulSet控制器將刪除并重新創(chuàng)建StatefulSet中的每個Pod慌核。它將以Pod終止(從最大序數(shù)到最小序數(shù))的順序進行,一次更新每個Pod申尼。在更新下一個Pod之前垮卓,必須等待這個Pod Running and Ready。

  • Partitions:通過指定 .spec.updateStrategy.rollingUpdate.partition 來對 RollingUpdate 更新策略進行分區(qū)师幕,如果指定了分區(qū)粟按,則當(dāng) StatefulSet 的 .spec.template 更新時诬滩,具有大于或等于分區(qū)序數(shù)的所有 Pod 將被更新。
    具有小于分區(qū)的序數(shù)的所有 Pod 將不會被更新灭将,即使刪除它們也將被重新創(chuàng)建疼鸟。如果 StatefulSet 的 .spec.updateStrategy.rollingUpdate.partition 大于其 .spec.replicas,則其 .spec.template 的更新將不會傳播到 Pod庙曙。在大多數(shù)情況下空镜,不需要使用分區(qū)。

參考:
https://www.cnblogs.com/tylerzhou/p/11027559.html

https://www.cnblogs.com/buyicoding/p/12591259.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末捌朴,一起剝皮案震驚了整個濱河市吴攒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌砂蔽,老刑警劉巖洼怔,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異左驾,居然都是意外死亡镣隶,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門什荣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來矾缓,“玉大人,你說我怎么就攤上這事稻爬∈任牛” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵桅锄,是天一觀的道長琉雳。 經(jīng)常有香客問我,道長友瘤,這世上最難降的妖魔是什么翠肘? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮辫秧,結(jié)果婚禮上束倍,老公的妹妹穿的比我還像新娘。我一直安慰自己盟戏,他們只是感情好绪妹,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著柿究,像睡著了一般邮旷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蝇摸,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天婶肩,我揣著相機與錄音办陷,去河邊找鬼。 笑死律歼,一個胖子當(dāng)著我的面吹牛民镜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播苗膝,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼殃恒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了辱揭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤病附,失蹤者是張志新(化名)和其女友劉穎问窃,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體完沪,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡域庇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了覆积。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片听皿。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖宽档,靈堂內(nèi)的尸體忽然破棺而出尉姨,到底是詐尸還是另有隱情,我是刑警寧澤吗冤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布又厉,位于F島的核電站,受9級特大地震影響椎瘟,放射性物質(zhì)發(fā)生泄漏覆致。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一肺蔚、第九天 我趴在偏房一處隱蔽的房頂上張望煌妈。 院中可真熱鬧,春花似錦宣羊、人聲如沸璧诵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腮猖。三九已至,卻和暖如春赞枕,著一層夾襖步出監(jiān)牢的瞬間澈缺,已是汗流浹背坪创。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留姐赡,地道東北人莱预。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像项滑,于是被迫代替她去往敵國和親依沮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容

  • 概述 RC枪狂、Deployment危喉、DaemonSet都是面向無狀態(tài)的服務(wù),它們所管理的Pod的IP州疾、名字辜限,啟停順序...
    小波同學(xué)閱讀 2,307評論 0 1
  • Statefulset控制器:概念、原理解讀StatefulSet是為了管理有狀態(tài)服務(wù)的問題而設(shè)計的 有狀態(tài)服務(wù)?...
    菜頭_355f閱讀 2,214評論 0 0
  • 概述 RC严蓖、Deployment薄嫡、DaemonSet都是面向無狀態(tài)的服務(wù),它們所管理的Pod的IP颗胡、名字毫深,啟停順序...
    沉淪2014閱讀 11,472評論 1 5
  • 一哑蔫、前言 上一文《從零開始搭建Kubernetes集群(五、搭建K8S Ingress)》[https://www...
    宅楠軍閱讀 55,685評論 43 63
  • 16宿命:用概率思維提高你的勝算 以前的我是風(fēng)險厭惡者手素,不喜歡去冒險鸳址,但是人生放棄了冒險,也就放棄了無數(shù)的可能泉懦。 ...
    yichen大刀閱讀 6,033評論 0 4