成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

kubernetes中的local persistent volume

Zhuxy / 1714人閱讀

摘要:的詳細(xì)內(nèi)容如下當(dāng)然,也可以不使用,而是手動創(chuàng)建。前是將作為記錄到中,起將其獨立為一個字段接下來可以創(chuàng)建各種,記得要在的模板中聲明。注意到這里是,即我們一開始創(chuàng)建的實例的名字。為表示中申明的未的,在集群內(nèi)的中找不到可以匹配的。

什么是Local Persistent Volumes

在kubernetes 1.14版本中, Local Persistent Volumes(以下簡稱LPV)已變?yōu)檎桨姹荆℅A),LPV的概念在1.7中被首次提出(alpha),并在1.10版本中升級到beat版本?,F(xiàn)在用戶終于可以在生產(chǎn)環(huán)境中使用LPV的功能和API了。

首先:Local Persistent Volumes代表了直接綁定在計算節(jié)點上的一塊本地磁盤。

kubernetes提供了一套卷插件(volume plugin)標(biāo)準(zhǔn),使得k8s集群的工作負(fù)載可以使用多種塊存儲和文件存儲。大部分磁盤插件都使用了遠(yuǎn)程存儲,這是為了讓持久化的數(shù)據(jù)與計算節(jié)點彼此獨立,但遠(yuǎn)程存儲通常無法提供本地存儲那么強(qiáng)的讀寫性能。有了LPV 插件,kubernetes負(fù)載現(xiàn)在可以用同樣的volume api,在容器中使用本地磁盤。

這跟hostPath有什么區(qū)別

hostPath是一種volume,可以讓pod掛載宿主機(jī)上的一個文件或目錄(如果掛載路徑不存在,則創(chuàng)建為目錄或文件并掛載)。

最大的不同在于調(diào)度器是否能理解磁盤和node的對應(yīng)關(guān)系,一個使用hostPath的pod,當(dāng)他被重新調(diào)度時,很有可能被調(diào)度到與原先不同的node上,這就導(dǎo)致pod內(nèi)數(shù)據(jù)丟失了。而使用LPV的pod,總會被調(diào)度到同一個node上(否則就調(diào)度失敗)。

如何使用LPV

首先 需要創(chuàng)建StorageClass

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

注意到這里volumeBindingMode字段的值是WaitForFirstConsumer。這種bindingmode意味著:

kubernetes的pv控制器會將這類pv的binding延遲,直到有一個使用了對應(yīng)pvc的pod被創(chuàng)建出來且該pod被調(diào)度完畢。這時候才會將pv和pvc進(jìn)行binding,并且這時候pv的選擇會結(jié)合調(diào)度的node和pv的nodeaffinity。

接下來,提前準(zhǔn)備好的provisioner會動態(tài)創(chuàng)建PV。

$ kubectl get pv
NAME                CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM  STORAGECLASS   REASON      AGE
local-pv-27c0f084   368Gi      RWO            Delete           Available          local-storage              8s
local-pv-3796b049   368Gi      RWO            Delete           Available          local-storage              7s
local-pv-3ddecaea   368Gi      RWO            Delete           Available          local-storage              7s

LPV的詳細(xì)內(nèi)容如下:

$ kubectl describe pv local-pv-ce05be60 
Name:        local-pv-ce05be60
Labels:        
Annotations:    pv.kubernetes.io/provisioned-by=local-volume-provisioner-minikube-18f57fb2-a186-11e7-b543-080027d51893
StorageClass:    local-fast
Status:        Available
Claim:        
Reclaim Policy:    Delete
Access Modes:    RWO
Capacity:    1024220Ki
NodeAffinity:
  Required Terms:
      Term 0:  kubernetes.io/hostname in [my-node]
Message:    
Source:
    Type:    LocalVolume (a persistent volume backed by local storage on a node)
    Path:    /mnt/disks/vol1
Events:        

當(dāng)然,也可以不使用provisioner,而是手動創(chuàng)建PV。但是必須要注意的是,LPV必須要填寫nodeAffinity。 (1.10前k8s是將nodeAffinity作為annotation記錄到PV中,1.10起將其獨立為一個字段)

apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pv
spec:
  capacity:
    storage: 100Gi
  # volumeMode field requires BlockVolume Alpha feature gate to be enabled.
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete
  storageClassName: local-storage
  local:
    path: /mnt/disks/ssd1
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - example-node

接下來可以創(chuàng)建各種workload,記得要在workload的模板中聲明volumeClaimTemplates。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: local-test
spec:
  serviceName: "local-service"
  replicas: 3
  selector:
    matchLabels:
      app: local-test
  template:
    metadata:
      labels:
        app: local-test
    spec:
      containers:
      - name: test-container
        image: k8s.gcr.io/busybox
        command:
        - "/bin/sh"
        args:
        - "-c"
        - "sleep 100000"
        volumeMounts:
        - name: local-vol
          mountPath: /usr/test-pod
  volumeClaimTemplates:
  - metadata:
      name: local-vol
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "local-storage"
      resources:
        requests:
          storage: 368Gi

注意到這里volumeClaimTemplates.spec.storageClassNamelocal-storage,即我們一開始創(chuàng)建的storageclass實例的名字。

使用LPV的pod的調(diào)度流程

上面這個statefulset創(chuàng)建后,控制器會為其創(chuàng)建對應(yīng)的PVC,并且會為PVC查找符合條件的PV,但是由于我們在local-storage中配置了WaitForFirstConsumer,所以控制器不會處理pvc和pv的bind;

同時,調(diào)度器在調(diào)度該pod時,predicate算法中也會根據(jù)PVC的要求去找到可用的PV,并且會過濾掉“與LPV的affinity”不匹配的node。最終,調(diào)度器發(fā)現(xiàn):

pv:example-pv滿足了pvc的要求;

node:example-node滿足了pv:example-pv的nodeAffinity要求。

于是乎調(diào)度器嘗試將pv和pvc bind起來,并且對pod進(jìn)行重新調(diào)度。

重新調(diào)度pod時調(diào)度器發(fā)現(xiàn)pod的pvc資源得到了滿足(都bound了pv),且bound的pv的nodeAffinity與node:example-node匹配。于是將pod調(diào)度到node:example-node上。完成調(diào)度。

如何創(chuàng)建LPV

在機(jī)器上創(chuàng)建目錄: mkdir -p /mnt/disks/ssd1

在機(jī)器上執(zhí)行命令,將某個卷掛載到該目錄:mount -t /dev/vdc /mnt/disks/ssd1

在集群中創(chuàng)建對應(yīng)的storageClass. 參見上文。

手動創(chuàng)建本地卷的PV,或者通過provisioner去自動創(chuàng)建。手動創(chuàng)建的模板見上文。

如何刪除LPV

對于已經(jīng)被bind并被pod使用的LPV,刪除一定要按照流程來 , 要不然會刪除失?。?/p>

刪除使用這個pv的pod

從node上移除這個磁盤(按照一個pv一塊盤)

刪除pvc

刪除pv

LPV延遲綁定部分的代碼解讀

所有的關(guān)鍵在于volumeBinder這個結(jié)構(gòu),它繼承了SchedulerVolumeBinder接口,包括:

type SchedulerVolumeBinder interface {
    FindPodVolumes(pod *v1.Pod, node *v1.Node) 
    AssumePodVolumes(assumedPod *v1.Pod, nodeName string) 
    BindPodVolumes(assumedPod *v1.Pod) error
    GetBindingsCache() PodBindingCache
}
FindPodVolumes

了解調(diào)度器原理的應(yīng)該知道,調(diào)度器的predicate算法,在調(diào)度pod時,會逐個node的去進(jìn)行predicate,以確認(rèn)這個node是否可以調(diào)度。我們稱之為預(yù)選階段。

VolumeBindingChecker 是一個檢查器,在調(diào)度器的算法工廠初始化的最后一步,會向工廠中注冊檢查算法,這樣調(diào)度器在進(jìn)行predicate時,最后一步會執(zhí)行對volumeBinding的檢查。我們看func (c *VolumeBindingChecker) predicate 方法就能看到,這里面執(zhí)行了FindPodVolumes,并且判斷返回的幾個值是否為true,或err是否為空:

unboundSatisfied, boundSatisfied, err := c.binder.Binder.FindPodVolumes(pod, node)

boundSatisfied 為false表示pod綁定的pv 與當(dāng)前計算的node親和性不過關(guān)。
unboundSatisfied 為false表示pod中申明的未bound的pvc,在集群內(nèi)的pv中找不到可以匹配的。

就這樣,調(diào)度器會反復(fù)去重試調(diào)度,反復(fù)執(zhí)行FindPodVolumes,直到我們(或者provisoner)創(chuàng)建出了PV,比如這時新建的PV,其nodeAffinity對應(yīng)到了node A。這次調(diào)度,在對node A進(jìn)行predicate計算時,發(fā)現(xiàn)pod中申明的、未bound的pvc,在集群中有合適的pv,且該pv的nodeAffinity就是node A,于是返回的unboundSatisfied為 true, 調(diào)度器最終找到了一個合適的node。

那么,調(diào)度器接下來要對pod執(zhí)行assume,在對pod assume之前,調(diào)度器要先對pod中bind的volume進(jìn)行assume。見func (sched *Scheduler) assumeAndBindVolumes(assumed *v1.Pod, host string) error 。這個函數(shù)里,我們調(diào)用了volumeBinderAssumePodVolumes方法。

AssumePodVolumes

assume是假設(shè)的意思,顧名思義,這個方法會先在調(diào)度器的緩存中,假定pod已經(jīng)調(diào)度到node A上,對緩存中的pv、pvc、binding等資源進(jìn)行更新,看是否能成功,它會返回一些訊息:

allBound, bindingRequired, err := sched.config.VolumeBinder.Binder.AssumePodVolumes(assumed, host)

allBound 為true表示所有的pv、pvc,在緩存中已經(jīng)是bind。如果為false,會最終導(dǎo)致本次調(diào)度失敗。
bindingRequired 為true表示有一些pv需要和pvc bind起來。如果為true,調(diào)度器會向volumeBinderBindQueue中寫入一個用例。這個隊列會被一個worker輪詢,并進(jìn)行對應(yīng)的工作。

什么工作呢? BindPodVolumes

BindPodVolumes

調(diào)度器在Run起來的時候,會啟動一個協(xié)程,反復(fù)執(zhí)行bindVolumesWorker。在這個worker中我們可以看到,他嘗試從volumeBinderBindQueue中取出任務(wù),進(jìn)行BindPodVolumes,成功則該任務(wù)Done,失敗則報錯重試。

閱讀BindPodVolumes這個方法,很簡單,從緩存中找到對應(yīng)的pod、pv、pvc等內(nèi)容,更新到APIserver中。

由于我們在AssumePodVolumes中已經(jīng)更新了緩存,所以這里更新到apiserver的操作,會真正地將pv和pvc bind起來。

之后呢?

在worker中我們看到,如果BindPodVolumes成功,依然會構(gòu)造一個pod調(diào)度失敗的事件,并更新pod的狀態(tài)為PodScheduled,這么做是為了將pod放回調(diào)度隊列,讓調(diào)度器再去調(diào)度一次。

我們假設(shè)pod中只申明了一個LPV,在剛剛描述的這次BindPodVolumes操作中已經(jīng)在apiserver中對這個LPV,和pod中的pvc進(jìn)行了bind。那么,下一次調(diào)度器調(diào)度pod時,在AssumePodVolumes時會發(fā)現(xiàn)已經(jīng)allBound ,調(diào)度器會繼續(xù)后續(xù)的操作,最終pod被成功地調(diào)度(創(chuàng)建出Binding資源,apiserver將pod的nodeName更新)。

pv控制器不管嗎?

創(chuàng)建PVC后,pv控制器會有一個worker:syncUnboundClaim去管理未bind的pvc。這個worker中,對于spec.VolumeName不為空的pvc,會去進(jìn)行bind操作,確保pv和pvc綁定起來;對于spec.VolumeName為空的pvc,會去檢查是否延遲綁定,并查找集群中適合該pvc的pv(這里沒有node的概念,所以在查找時更多地是根據(jù)selector和AccessModes去過濾)??梢栽?/p>

func findMatchingVolume(
    claim *v1.PersistentVolumeClaim,
    volumes []*v1.PersistentVolume,
    node *v1.Node,
    excludedVolumes map[string]*v1.PersistentVolume,
    delayBinding bool) (*v1.PersistentVolume, error)

中找到過濾的邏輯。這里我們只要知道:對于延遲綁定的pvc,我們會過濾掉所有的pv,并最后發(fā)出一個WaitForFirstConsumer的event結(jié)束worker。

可見,pv控制器對于延遲調(diào)度的pvc放任自流了。我們在findMatchingVolume方法中也可以看到官方的一段注釋:

if node == nil && delayBinding {
    // PV controller does not bind this claim.
    // Scheduler will handle binding unbound volumes
    // Scheduler path will have node != nil
    continue
}
總結(jié)本地盤的使用流程

待補(bǔ)充: pv控制器、CSI的工作機(jī)制

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/33183.html

相關(guān)文章

  • 深入淺出聊聊Kubernetes存儲(二):搞定持久化存儲

    摘要:這與不同,因為將繼續(xù)存在于系統(tǒng)中,直到用戶刪除它。和持久卷聲明之間很容易弄混淆。該在直接和使用前必須已經(jīng)存在。這對于需要持久化儲存但只有本地卷可用的工作負(fù)載,這非常有用。此外,由于缺少,會失去使用自動伸縮的能力。 showImg(https://segmentfault.com/img/remote/1460000017071596?w=1920&h=1080); 回 顧 在本系列...

    韓冰 評論0 收藏0
  • Kubernetes 1.14 正式發(fā)布,Windows節(jié)點生產(chǎn)級支持!

    摘要:此次新版的最重大更新無疑為對節(jié)點的生產(chǎn)級支持。持久化本地存儲的最主要用例是分布式文件系統(tǒng)和數(shù)據(jù)庫,主要是由于性能和成本的原因。在裸機(jī)上,除了性能之外,本地存儲通常也更便宜,并且使用它是配置分布式文件系統(tǒng)的必要條件。 Kubernetes 1.14現(xiàn)已正式發(fā)布,這是Kubernetes在2019年的首次更新! Kubernetes 1.14由31個增強(qiáng)功能組成:10個功能現(xiàn)進(jìn)入Stabl...

    wean 評論0 收藏0
  • 通過一個例子學(xué)習(xí)Kubernetes里的PersistentVolumeClaim的用法

    摘要:的本身是無狀態(tài)的生命周期通常比較短,只要出現(xiàn)了異常,就會自動創(chuàng)建一個新的來代替它。為了實現(xiàn)內(nèi)數(shù)據(jù)的存儲管理,引入了兩個資源持久卷,以下簡稱和持久卷申請,以下簡稱。跟里的卷類似,不過會有獨立于的生命周期。 Kubernetes的pod本身是無狀態(tài)的(stateless),生命周期通常比較短,只要出現(xiàn)了異常,Kubernetes就會自動創(chuàng)建一個新的Pod來代替它。 而容器產(chǎn)生的數(shù)據(jù),會隨著...

    mindwind 評論0 收藏0
  • 通過一個例子學(xué)習(xí)Kubernetes里的PersistentVolumeClaim的用法

    摘要:的本身是無狀態(tài)的生命周期通常比較短,只要出現(xiàn)了異常,就會自動創(chuàng)建一個新的來代替它。為了實現(xiàn)內(nèi)數(shù)據(jù)的存儲管理,引入了兩個資源持久卷,以下簡稱和持久卷申請,以下簡稱。跟里的卷類似,不過會有獨立于的生命周期。 Kubernetes的pod本身是無狀態(tài)的(stateless),生命周期通常比較短,只要出現(xiàn)了異常,Kubernetes就會自動創(chuàng)建一個新的Pod來代替它。 而容器產(chǎn)生的數(shù)據(jù),會隨著...

    Rindia 評論0 收藏0
  • 通過一個例子學(xué)習(xí)Kubernetes里的PersistentVolumeClaim的用法

    摘要:的本身是無狀態(tài)的生命周期通常比較短,只要出現(xiàn)了異常,就會自動創(chuàng)建一個新的來代替它。為了實現(xiàn)內(nèi)數(shù)據(jù)的存儲管理,引入了兩個資源持久卷,以下簡稱和持久卷申請,以下簡稱。跟里的卷類似,不過會有獨立于的生命周期。 Kubernetes的pod本身是無狀態(tài)的(stateless),生命周期通常比較短,只要出現(xiàn)了異常,Kubernetes就會自動創(chuàng)建一個新的Pod來代替它。 而容器產(chǎn)生的數(shù)據(jù),會隨著...

    Bamboy 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<