技術乾貨 | K8S如何引入Volumes?

Number1

爲什麼引入Volume?

  • 當container crash的時候,kubelet將會重啓它,裏面之前運行的數據將會丟失,容器將以一個clean state的狀態來啓動。

  • 運行在pod中的containers通常會共享數據,volumes的概念就是爲了解決這些問題。

Number2

現狀

kubernetes中的volume有完整的lifetime,在pod中可以脫離Container而存在。container重啓的時候,volume中的pod會被保存;pod消失的時候,volume也會消失。 kubernetes支持多種volumes的類型,pod可以使用同時使用多個volume。類型如下:

emptyDir 

hostPath 

gcePersistentDisk 

awsElasticBlockStore 

nfs 

iscsi 

flocker 

glusterfs 

rbd 

cephfs 

gitRepo 

secret 

persistentVolumeClaim 

downwardAPI 

projected 

azureFileVolume 

azureDisk 

vsphereVolume 

Quobyte 

PortworxVolume 

ScaleIO 

Number3

常用存儲類型

emptyDir

emptyDir卷當pod分配給Node的時候會被創建,伴隨這pod在該Node上運行整個過程。開始的時候爲空的, pod中的containers可以讀寫emptyDir volume中的同一個文件,這個volume可以被掛載到容器相同或者不同的目錄。但是如果pod在該node上被removed,那麼emptyDir中的數據將會被永遠的刪除。注意:如果容器crashing pod沒有從node上remove,emptyDir中的volume數據是safe的。

emptyDir的用途

  • 暫存空間,如基於磁盤的合併排序

  • 檢查一個長時間的計算以恢復崩潰

  • 持有內容管理器容器在Web服務器容器提供數據時提取的文件

默認情況下,根據您的環境,emptyDir卷存儲在任何介質中,可能是磁盤或SSD或網絡存儲。 但是,您可以將emptyDir.medium字段設置爲“Memory”,以告訴Kubernetes爲您安裝tmpfs(RAM支持的文件系統)。 雖然tmpfs非常快,但請注意,與磁盤不同,tmpfs在機器重新啓動時被清除,您寫入的任何文件都會計入您的容器的內存限制。

Pod的例子:

apiVersion: v1

kind: Pod

metadata:

  name: test-pd

spec:

  containers:

  – image: gcr.io/google_containers/test-webserver

    name: test-container

    volumeMounts:

    – mountPath: /cache

      name: cache-volume

  volumes:

  – name: cache-volume

    emptyDir: {}

Hostpath

hostPath卷將文件或目錄從主機節點的文件系統掛載到您的pod中。 這不是大多數Pods需要的,但它爲某些應用提供了強大的逃生艙。 

比如,一些使用hostPath的例子:

運行需要訪問Docker內部的容器; 使用/ var / lib / docker的hostPath

在容器中運行cAdvisor; 使用/ dev / cgroups的hostPath

使用的時候需要注意:

1. 具有相同配置的pod(例如從podTemplate創建的),可能因節點上的不同文件在不同節點上的行爲不同。 

2. 當Kubernetes按計劃添加資源感知調度時,它將無法解決hostPath使用的資源。 

3. 在底層主機上創建的目錄只能由root寫入。 您需要以特權容器的身份運行您的進程,或修改主機上的文件權限,以便能夠寫入hostPath卷。

apiVersion: v1

kind: Pod

metadata:

  name: test-pd

spec:

  containers:

  – image: gcr.io/google_containers/test-webserver

    name: test-container

    volumeMounts:

    – mountPath: /test-pd

      name: test-volume

  volumes:

  – name: test-volume

    hostPath:

      # directory location on host

      path: /data

gcePersistentDisk

awsElasticBlockStore

Nfs

nfs卷允許現有的NFS(網絡文件系統)共享掛載到您的pod中。 不同於在刪除Pod時被清除的emptyDir,nfs卷的內容將被保留,並且卷僅被卸載。 這意味着NFS卷可以預先填充數據,並且該數據可以在pod之間“切換”。 NFS可以同時由多個寫入器安裝。

nfs例子:

https://github.com/kubernetes/kubernetes/tree/master/examples/volumes/nfs

iSCSI

iscsi卷允許將現有iSCSI(基於IP的SCSI)卷安裝到您的pod中。 不同於在刪除Pod時被清除的emptyDir,將保留iscsi卷的內容,並且該卷僅被卸載。 這意味着可以使用數據預先填充一個iscsi卷,並且該數據可以在pod之間“切換”。

iSCSI的一個特點是它可以同時由多個消費者以只讀方式安裝。 這意味着您可以使用數據集預先填充卷,然後根據需要從多個pod中並行提供。 不幸的是,iSCSI卷只能由讀寫模式的單個消費者進行裝載——不允許同時寫入。

iSCSI例子

https://github.com/kubernetes/kubernetes/tree/master/examples/volumes/iscsi

Flocker

Flocker是一個開源的集羣容器數據卷管理器。它提供由各種存儲後端支持的數據卷的管理和編排。

Flocker卷允許將Flocker數據集掛載到pod中。如果Flocker中尚未存在數據集,則需要首先使用Flocker CLI或使用Flocker API創建數據集。如果數據集已經存在,它將被Flocker重新連接到調度盒的節點,這意味着數據可以根據需要在pod之間“切換”。

Flocker例子:

https://github.com/kubernetes/kubernetes/tree/master/examples/volumes/flocker

glusterfs

glusterfs卷允許將Glusterfs(開源網絡文件系統)卷安裝到您的pod中。不同於在刪除Pod時被清除的emptyDir,保留了一個glusterfs卷的內容,並且該卷只是被卸載。這意味着可以使用數據預先填充一個glusterfs卷,並且該數據可以在pod之間“切換”。GlusterFS可以同時由多個寫入器安裝。

Rbd

cephfs

gitRepo

secret

祕密卷用於將敏感信息(如密碼)傳遞給pod。 您可以將祕密存儲在Kubernetes API中,並將其作爲文件安裝在pod上,而不直接與Kubernetes連接。 祕密卷由tmpfs(RAM支持的文件系統)支持,因此它們永遠不會寫入非易失性存儲。

PersistentVolumeClaim

persistentVolumeClaim卷用於將PersistentVolume安裝到pod中。PersistentVolumes是用戶在不知道特定雲環境的細節的情況下“聲稱”持久存儲(如GCE PersistentDisk或iSCSI卷)的一種方式。

downwardAPI

一個向下的API卷被用於使向下的API數據可用於應用程序。它安裝一個目錄,並將所請求的數據寫入純文本文件。

https://kubernetes.io/docs/tasks/configure-pod-container/downward-api-volume-expose-pod-information/

projected

A projected volume可以映射很多volume源到相同的目錄下, 當前,下面類型的volume sources支持的有:

secret

downwardAPI

configMap

例子:

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

SubPath

有時,在一個pod中共享一個卷用於多個用途是有用的。 volumeMounts.subPath屬性可用於指定引用卷而不是根的子路徑。 

下面是一個LAMP stack的例子,Html內容映射到html文件目錄下,databases存儲在MySQL文件目錄下:

apiVersion: v1

kind: Pod

metadata:

  name: my-lamp-site

spec:

    containers:

    – name: mysql

      image: mysql

      volumeMounts:

      – mountPath: /var/lib/mysql

        name: site-data

        subPath: mysql

    – name: php

      image: php

      volumeMounts:

      – mountPath: /var/www/html

        name: site-data

        subPath: html

    volumes:

    – name: site-data

      persistentVolumeClaim:

        claimName: my-lamp-site-data


本文轉移K8S技術社區-技術乾貨 | K8S如何引入Volumes?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章