kubernetes物件之Volume

周國通發表於2019-06-11

系列目錄

概述

Volume是對各種儲存資源的抽象、虛擬化。為管理、控制、使用儲存資源提供統一介面。Openstack中的volume為虛擬機器提供儲存,Docker中的volume為容器提供儲存。因為在kubernetes中可部署執行最小單位是pod ,所以kubernetes的volume為pod提供儲存。當然在部署pod時可以不為其提供volume,pod中的容器使用所在節點的硬碟,能同時讀寫資料的地方稱為可讀寫層。這種儲存是容器級的臨時儲存,不是pod級。其生命週期與容器相同,如果容器crash後被重啟,也就是舊容器被刪除而新容器啟動,則舊容器的可讀寫層與容器一起被刪除,其上資料丟失。同理如果pod在節點之間遷移排程,容器的可讀寫層並不會遷移排程。因此,kubernetes需要提供pod級volume,本文中的volume特指kubernetes。

Volume型別
Volume是抽象概念,有很多種具體實現,每種實現各具目的、特點、特性。差不多什麼東西都可以當成volume,型別如下:

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

這裡不對以上所有型別一一介紹,只對目前可能會用到的本地磁碟儲存和分散式儲存做簡單介紹說明

常見儲存型別說明及示例

cephfs

cephfs是一款優秀、流行的雲環境儲存解決方案,原因是它開源、高可用、彈性伸縮,對作業系統、硬體無特殊要求,使用者很容易搭建,使用它的節點也無特別要求。它具備awsElasticBlockStore陳述之所有特點,並且單個voluem可以被多個節點同時使用。使用者首先搭建自己的cephfs環境,然後配置kubernetes叢集與其對接,最後在pod中使用其提供的volume,詳細參考這裡

configMap

使用者首先建立configMap並建立資料儲存其中,此時資料儲存在kubernetes的etcd資料庫中,volume還不存在。當使用者在pod中引用建立的configMap時,系統首先在節點上建立volume並將資料儲存其中,這個volume佔用的是節佔的儲存空間。此後就可以像使用普通volume一樣使用它。

configMap是kubernetes中的一種物件型別,核心本質是以volume的方式將單獨管理的配置資訊傳遞給pod中的容器,並非用來儲存持久化資料。詳細參考這裡

downwardAPI

與configMap類似,以volume的方式向pod中的容器傳遞資訊。configMap中的資訊由使用者在建立物件時傳遞,而downwardAPI的資訊就來自pod物件本身,downwardAPI不需要建立,它是pod Spec中的一個欄位,內容指向pod物件本身的其它欄位,如pod的metadata、image等資訊。在建立pod時系統首先將指向的欄位提取出來,然後建立volume並儲存提取出來的欄位並掛載,容器就可以讀取這些欄位了。

downwardAPI的目的是為將pod本身的欄位資訊如label、annotation等傳遞給容器的一種手段。詳細參考這裡

emptyDir

在節點上執行pod例項時才會建立emptyDir volume。它首先是節點上的一個空目錄,pod中的任何容器都可以用volume的形式掛載使用它。如果容器因為某種原因被刪除並重新啟動,建立的emptyDir不會刪除也不會被清空。當pod例項離開節點排程到其它節點或因為縮容被刪除時,emptyDir被刪除,相當於pod還在但資料丟了。示例:

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}

glusterfs

與cephfs一樣,流行的雲環境下的儲存解決方案,詳細參考這裡,示例參考這裡

hostPath

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:
      # directory location on host
      path: /data
      # this field is optional
      type: Directory

iscsi

網際網路小型計算機系統介面,其特點是便宜。示例參考這裡

local

與emptyDir相似,它也佔用節點的儲存空間。不同點是它是kubernetes中的一種物件型別,使用者可以像管理普通物件一樣管理它。emptyDir在pod例項開時執行時分配,當pod離節點時刪除。local型別的volume則由使用者建立,系統在合適的節點上為其分配資源,排程到這個節點上的pod可以掛載它,pod離開時它也不會消失,除非使用者刪除。示例:

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

nfs

nfs
網路檔案系統,詳細參考這裡

persistentVolumeClaim

與flocker相似,用來遮蔽不同雲環境,詳細參考這裡

projected

如果一個容器需要掛開多個已經存在的volume比如Secret、ConfigMap、DownwardAPI等,原本每個這種型別的volume需要各自佔用一個掛載目錄,而projected能將它們整合在一起,並只掛開到一個目錄下,示例:

apiVersion: v1
kind: Pod
metadata:
  name: volume-test
spec:
  containers:
  - name: container-test
    image: busybox
    volumeMounts:
    - name: all-in-one
      mountPath: "/projected-volume"
      readOnly: true
  volumes:
  - name: all-in-one
    projected:
      sources:
      - secret:
          name: mysecret
          items:
            - key: username
              path: my-group/my-username
      - downwardAPI:
          items:
            - path: "labels"
              fieldRef:
                fieldPath: metadata.labels
            - path: "cpu_limit"
              resourceFieldRef:
                containerName: container-test
                resource: limits.cpu
      - configMap:
          name: myconfigmap
          items:
            - key: config
              path: my-group/my-config

相關文章