1. 程式人生 > >Kubernetes-儲存卷Volume

Kubernetes-儲存卷Volume

1、儲存卷概述

由於容器本身是非持久化的,因此需要解決在容器中執行應用程式遇到的一些問題。首先,當容器崩潰時,kubelet將重新啟動容器,但是寫入容器的檔案將會丟失,容器將會以映象的初始狀態重新開始;第二,在通過一個Pod中一起執行的容器,通常需要共享容器之間一些檔案。Kubernetes通過儲存卷解決上述的兩個問題。

在Docker有儲存卷的概念卷,但Docker中儲存卷只是磁碟的或另一個容器中的目錄,並沒有對其生命週期進行管理。Kubernetes的儲存卷有自己的生命週期,它的生命週期與使用的它Pod生命週期一致。因此,相比於在Pod中執行的容器來說,儲存卷的存在時間會比的其中的任何容器都長,並且在容器重新啟動時會保留資料。當然,當Pod停止存在時,儲存卷也將不再存在。在Kubernetes支援多種型別的卷,而Pod可以同時使用各種型別和任意數量的儲存卷。在Pod中通過指定下面的欄位來使用儲存卷:

  • spec.volumes:通過此欄位提供指定的儲存卷
  • spec.containers.volumeMounts:通過此欄位將儲存卷掛接到容器中

2、儲存卷型別和示例

當前Kubernetes支援如下所列這些儲存卷型別,並以hostPath、nfs和persistentVolumeClaim型別的儲存卷為例,介紹如何定義儲存卷,以及如何在Pod中被使用。

  • awsElasticBlockStore
  • azureDisk
  • azureFile
  • cephfs
  • configMap
  • csi
  • downwardAPI
  • emptyDir
  • fc (fibre channel)
  • flocker
  • gcePersistentDisk
  • gitRepo
  • glusterfs
  • hostPath
  • iscsi
  • local
  • nfs
  • persistentVolumeClaim
  • projected
  • portworxVolume
  • quobyte
  • rbd
  • scaleIO
  • secret
  • storageos
  • vsphereVolume

2.1 hostPath

hostPath型別的儲存卷用於將宿主機的檔案系統的檔案或目錄掛接到Pod中,除了需要指定path欄位之外,在使用hostPath型別的儲存卷時,也可以設定type,type支援的列舉值由下表。另外在使用hostPath時,需要注意下面的事項:

  • 具有相同配置的Pod(例如:從同一個podTemplate建立的),可能會由於Node的檔案不同,而行為不同。
  • 在宿主機上建立的檔案或目錄,只有root使用者具寫入的許可權。您要麼在容器中以root身份執行程序,要麼在主機上修改的檔案或目錄的許可權,以便具備寫入內容到hostPath的儲存卷中。
行為
空字串(預設)是用於向後相容,這意味著在掛接主機路徑儲存卷之前不執行任何檢查。
DirectoryOrCreate如果path指定目錄不存在,則會在宿主機上建立一個新的目錄,並設定目錄許可權為0755,此目錄與kubelet擁有一樣的組和擁有者。
Directorypath指定的目標必需存在
FileOrCreate如果path指定的檔案不存在,則會在宿主機上建立一個空的檔案,設定許可權為0644,此檔案與kubelet擁有一樣的組和擁有者。
Filepath指定的檔案必需存在
Socketpath指定的UNIX socket必需存在
CharDevicepath指定的字元裝置必需存在
BlockDevice在path給定路徑上必須存在塊裝置。

下面是使用hostPath作為儲存卷的YAML檔案,此YAML檔案定義了一個名稱為test-pd的Pod資源。它通過hostPath型別的儲存卷,將Pod宿主機上的/data掛接到容器中的/teset-pd目錄。

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    # 指定在容器中掛接路徑
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  # 指定所提供的儲存卷
  volumes:
  - name: test-volume
    hostPath:
      # 宿主機上的目錄
      path: /data
      # this field is optional
      type: Directory

2.2 NFS

在Kubernetes中,可以通過nfs型別的儲存卷將現有的NFS(網路檔案系統)到的掛接到Pod中。在移除Pod時,NFS儲存卷中的內容被不會被刪除,只是將儲存卷解除安裝而已。這意味著在NFS儲存卷總可以預先填充資料,並且可以在Pod之間共享資料。NFS可以被同時掛接到多個Pod中,並能同時進行寫入。需要注意的是:在使用nfs儲存卷之前,必須已正確部署和執行NFS伺服器,並已經設定了共享目錄。

下面是一個redis部署的YAML配置檔案,redis在容器中的持久化資料儲存在/data目錄下;儲存卷使用nfs,nfs的服務地址為:192.168.8.150,儲存路徑為:/k8s-nfs/redis/data。容器通過volumeMounts.name的值確定所使用的儲存卷。

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: redis
spec:
  selector:
    matchLabels:
      app: redis
  revisionHistoryLimit: 2
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      # 應用的映象
      - image: redis
        name: redis
        imagePullPolicy: IfNotPresent
        # 應用的內部埠
        ports:
        - containerPort: 6379
          name: redis6379
        env:
        - name: ALLOW_EMPTY_PASSWORD
          value: "yes"
        - name: REDIS_PASSWORD
          value: "redis"   
        # 持久化掛接位置,在docker中 
        volumeMounts:
        - name: redis-persistent-storage
          mountPath: /data
      volumes:
      # 宿主機上的目錄
      - name: redis-persistent-storage
        nfs:
          path: /k8s-nfs/redis/data
          server: 192.168.8.150

2.3 persistentVolumeClaim

persistentVolumeClaim型別儲存卷將PersistentVolume掛接到Pod中作為儲存卷。使用此型別的儲存卷,使用者並不知道儲存卷的詳細資訊。

此處定義名為busybox-deployment的部署YAML配置檔案,使用的映象為busybox。基於busybox映象的容器需要對/mnt目錄下的資料進行持久化,在YAML檔案指定使用名稱為nfs的PersistenVolumeClaim對容器的資料進行持久化。

# This mounts the nfs volume claim into /mnt and continuously
# overwrites /mnt/index.html with the time and hostname of the pod. 
apiVersion: v1
kind: Deployment
metadata:  
  name: busybox-deployment
spec:  
  replicas: 2  
  selector:    
    name: busybox-deployment
  template:    
    metadata:      
      labels:        
        name: busybox-deployment    
    spec:      
      containers:      
      - image: busybox        
        command:          
        - sh          
        - -c          
        - 'while true; do date > /mnt/index.html; hostname >> /mnt/index.html; sleep $(($RANDOM % 5 + 5)); done'        
        imagePullPolicy: IfNotPresent        
        name: busybox        
        volumeMounts:          
        # name must match the volume name below          
        - name: nfs            
          mountPath: "/mnt"     
     volumes:      
     - name: nfs        
       persistentVolumeClaim:          
         claimName: nfs-pvc