日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

目錄
  • StatefulSet 對(duì)存儲(chǔ)狀態(tài)的管理機(jī)制
    • 第一步:定義一個(gè) PVC,聲明想要的 Volume 的屬性
    • 第二步:在應(yīng)用的 Pod 中,聲明使用這個(gè) PVC
  • 常見的 PV 對(duì)象的 YAML 文件

    StatefulSet 對(duì)存儲(chǔ)狀態(tài)的管理機(jī)制

    這個(gè)機(jī)制,主要使用的是一個(gè)叫作 Persistent Volume Claim 的功能。

    要在一個(gè) Pod 里聲明 Volume,只要在 Pod 里加上 spec.volumes 字段即可。然后,你就可以在這個(gè)字段里定義一個(gè)具體類型的 Volume 了,比如:hostPath。

    可是,你有沒有想過這樣一個(gè)場景:如果你并不知道有哪些 Volume 類型可以用,要怎么辦呢?

    更具體地說,作為一個(gè)應(yīng)用開發(fā)者,我可能對(duì)持久化存儲(chǔ)項(xiàng)目(比如 Ceph、GlusterFS 等)一竅不通,也不知道公司的 Kubernetes 集群里到底是怎么搭建出來的,我也自然不會(huì)編寫它們對(duì)應(yīng)的 Volume 定義文件。

    這些關(guān)于 Volume 的管理和遠(yuǎn)程持久化存儲(chǔ)的知識(shí),不僅超越了開發(fā)者的知識(shí)儲(chǔ)備,還會(huì)有暴露公司基礎(chǔ)設(shè)施秘密的風(fēng)險(xiǎn)。

    比如,下面這個(gè)例子,就是一個(gè)聲明了 Ceph RBD 類型 Volume 的 Pod:

    apiVersion: v1
    kind: Pod
    metadata:
      name: rbd
    spec:
      containers:
        - image: kubernetes/pause
          name: rbd-rw
          volumeMounts:
          - name: rbdpd
            mountPath: /mnt/rbd
      volumes:
        - name: rbdpd
          rbd:
            monitors:
            - '10.16.154.78:6789'
            - '10.16.154.82:6789'
            - '10.16.154.83:6789'
            pool: kube
            image: foo
            fsType: ext4
            readOnly: true
            user: admin
            keyring: /etc/ceph/keyring
            imageformat: "2"
            imagefeatures: "layering"
    

    其一,如果不懂得 Ceph RBD 的使用方法,那么這個(gè) Pod 里 Volumes 字段,你十有八九也完全看不懂。其二,這個(gè) Ceph RBD 對(duì)應(yīng)的存儲(chǔ)服務(wù)器的地址、用戶名、授權(quán)文件的位置,也都被輕易地暴露給了全公司的所有開發(fā)人員,這是一個(gè)典型的信息被“過度暴露”的例子。

    這也是為什么,在后來的演化中,Kubernetes 項(xiàng)目引入了一組叫作 Persistent Volume Claim(PVC)和 Persistent Volume(PV)的 API 對(duì)象,大大降低了用戶聲明和使用持久化 Volume 的門檻。

    舉個(gè)例子,有了 PVC 之后,一個(gè)開發(fā)人員想要使用一個(gè) Volume,只需要簡單的兩步即可。

    第一步:定義一個(gè) PVC,聲明想要的 Volume 的屬性

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: pv-claim
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
    

    可以看到,在這個(gè) PVC 對(duì)象里,不需要任何關(guān)于 Volume 細(xì)節(jié)的字段,只有描述性的屬性和定義。比如,storage: 1Gi,表示我想要的 Volume 大小至少是 1 GiB;accessModes: ReadWriteOnce,表示這個(gè) Volume 的掛載方式是可讀寫,并且只能被掛載在一個(gè)節(jié)點(diǎn)上而非被多個(gè)節(jié)點(diǎn)共享。

    第二步:在應(yīng)用的 Pod 中,聲明使用這個(gè) PVC

    apiVersion: v1
    kind: Pod
    metadata:
      name: pv-pod
    spec:
      containers:
        - name: pv-container
          image: nginx
          ports:
            - containerPort: 80
              name: "http-server"
          volumeMounts:
            - mountPath: "/usr/share/nginx/html"
              name: pv-storage
      volumes:
        - name: pv-storage
          persistentVolumeClaim:
            claimName: pv-claim
    

    可以看到,在這個(gè) Pod 的 Volumes 定義中,我們只需要聲明它的類型是 persistentVolumeClaim,然后指定 PVC 的名字,而完全不必關(guān)心 Volume 本身的定義。

    這時(shí)候,只要我們創(chuàng)建這個(gè) PVC 對(duì)象,Kubernetes 就會(huì)自動(dòng)為它綁定一個(gè)符合條件的 Volume。可是,這些符合條件的 Volume 又是從哪里來的呢?

    答案是,它們來自于由運(yùn)維人員維護(hù)的 PV(Persistent Volume)對(duì)象。

    常見的 PV 對(duì)象的 YAML 文件

    kind: PersistentVolume
    apiVersion: v1
    metadata:
      name: pv-volume
      labels:
        type: local
    spec:
      capacity:
        storage: 10Gi
      rbd:
        monitors:
        - '10.16.154.78:6789'
        - '10.16.154.82:6789'
        - '10.16.154.83:6789'
        pool: kube
        image: foo
        fsType: ext4
        readOnly: true
        user: admin
        keyring: /etc/ceph/keyring
        imageformat: "2"
        imagefeatures: "layering"
    

    可以看到,這個(gè) PV 對(duì)象的 spec.rbd 字段,正是我們前面介紹過的 Ceph RBD Volume 的詳細(xì)定義。而且,它還聲明了這個(gè) PV 的容量是 10 GiB。這樣,Kubernetes 就會(huì)為我們剛剛創(chuàng)建的 PVC 對(duì)象綁定這個(gè) PV。

    所以,Kubernetes 中 PVC 和 PV 的設(shè)計(jì),實(shí)際上類似于“接口”和“實(shí)現(xiàn)”的思想。開發(fā)者只要知道并會(huì)使用“接口”,即:PVC;而運(yùn)維人員則負(fù)責(zé)給“接口”綁定具體的實(shí)現(xiàn),即:PV。

    這種解耦,就避免了因?yàn)橄蜷_發(fā)者暴露過多的存儲(chǔ)系統(tǒng)細(xì)節(jié)而帶來的隱患。此外,這種職責(zé)的分離,往往也意味著出現(xiàn)事故時(shí)可以更容易定位問題和明確責(zé)任,從而避免“扯皮”現(xiàn)象的出現(xiàn)。

    而 PVC、PV 的設(shè)計(jì),也使得 StatefulSet 對(duì)存儲(chǔ)狀態(tài)的管理成為了可能。

    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: nginx:1.9.1
            ports:
            - containerPort: 80
              name: web
            volumeMounts:
            - name: www
              mountPath: /usr/share/nginx/html
      volumeClaimTemplates:
      - metadata:
          name: www
        spec:
          accessModes:
          - ReadWriteOnce
          resources:
            requests:
              storage: 1Gi
    

    這次,我們?yōu)檫@個(gè) StatefulSet 額外添加了一個(gè) volumeClaimTemplates 字段。從名字就可以看出來,它跟 Deployment 里 Pod 模板(PodTemplate)的作用類似。也就是說,凡是被這個(gè) StatefulSet 管理的 Pod,都會(huì)聲明一個(gè)對(duì)應(yīng)的 PVC;而這個(gè) PVC 的定義,就來自于 volumeClaimTemplates 這個(gè)模板字段。更重要的是,這個(gè) PVC 的名字,會(huì)被分配一個(gè)與這個(gè) Pod 完全一致的編號(hào)。

    這個(gè)自動(dòng)創(chuàng)建的 PVC,與 PV 綁定成功后,就會(huì)進(jìn)入 Bound 狀態(tài),這就意味著這個(gè) Pod 可以掛載并使用這個(gè) PV 了。

    如果你還是不太理解 PVC 的話,可以先記住這樣一個(gè)結(jié)論:PVC 其實(shí)就是一種特殊的 Volume。只不過一個(gè) PVC 具體是什么類型的 Volume,要在跟某個(gè) PV 綁定之后才知道。關(guān)于 PV、PVC 更詳細(xì)的知識(shí),我會(huì)在容器存儲(chǔ)部分做進(jìn)一步解讀。

    當(dāng)然,PVC 與 PV 的綁定得以實(shí)現(xiàn)的前提是,運(yùn)維人員已經(jīng)在系統(tǒng)里創(chuàng)建好了符合條件的 PV(比如,我們?cè)谇懊嬗玫降?pv-volume);或者,你的 Kubernetes 集群運(yùn)行在公有云上,這樣 Kubernetes 就會(huì)通過 Dynamic Provisioning 的方式,自動(dòng)為你創(chuàng)建與 PVC 匹配的 PV。

    所以,我們?cè)谑褂?kubectl create 創(chuàng)建了 StatefulSet 之后,就會(huì)看到 Kubernetes 集群里出現(xiàn)了兩個(gè) PVC

    可以看到,這些 PVC,都以“<PVC 名字 >-<StatefulSet 名字 >-< 編號(hào) >”的方式命名,并且處于 Bound 狀態(tài)。

    我們前面已經(jīng)講到過,這個(gè) StatefulSet 創(chuàng)建出來的所有 Pod,都會(huì)聲明使用編號(hào)的 PVC。比如,在名叫 web-0 的 Pod 的 volumes 字段,它會(huì)聲明使用名叫 www-web-0 的 PVC,從而掛載到這個(gè) PVC 所綁定的 PV。

    所以,我們就可以使用如下所示的指令,在 Pod 的 Volume 目錄里寫入一個(gè)文件,來驗(yàn)證一下上述 Volume 的分配情況

    for i in 0 1; do kubectl exec web-$i — sh -c 'echo hello $(hostname) > /usr/share/nginx/html/index.html'; done

    如上所示,通過 kubectl exec 指令,我們?cè)诿總€(gè) Pod 的 Volume 目錄里,寫入了一個(gè) index.html 文件。這個(gè)文件的內(nèi)容,正是 Pod 的 hostname。比如,我們?cè)?web-0 的 index.html 里寫入的內(nèi)容就是 "hello web-0"。

    此時(shí),如果你在這個(gè) Pod 容器里訪問“http://localhost”,你實(shí)際訪問到的就是 Pod 里 Nginx 服務(wù)器進(jìn)程,而它會(huì)為你返回 /usr/share/nginx/html/index.html 里的內(nèi)容。這個(gè)操作的執(zhí)行方法如下所示:

    $ for i in 0 1; do kubectl exec -it web-$i -- curl localhost; done
    hello web-0
    hello web-1
    

    如果你使用 kubectl delete 命令刪除這兩個(gè) Pod,這些 Volume 里的文件會(huì)不會(huì)丟失呢?

    可以看到,正如我們前面介紹過的,在被刪除之后,這兩個(gè) Pod 會(huì)被按照編號(hào)的順序被重新創(chuàng)建出來。而這時(shí)候,如果你在新創(chuàng)建的容器里通過訪問“http://localhost”的方式去訪問 web-0 里的 Nginx 服務(wù)

    就會(huì)發(fā)現(xiàn),這個(gè)請(qǐng)求依然會(huì)返回:hello web-0。也就是說,原先與名叫 web-0 的 Pod 綁定的 PV,在這個(gè) Pod 被重新創(chuàng)建之后,依然同新的名叫 web-0 的 Pod 綁定在了一起。對(duì)于 Pod web-1 來說,也是完全一樣的情況。

    這是怎么做到的呢?

    其實(shí),我和你分析一下 StatefulSet 控制器恢復(fù)這個(gè) Pod 的過程,你就可以很容易理解了。

    首先,當(dāng)你把一個(gè) Pod,比如 web-0,刪除之后,這個(gè) Pod 對(duì)應(yīng)的 PVC 和 PV,并不會(huì)被刪除,而這個(gè) Volume 里已經(jīng)寫入的數(shù)據(jù),也依然會(huì)保存在遠(yuǎn)程存儲(chǔ)服務(wù)里(比如,我們?cè)谶@個(gè)例子里用到的 Ceph 服務(wù)器)。

    此時(shí),StatefulSet 控制器發(fā)現(xiàn),一個(gè)名叫 web-0 的 Pod 消失了。所以,控制器就會(huì)重新創(chuàng)建一個(gè)新的、名字還是叫作 web-0 的 Pod 來,“糾正”這個(gè)不一致的情況。

    需要注意的是,在這個(gè)新的 Pod 對(duì)象的定義里,它聲明使用的 PVC 的名字,還是叫作:www-web-0。這個(gè) PVC 的定義,還是來自于 PVC 模板(volumeClaimTemplates),這是 StatefulSet 創(chuàng)建 Pod 的標(biāo)準(zhǔn)流程。

    所以,在這個(gè)新的 web-0 Pod 被創(chuàng)建出來之后,Kubernetes 為它查找名叫 www-web-0 的 PVC 時(shí),就會(huì)直接找到舊 Pod 遺留下來的同名的 PVC,進(jìn)而找到跟這個(gè) PVC 綁定在一起的 PV。

    這樣,新的 Pod 就可以掛載到舊 Pod 對(duì)應(yīng)的那個(gè) Volume,并且獲取到保存在 Volume 里的數(shù)據(jù)。

    通過這種方式,Kubernetes 的 StatefulSet 就實(shí)現(xiàn)了對(duì)應(yīng)用存儲(chǔ)狀態(tài)的管理。

    看到這里,你是不是已經(jīng)大致理解了 StatefulSet 的工作原理呢?現(xiàn)在,我再為你詳細(xì)梳理一下吧。

    首先,StatefulSet 的控制器直接管理的是 Pod。這是因?yàn)椋琒tatefulSet 里的不同 Pod 實(shí)例,不再像 ReplicaSet 中那樣都是完全一樣的,而是有了細(xì)微區(qū)別的。比如,每個(gè) Pod 的 hostname、名字等都是不同的、攜帶了編號(hào)的。而 StatefulSet 區(qū)分這些實(shí)例的方式,就是通過在 Pod 的名字里加上事先約定好的編號(hào)。

    其次,Kubernetes 通過 Headless Service,為這些有編號(hào)的 Pod,在 DNS 服務(wù)器中生成帶有同樣編號(hào)的 DNS 記錄。只要 StatefulSet 能夠保證這些 Pod 名字里的編號(hào)不變,那么 Service 里類似于 web-0.nginx.default.svc.cluster.local 這樣的 DNS 記錄也就不會(huì)變,而這條記錄解析出來的 Pod 的 IP 地址,則會(huì)隨著后端 Pod 的刪除和再創(chuàng)建而自動(dòng)更新。這當(dāng)然是 Service 機(jī)制本身的能力,不需要 StatefulSet 操心。

    最后,StatefulSet 還為每一個(gè) Pod 分配并創(chuàng)建一個(gè)同樣編號(hào)的 PVC。這樣,Kubernetes 就可以通過 Persistent Volume 機(jī)制為這個(gè) PVC 綁定上對(duì)應(yīng)的 PV,從而保證了每一個(gè) Pod 都擁有一個(gè)獨(dú)立的 Volume。

    在這種情況下,即使 Pod 被刪除,它所對(duì)應(yīng)的 PVC 和 PV 依然會(huì)保留下來。所以當(dāng)這個(gè) Pod 被重新創(chuàng)建出來之后,Kubernetes 會(huì)為它找到同樣編號(hào)的 PVC,掛載這個(gè) PVC 對(duì)應(yīng)的 Volume,從而獲取到以前保存在 Volume 里的數(shù)據(jù)。

    以上就是k8s編排之StatefulSet知識(shí)點(diǎn)詳解二的詳細(xì)內(nèi)容,更多關(guān)于k8s編排StatefulSet的資料請(qǐng)關(guān)注其它相關(guān)文章!

    分享到:
    標(biāo)簽:K8S 服務(wù)器 知識(shí)點(diǎn) 編排 詳解
    用戶無頭像

    網(wǎng)友整理

    注冊(cè)時(shí)間:

    網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

    • 51998

      網(wǎng)站

    • 12

      小程序

    • 1030137

      文章

    • 747

      會(huì)員

    趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
    最新入駐小程序

    數(shù)獨(dú)大挑戰(zhàn)2018-06-03

    數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

    答題星2018-06-03

    您可以通過答題星輕松地創(chuàng)建試卷

    全階人生考試2018-06-03

    各種考試題,題庫,初中,高中,大學(xué)四六

    運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

    記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

    每日養(yǎng)生app2018-06-03

    每日養(yǎng)生,天天健康

    體育訓(xùn)練成績?cè)u(píng)定2018-06-03

    通用課目體育訓(xùn)練成績?cè)u(píng)定