成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Kubernetes 3種存儲傻傻分不清楚!

存儲 存儲軟件
Kubernetes支持幾十種類型的后端存儲卷,其中有幾種存儲卷總是給人一種分不清楚它們之間有什么區別的感覺,尤其是local與hostPath這兩種存儲卷類型,看上去都像是node本地存儲方案嘛。當然,還另有一種volume類型是emptyDir,也有相近之處。

 Kubernetes支持幾十種類型的后端存儲卷,其中有幾種存儲卷總是給人一種分不清楚它們之間有什么區別的感覺,尤其是local與hostPath這兩種存儲卷類型,看上去都像是node本地存儲方案嘛。當然,還另有一種volume類型是emptyDir,也有相近之處。

在Docker容器時代,我們就對Volume很熟悉了,一般來說我們是通過創建Volume數據卷,然后掛載到指定容器的指定路徑下,以實現容器數據的持久化存儲或者是多容器間的數據共享,當然這里說的都是單機版的容器解決方案。

[[252662]]

進入到容器集群時代后,我們看到Kubernetes按時間順序先后提供了emptyDir、hostPath和local的本地磁盤存儲卷解決方案。

emptyDir、hostPath都是Kubernetes很早就實現和支持了的技術,local volume方式則是從k8s v1.7才剛剛發布的alpha版本,目前在k8s v1.10中發布了local volume的beta版本,部分功能在早期版本中并不支持。

在展開之前,我們先討論一個問題,就是既然都已經實現容器云平臺了,我們為什么還要關注這幾款本地存儲卷的貨呢?

粗略歸納了下,有以下幾個原因:

  • 特殊使用場景需求,如需要個臨時存儲空間,運行cAdvisor需要能訪問到node節點/sys/fs/cgroup的數據,做本機單節點的k8s環境功能測試等等。
  • 容器集群只是做小規模部署,滿足開發測試、集成測試需求。
  • 作為分布式存儲服務的一種補充手段,比如我在一臺node主機上插了塊SSD,準備給某個容器吃小灶。
  • 目前主流的兩個容器集群存儲解決方案是ceph和glusterfs,二者都是典型的網絡分布式存儲,所有的數據讀、寫都是對磁盤IO和網絡IO的考驗,所以部署存儲集群時至少要使用萬兆的光纖網卡和光纖交換機。如果你都沒有這些硬貨的話,強上分布式存儲方案的結果就是收獲一個以”慢動作”見長的容器集群啦。
  • 分布式存儲集群服務的規劃、部署和長期的監控、擴容與運行維護是專業性很強的工作,需要有專職的技術人員做長期的技術建設投入。

我們并不是說分布式存儲服務不好,很多公司在云平臺建設的實踐中,往往是需要結合使用幾種通用的與專用的存儲解決方案,才能最終滿足大部分的使用需求。

所以,如果這里有一款場景適合你的話,不妨了解一下這幾款本地存儲卷的功能特點、使用技巧與異同。

1、emptyDir

emptyDir類型的Volume在Pod分配到Node上時被創建,Kubernetes會在Node上自動分配一個目錄,因此無需指定宿主機Node上對應的目錄文件。 這個目錄的初始內容為空,當Pod從Node上移除時,emptyDir中的數據會被***刪除。

注:容器的crashing事件并不會導致emptyDir中的數據被刪除。

***實踐

根據官方給出的***使用實踐的建議,emptyDir可以在以下幾種場景下使用:

  1. apiVersion: v1 
  2. kind: Pod 
  3. metadata: 
  4.  name: test-pod 
  5. spec: 
  6.  containers: 
  7.  - image: busybox 
  8.    name: test-emptydir 
  9.    command: [ "sleep""3600" ] 
  10.    volumeMounts: 
  11.    - mountPath: /data 
  12.      name: data-volume 
  13.  volumes: 
  14.  - name: data-volume 
  15.    emptyDir: {} 

查看下創建出來的pod,這里只截取了與volume有關的部分,其他無關內容直接省略:

  1. # kubectl describe pod test-pod 
  2. Name:         test-pod 
  3. Namespace:    default 
  4. Node:         kube-node2/172.16.10.102 
  5. ...... 
  6.    Environment:    <none> 
  7.    Mounts: 
  8.      /data from data-volume (rw) 
  9. ...... 
  10. Volumes: 
  11.  data-volume: 
  12.    Type:    EmptyDir (a temporary directory that shares a pod's lifetime) 
  13.    Medium: 
  14. ...... 

可以進入到容器中查看下實際的卷掛載結果:

  1. # kubectl exec -it test-pod -c test-emptydir /bin/sh 

2、hostPath

hostPath類型則是映射node文件系統中的文件或者目錄到pod里。在使用hostPath類型的存儲卷時,也可以設置type字段,支持的類型有文件、目錄、File、Socket、CharDevice和BlockDevice。

下面是來自官網對hostPath的使用場景和注意事項的介紹。

使用場景:

  • 當運行的容器需要訪問Docker內部結構時,如使用hostPath映射/var/lib/docker到容器;
  • 當在容器中運行cAdvisor時,可以使用hostPath映射/dev/cgroups到容器中;
  • 注意事項:
  • 配置相同的pod(如通過podTemplate創建),可能在不同的Node上表現不同,因為不同節點上映射的文件內容不同
  • 當Kubernetes增加了資源敏感的調度程序,hostPath使用的資源不會被計算在內
  • 宿主機下創建的目錄只有root有寫權限。你需要讓你的程序運行在privileged container上,或者修改宿主機上的文件權限。

hostPath volume 實驗

下面我們在測試k8s環境中創建一個hostPath volume使用示例。

  1. apiVersion: v1 
  2. kind: Pod 
  3. metadata: 
  4.  name: test-pod2 
  5. spec: 
  6.  containers: 
  7.  - image: busybox 
  8.    name: test-hostpath 
  9.    command: [ "sleep""3600" ] 
  10.    volumeMounts: 
  11.    - mountPath: /test-data 
  12.      name: test-volume 
  13.  volumes: 
  14.  - name: test-volume 
  15.    hostPath: 
  16.      # directory location on host 
  17.      path: /data 
  18.      # this field is optional 
  19.      type: Directory 

查看下pod創建結果,觀察volumes部分:

  1. # kubectl describe pod test-pod2 
  2. Name:         test-pod2 
  3. Namespace:    default 
  4. Node:         kube-node2/172.16.10.102 
  5. ...... 
  6.    Mounts: 
  7.      /test-data from test-volume (rw) 
  8. ...... 
  9. Volumes: 
  10.  test-volume: 
  11.    Type:          HostPath (bare host directory volume) 
  12.    Path:          /data 
  13.    HostPathType:  Directory 
  14. ...... 

我們登錄到容器中,進入掛載的/test-data目錄中,創建個測試文件。

  1. # kubectl exec  -it test-pod2 -c test-hostpath /bin/sh 
  2. / # echo 'testtesttest' > /test-data/test.log 
  3. / # exit 

我們在運行該pod的node節點上,可以看到如下的文件和內容。

  1. [root@kube-node2 test-data]# cat /test-data/test.log 
  2. testtesttest 

現在,我們把該pod刪除掉,再看看node節點上的hostPath使用的目錄與數據會有什么變化。

  1. [root@kube-node1 ~]# kubectl delete pod test-pod2 
  2. pod "test-pod2" deleted 

到運行原pod的node節點上查看如下。

  1. [root@kube-node2 test-data]# ls -l 
  2. total 4 
  3. -rw-r--r-- 1 root root 13 Nov 14 00:25 test.log 
  4. [root@kube-node2 test-data]# cat /test-data/test.log 
  5. testtesttest 

在使用hostPath volume卷時,即便pod已經被刪除了,volume卷中的數據還在!

單節點的k8s本地測試環境與hostPath volume

有時我們需要搭建一個單節點的k8s測試環境,就利用到hostPath作為后端的存儲卷,模擬真實環境提供PV、StorageClass和PVC的管理功能支持。

  1. apiVersion: storage.k8s.io/v1 
  2. kind: StorageClass 
  3. metadata: 
  4.  namespace: kube-system 
  5.  name: standard 
  6.  annotations: 
  7.    storageclass.beta.kubernetes.io/is-default-class: "true" 
  8.  labels: 
  9.    addonmanager.kubernetes.io/mode: Reconcile 
  10. provisioner: kubernetes.io/host-path 
  11. ​ 

該場景僅能用于單節點的k8s測試環境中

3、emptyDir和hostPath在功能上的異同分析

二者都是node節點的本地存儲卷方式;

  • emptyDir可以選擇把數據存到tmpfs類型的本地文件系統中去,hostPath并不支持這一點;
  • hostPath除了支持掛載目錄外,還支持File、Socket、CharDevice和BlockDevice,既支持把已有的文件和目錄掛載到容器中,也提供了“如果文件或目錄不存在,就創建一個”的功能;
  • emptyDir是臨時存儲空間,完全不提供持久化支持;
  • hostPath的卷數據是持久化在node節點的文件系統中的,即便pod已經被刪除了,volume卷中的數據還會留存在node節點上;

4、local volume的概念

這是一個很新的存儲類型,建議在k8s v1.10+以上的版本中使用。該local volume類型目前還只是beta版。

Local volume 允許用戶通過標準PVC接口以簡單且可移植的方式訪問node節點的本地存儲。 PV的定義中需要包含描述節點親和性的信息,k8s系統則使用該信息將容器調度到正確的node節點。

配置要求

  • 使用local-volume插件時,要求使用到了存儲設備名或路徑都相對固定,不會隨著系統重啟或增加、減少磁盤而發生變化。
  • 靜態provisioner配置程序僅支持發現和管理掛載點(對于Filesystem模式存儲卷)或符號鏈接(對于塊設備模式存儲卷)。 對于基于本地目錄的存儲卷,必須將它們通過bind-mounted的方式綁定到發現目錄中。

StorageClass與延遲綁定

官方推薦在使用local volumes時,創建一個StorageClass并把volumeBindingMode字段設置為“WaitForFirstConsumer”。

雖然local volumes還不支持動態的provisioning管理功能,但我們仍然可以創建一個StorageClass并使用延遲卷綁定的功能,將volume binding延遲至pod scheduling階段執行。

這樣可以確保PersistentVolumeClaim綁定策略將Pod可能具有的任何其他node節點約束也進行評估,例如節點資源要求、節點選擇器、Pod親和性和Pod反親和性。

  1. kind: StorageClass 
  2. apiVersion: storage.k8s.io/v1 
  3. metadata: 
  4.  namelocal-storage 
  5. provisioner: kubernetes.io/no-provisioner 
  6. volumeBindingMode: WaitForFirstConsumer  

外部static provisioner

配置local volume后,可以使用一個外部的靜態配置器來幫助簡化本地存儲的管理。 Provisioner 配置程序將通過為每個卷創建和清理PersistentVolumes來管理發現目錄下的卷。

Local storage provisioner要求管理員在每個節點上預配置好local volumes,并指明該local volume是屬于以下哪種類型:

  • Filesystem volumeMode (default) PVs – 需要掛載到發現目錄下面。
  • Block volumeMode PVs – 需要在發現目錄下創建一個指向節點上的塊設備的符號鏈接。

一個local volume,可以是掛載到node本地的磁盤、磁盤分區或目錄。

Local volumes雖然可以支持創建靜態PersistentVolume,但到目前為止仍不支持動態的PV資源管理。

這意味著,你需要自己手動去處理部分PV管理的工作,但考慮到至少省去了在創建pod時手動定義和使用PV的工作,這個功能還是很值得的。

創建基于Local volumes的PV的示例

  1. apiVersion: v1 
  2. kind: PersistentVolume 
  3. metadata: 
  4.  name: example-pv 
  5. spec: 
  6.  capacity: 
  7.    storage: 100Gi 
  8.  volumeMode: Filesystem 
  9.  accessModes: 
  10.  - ReadWriteOnce 
  11.  persistentVolumeReclaimPolicy: Delete 
  12.  storageClassName: local-storage 
  13.  local
  14.    path: /mnt/disks/ssd1 
  15.  nodeAffinity: 
  16.    required: 
  17.      nodeSelectorTerms: 
  18.      - matchExpressions: 
  19.        - key: kubernetes.io/hostname 
  20.          operator: In 
  21.          values
  22.          - example-node 
  23. ​ 
  • nodeAffinity字段是必須配置的,k8s依賴于這個標簽為你定義的Pods在正確的nodes節點上找到需要使用的local volumes。
  • 使用volumeMode字段時,需要啟用BlockVolume 這一Alpha feature特性。
  • volumeMode字段的默認值是Filesystem,但也支持配置為Block,這樣就會把node節點的local volume作為容器的一個裸塊設備掛載使用。

數據安全風險

local volume仍受node節點可用性方面的限制,因此并不適用于所有應用程序。 如果node節點變得不健康,則local volume也將變得不可訪問,使用這個local volume的Pod也將無法運行。 使用local voluems的應用程序必須能夠容忍這種降低的可用性以及潛在的數據丟失,是否會真得導致這個后果將取決于node節點底層磁盤存儲與數據保護的具體實現了。

5、hostPath與local volume在功能上的異同分析

二者都基于node節點本地存儲資源實現了容器內數據的持久化功能,都為某些特殊場景下提供了更為適用的存儲解決方案;

前者時間很久了,所以功能穩定,而后者因為年輕,所以功能的可靠性與穩定性還需要經歷時間和案例的歷練,尤其是對Block設備的支持還只是alpha版本;

二者都為k8s存儲管理提供了PV、PVC和StorageClass的方法實現;

  • local volume實現的StorageClass不具備完整功能,目前只支持卷的延遲綁定;
  • hostPath是單節點的本地存儲卷方案,不提供任何基于node節點親和性的pod調度管理支持;
  • local volume適用于小規模的、多節點的k8s開發或測試環境,尤其是在不具備一套安全、可靠且性能有保證的存儲集群服務時;

6、local volume的安裝配置方法

local-volume項目及地址

https://github.com/kubernetes-incubator/external-storage/tree/master/local-volume

Step 1:配置k8s集群使用本地磁盤存儲

如果使用block塊設備,則需要啟用Alpha的功能特性:k8s v1.10+

  1. $ export KUBE_FEATURE_GATES=”BlockVolume=true” 

注:如果是已經部署好的k8s v1.10+集群,需要為幾個主要組件均開啟對該特性的支持后,才能使用block塊設備功能。如果k8s是低于1.10版本,則還需要啟用其它的幾個功能特性,因為在低版本中這些功能特性還都是alpha版本的。

根據大家搭建k8s的方法的不同,下面提供了四種情況下的配置說明。

  1. Option 1: GCE(Google Compute Engine)集群​​ 

使用kube-up.sh啟動的GCE集群將自動格式化并掛載所請求的Local SSDs,因此您可以使用預先生成的部署規范部署配置器并跳至步驟4,除非您要自定義配置器規范或存儲類。

  1. $ NODE_LOCAL_SSDS_EXT=<n>,<scsi|nvme>,fs cluster/kube-up.sh 
  2. $ kubectl create -f provisioner/deployment/kubernetes/gce/class-local-ssds.yaml 
  3. $ kubectl create -f provisioner/deployment/kubernetes/gce/provisioner_generated_gce_ssd_volumes.yaml 

Option 2: GKE(Google Kubernetes Engine)集群

GKE集群將自動格式化并掛載所請求的Local SSDs。在GKE documentation中有更詳細的說明。

然后,跳至步驟4。

Option 3: 使用裸機環境搭建的集群

1.根據應用程序的使用要求對每個節點上的本地數據磁盤進行分區和格式化。 2.定義一個StorageClass,并在一個發現目錄下掛載所有要使用的存儲文件系統。 發現目錄是在configmap中指定,見下文。 3.如上所述,使用KUBEFEATUREGATES配置Kubernetes API Server, controller-manager, scheduler, 和所有節點上的 kubelets。 4.如果沒有使用默認的Kubernetes調度程序策略,則必須啟用以下特性:

  • Pre-1.9: NoVolumeBindConflict
  • 9+: VolumeBindingChecker

說明:在我們使用測試環境中,是一套3節點的k8s測試環境,為了模擬測試local volume功能,直接結合使用了下面option4中提供的ram disks測試方法,創建了3個tmpfs格式的文件系統掛載資源。

Option 4: 使用一個本機單節點的測試集群

創建/mnt/disks目錄,并在該目錄下掛載幾個子目錄。下面是使用三個ram disks做一個真實存儲卷的模擬測試。

  1. $ mkdir /mnt/fast-disks 
  2. for vol in vol1 vol2 vol3; 
  3. do 
  4.    mkdir -p /mnt/fast-disks/$vol 
  5.    mount -t tmpfs $vol /mnt/fast-disks/$vol 
  6. done 

(2)創建單機k8s本地測試集群

  1. $ ALLOW_PRIVILEGED=true LOG_LEVEL=5 FEATURE_GATES=$KUBE_FEATURE_GATES hack/local-up-cluster.sh​​ 

Step 2: 創建一個StorageClass (1.9+)

要延遲卷綁定直到pod調度并處理單個pod中的多個本地PV,必須創建StorageClass并將volumeBindingMode設置為WaitForFirstConsumer。

  1. Only create this for K8s 1.9+ 
  2. apiVersion: storage.k8s.io/v1 
  3. kind: StorageClass 
  4. metadata: 
  5.  name: fast-disks 
  6. provisioner: kubernetes.io/no-provisioner 
  7. volumeBindingMode: WaitForFirstConsumer 
  8. # Supported policies: Delete, Retain 
  9. reclaimPolicy: Delete 
  10. $ kubectl create -f provisioner/deployment/kubernetes/example/default_example_storageclass.yaml 
  11. ​ 

yaml文件請到local volume項目文件中查找需要使用的yaml文件

Step 3: 創建local persistent volumes

Option 1: local volume static provisioner 方式

配置一個外部的靜態配置器。

(1)生成Provisioner的ServiceAccount,Roles,DaemonSet和ConfigMap規范,并對其進行自定義配置。

此步驟使用helm模板生成需要的配置規格。 有關設置說明,請參閱helm README。

使用默認值生成Provisioner的配置規格,請運行:

helm template ./helm/provisioner > ./provisioner/deployment/kubernetes/provisioner_generated.yaml

這里是將模板經過渲染后得到最終使用的各項資源定義文件。 如果是使用自定義的配置文件的話:

  1. helm template ./helm/provisioner --values custom-values.yaml > ./provisioner/deployment/kubernetes/provisioner_generated.yaml​​ 

(2)部署Provisioner

如果用戶對Provisioner的yaml文件的內容感到滿意,就可以使用kubectl創建Provisioner的DaemonSet和ConfigMap了。

  1. # kubectl create -f ./provisioner/deployment/kubernetes/provisioner_generated.yaml 
  2. configmap "local-provisioner-config" created 
  3. daemonset.extensions "local-volume-provisioner" created 
  4. serviceaccount "local-storage-admin" created 
  5. clusterrolebinding.rbac.authorization.k8s.io "local-storage-provisioner-pv-binding" created 
  6. clusterrole.rbac.authorization.k8s.io "local-storage-provisioner-node-clusterrole" created 
  7. clusterrolebinding.rbac.authorization.k8s.io "local-storage-provisioner-node-binding" created 

(3)檢查已自動發現的local volumes

一旦啟動,外部static provisioner將發現并自動創建出 local-volume PVs。

我們查看下上面測試中創建出的PVs有哪些:

  1. # kubectl get pv 
  2. NAME                CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM     STORAGECLASS   REASON    AGE 
  3. local-pv-436f0527   495Mi      RWO            Delete           Available             fast-disks               2m 
  4. local-pv-77a4ffb0   495Mi      RWO            Delete           Available             fast-disks               2m 
  5. local-pv-97f7ec5c   495Mi      RWO            Delete           Available             fast-disks               2m 
  6. local-pv-9f0ddba3   495Mi      RWO            Delete           Available             fast-disks               2m 
  7. local-pv-a0dfdc91   495Mi      RWO            Delete           Available             fast-disks               2m 
  8. local-pv-a52333e3   495Mi      RWO            Delete           Available             fast-disks               2m 
  9. local-pv-bed86926   495Mi      RWO            Delete           Available             fast-disks               2m 
  10. local-pv-d037a0d1   495Mi      RWO            Delete           Available             fast-disks               2m 
  11. local-pv-d26c3252   495Mi      RWO            Delete           Available             fast-disks               2m 
  12. ​ 

因為是有3個node節點,每個上面的/mnt/fast-disks自動發現目錄下掛載了3個文件系統,所以這里查詢的結果是生成了9個PVs

查看某一個PV的詳細描述信息:

  1. # kubectl describe pv local-pv-436f0527 
  2. Name:              local-pv-436f0527 
  3. Labels:            <none> 
  4. Annotations:       pv.kubernetes.io/provisioned-by=local-volume-provisioner-kube-node2-c3733876-b56f-11e8-990b-080027395360 
  5. Finalizers:        [kubernetes.io/pv-protection] 
  6. StorageClass:      fast-disks 
  7. Status:            Available 
  8. Claim:             
  9. Reclaim Policy:    Delete 
  10. Access Modes:      RWO 
  11. Capacity:          495Mi 
  12. Node Affinity:     
  13.  Required Terms:   
  14.    Term 0:        kubernetes.io/hostname in [kube-node2] 
  15. Message:           
  16. Source: 
  17.    Type:  LocalVolume (a persistent volume backed by local storage on a node) 
  18.    Path:  /mnt/fast-disks/vol2 
  19. Events:    <none> 
  20. ​ 

此時就可以直接通過引用名為fast-disks的storageClassName名稱來聲明使用上述PV并將其綁定到PVC。

Option 2: 手動創建 local persistent volume

參照前文介紹local volume概念的章節中已經講解過的PersistentVolume使用示例。

Step 4: 創建 local persistent volume claim

  1. kind: PersistentVolumeClaim 
  2. apiVersion: v1 
  3. metadata: 
  4.  name: example-local-claim 
  5. spec: 
  6.  accessModes: 
  7.  - ReadWriteOnce 
  8.  resources: 
  9.    requests: 
  10.      storage: 50Mi 
  11.  storageClassName: fast-disks 
  12. ​ 

請在使用時替換為您實際的存儲容量需求和storageClassName值。

  1. # kubectl create -f local-pvc.yaml 
  2. persistentvolumeclaim "example-local-claim" created 
  3. # kubectl get pvc 
  4. NAME                  STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE 
  5. example-local-claim   Pending     
  6. # kubectl describe pvc example-local-claim 
  7. Name:          example-local-claim 
  8. Namespace:     default 
  9. StorageClass:  fast-disks 
  10. Status:        Pending 
  11. Volume:         
  12. Labels:        <none> 
  13. Annotations:   <none> 
  14. Finalizers:    [kubernetes.io/pvc-protection] 
  15. Capacity:       
  16. Access Modes:   
  17. Events: 
  18.  Type    Reason                Age               From                         Message 
  19.  ----    ------                ----              ----                         ------- 
  20. ​ 

Normal WaitForFirstConsumer 6s (x6 over 59s) persistentvolume-controller waiting for first consumer to be created before binding

我們可以看到存儲卷延遲綁定的效果,在綁定到容器前,該PVC的狀態會是pending

Step 5:創建一個測試Pod并引用上面創建的PVC

  1. apiVersion: v1 
  2. kind: Pod 
  3. metadata: 
  4.  namelocal-pvc-pod 
  5. spec: 
  6.  containers: 
  7.  - image: busybox 
  8.    name: test-local-pvc 
  9.    command: [ "sleep""3600" ] 
  10.    volumeMounts: 
  11.    - mountPath: /data 
  12.      name: data-volume 
  13.  volumes: 
  14.  - name: data-volume 
  15.    persistentVolumeClaim: 
  16.      claimName: example-local-claim 
  17. ​ 

創建并查看:

  1. # kubectl create -f example-local-pvc-pod.yaml 
  2. pod "local-pvc-pod" created 
  3. # kubectl get pods -o wide 
  4. NAME                             READY     STATUS    RESTARTS   AGE       IP            NODE 
  5. client1                          1/1       Running   67         64d       172.30.80.2   kube-node3 
  6. local-pvc-pod                    1/1       Running   0          2m        172.30.48.6   kube-node1 
  7. ​ 

查看pod中容器掛載PVC的配置詳情,這里只截取了部分信息:

  1. # kubectl describe pod local-pvc-pod 
  2. Name:         local-pvc-pod 
  3. Namespace:    default 
  4. Node:         kube-node1/172.16.10.101 
  5. Start Time:   Thu, 15 Nov 2018 16:39:30 +0800 
  6. Labels:       <none> 
  7. Annotations:  <none> 
  8. Status:       Running 
  9. IP:           172.30.48.6 
  10. Containers: 
  11.  test-local-pvc: 
  12. ...... 
  13.    Mounts: 
  14.      /data from data-volume (rw) 
  15.      /var/run/secrets/kubernetes.io/serviceaccount from default-token-qkhcf (ro) 
  16. Conditions: 
  17.  Type           Status 
  18.  Initialized    True 
  19.  Ready          True 
  20.  PodScheduled   True 
  21. Volumes: 
  22.  data-volume: 
  23.    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) 
  24.    ClaimName:  example-local-claim 
  25.    ReadOnly:   false 
  26. ...... 
  27. [root@kube-node1 ~]# kubectl exec -it local-pvc-pod -c test-local-pvc /bin/sh 
  28. / # ls 
  29. bin   data  dev   etc   home  proc  root  sys   tmp   usr   var 
  30. / # df -h 
  31. Filesystem                Size      Used Available Use% Mounted on 
  32. overlay                  41.0G      8.1G     32.8G  20% / 
  33. tmpfs                    64.0M         0     64.0M   0% /dev 
  34. tmpfs                   495.8M         0    495.8M   0% /sys/fs/cgroup 
  35. vol3                    495.8M         0    495.8M   0% /data 
  36. ​ 

再回過頭來看下PVC的狀態,已經變成了Bound:

  1. # kubectl get pvc 
  2. NAME                        STATUS    VOLUME              CAPACITY   ACCESS MODES   STORAGECLASS   AGE 
  3. example-local-claim         Bound     local-pv-a0dfdc91   495Mi      RWO            fast-disks     1h 
  4. ​ 

7、一個關于local volume功能局限性問題的討論

在上面的實驗過程中不知道大家有沒有發現一處問題,就是我們在定義PVC時是指定的申請50Mi的空間,而實際掛載到測試容器上的存儲空間是495.8M,剛好是我們在某個node節點上掛載的一個文件系統的全部空間。

為什么會這樣呢?這就是我們所使用的這個local persistent volume外部靜態配置器的功能局限性所在了。它不支持動態的PV空間申請管理。

也就是說,雖然通過這個靜態PV配置器,我們省去了手寫PV YAML文件的痛苦,但仍然需要手工處理這項工作:

  • 手工維護在ConfigMap中指定的自動發現目錄下掛載的文件系統資源,或者是block設備的符號鏈接;
  • 我們需要對能夠使用的本地存儲資源提前做一個全局的規劃,然后劃分為各種尺寸的卷后掛載到自動發現目錄下,當然了只要是還有空閑存儲資源,現有現掛載也是可以的。

那如果以前給某容器分配的一個存儲空間不夠用了怎么辦?

給大家的一個建議是使用Linux下的LVM(邏輯分區管理)來管理每個node節點上的本地磁盤存儲空間。

  • 創建一個大的VG分組,把一個node節點上可以使用的存儲空間都放進去;
  • 按未來一段時間內的容器存儲空間使用預期,提前批量創建出一部分邏輯卷LVs,都掛載到自動發現目錄下去;
  • 不要把VG中的存儲資源全部用盡,預留少部分用于未來給個別容器擴容存儲空間的資源;
  • 使用lvextend為特定容器使用的存儲卷進行擴容;

8、如果容器需要使用block塊設備怎么配置

有幾點會與上面的配置方法上不同。

首先,是要在k8s主要的組件上均開啟用于支持block塊設備的特性。

  1. KUBE_FEATURE_GATES="BlockVolume=true"​​ 

其次是,定義一個”Block”類型的volumeMode PVC,為容器申請一個”Block”類型的PV。

  1. kind: PersistentVolumeClaim 
  2. apiVersion: v1 
  3. metadata: 
  4.  name: example-block-local-claim 
  5. spec: 
  6.  accessModes: 
  7.  - ReadWriteOnce 
  8.  resources: 
  9.    requests: 
  10.      storage: 50Mi 
  11.  volumeMode: Block 
  12.  storageClassName: fast-disks 
  13. ​ 

9、Local volumes的***實踐

  • 為了更好的IO隔離效果,建議將一整塊磁盤作為一個存儲卷使用;
  • 為了得到存儲空間的隔離,建議為每個存儲卷使用一個獨立的磁盤分區;
  • 在仍然存在指定了某個node節點的親和性關系的舊PV時,要避免重新創建具有相同節點名稱的node節點。 否則,系統可能會認為新節點包含舊的PV。
  • 對于具有文件系統的存儲卷,建議在fstab條目和該卷的mount安裝點的目錄名中使用它們的UUID(例如ls -l /dev/disk/by-uuid的輸出)。 這種做法可確保不會安裝錯誤的本地卷,即使其設備路徑發生了更改(例如,如果/dev/sda1在添加新磁盤時變為/dev/sdb1)。 此外,這種做法將確保如果創建了具有相同名稱的另一個節點時,該節點上的任何卷仍然都會是唯一的,而不會被誤認為是具有相同名稱的另一個節點上的卷。
  • 對于沒有文件系統的原始塊存儲卷,請使用其唯一ID作為符號鏈接的名稱。 根據您的環境,/dev/disk/by-id/中的卷ID可能包含唯一的硬件序列號。 否則,應自行生成一個唯一ID。 符號鏈接名稱的唯一性將確保如果創建了另一個具有相同名稱的節點,則該節點上的任何卷都仍然是唯一的,而不會被誤認為是具有相同名稱的另一個節點上的卷。

10、停用local volume的方法

當您想要停用本地卷時,這是一個可能的工作流程。

  • 關閉使用這些卷的Pods;
  • 從node節點上移除local volumes(比如unmounting, 拔出磁盤等等);
  • 手動刪除相應的PVCs對象;
  • Provisioner將嘗試清理卷,但會由于卷不再存在而失敗;
  • 手動刪除相應的PVs對象。 注:以上工作也是拜我們所使用的外部靜態配置器所賜。

參考資料:

https://blog.csdn.net/watermelonbig/article/details/84108424

https://github.com/kubernetes-incubator/external-storage/tree/master/local-volume https://kubernetes.io/docs/concepts/storage/volumes/

責任編輯:武曉燕 來源: K8S中文社區
相關推薦

2021-03-10 08:56:37

Zookeeper

2024-02-29 09:08:56

Encoding算法加密

2021-02-08 23:47:51

文件存儲塊存儲對象存儲

2022-05-15 21:52:04

typeTypeScriptinterface

2021-07-27 07:31:16

JavaArrayList數組

2020-10-30 08:20:04

SD卡TF卡存儲

2023-09-03 21:18:07

Python編程語言

2018-05-22 16:24:20

HashMapJavaJDK

2020-03-03 17:35:09

Full GCMinor

2023-02-27 15:46:19

數據元元數據

2016-11-04 12:51:46

Unix網絡IO 模型

2021-11-09 06:01:35

前端JITAOT

2022-02-25 09:14:33

類變量共享實例變量

2024-11-04 00:00:03

viewportDOMSPA

2025-05-12 08:40:00

前端監控DOM

2020-11-11 07:32:18

MySQL InnoDB 存儲

2023-04-11 15:57:49

JavaScriptCSSHTML

2021-01-13 08:10:26

接口IEnumeratorIEnumerable

2019-11-21 14:22:12

WiFiWLAN區別

2021-02-14 22:33:23

Java字符字段
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久国产三级 | 亚洲精品18 | 久久小视频 | 亚洲精品乱码久久久久久按摩 | 亚洲国产激情 | 亚洲欧美国产毛片在线 | 99精品免费| 国产欧美精品一区二区三区 | 亚洲欧美一区二区三区在线 | 日韩中文一区 | 99亚洲综合| av中文字幕在线观看 | 91 中文字幕 | 婷婷丁香在线视频 | 久久精品亚洲精品国产欧美 | 中文字幕日韩欧美 | 国产精品日韩欧美一区二区 | 天天爽夜夜操 | 国产欧美日韩一区 | 久久国产精品免费一区二区三区 | 1区2区3区视频 | 亚洲区一区二 | 蜜桃在线视频 | 国产成人免费视频网站视频社区 | 一区天堂| 日韩精品免费在线 | 天天草狠狠干 | 久久精品亚洲精品国产欧美 | 国产成人一区二区 | 亚洲精品在线免费播放 | 欧美精品啪啪 | 在线视频中文字幕 | 国产精品亚洲成在人线 | 国产精品精品久久久久久 | 欧美国产日韩在线 | 国产精品久久久精品 | 一级做a| 81精品国产乱码久久久久久 | 中国一级特黄毛片大片 | 中文字幕在线一区二区三区 | 国产网站在线免费观看 |