kubernetes系列10—儲存卷詳解

alonghub發表於2019-01-30

本文收錄在容器技術學習系列文章總目錄

1、認識儲存卷

1.1 背景

  預設情況下容器中的磁碟檔案是非持久化的,容器中的磁碟的生命週期是短暫的,這就帶來了一系列的問題:第一,當一個容器損壞之後,kubelet 會重啟這個容器,但是檔案會丟失這個容器會是一個全新的狀態;第二,當很多容器在同一Pod中執行的時候,很多時候需要資料檔案的共享。Kubernete Volume解決了這個問題。

 

1.2 介紹

  Docker有一個Volumes的概念,雖然這個Volume有點寬鬆和管理性比較小。在Docker中,一個 Volume 是一個簡單的所在主機的一個目錄或者其它容器中的。生命週期是沒有辦法管理,直到最近才有 local-disk-backed 磁碟。Docker現在提供了磁碟驅動,但是功能非常有限(例如Docker1.7只能掛在一個磁碟每個容器,並且無法傳遞引數)

  從另外一個方面講,Kubernetes volume,擁有明確的生命週期,與所在的Pod的生命週期相同。因此,Kubernetes volume獨立與任何容器,與Pod相關,所以資料在重啟的過程中還會保留,當然,如果這個Pod被刪除了,那麼這些資料也會被刪除。更重要的是,Kubernetes volume 支援多種型別,任何容器都可以使用多個Kubernetes volume

  它的核心,一個 volume 就是一個目錄,可能包含一些資料,這些資料對pod中的所有容器都是可用的,這個目錄怎麼使用,什麼型別,由什麼組成都是由特殊的volume 型別決定的。

  要使用Volumepod需要指定Volume的型別和內容(spec.volumes欄位),和對映到容器的位置(spec.containers.volumeMounts欄位)。

  容器中的程式可以看成由Docker映象和卷組成的檔案系統檢視。Docker映象位於檔案系統層次結構的根目錄下,任何卷都安裝在影像中的指定路徑上。卷無法裝入其他卷或具有到其他卷的硬連結。Pod中的每個容器必須獨立指定每個卷的安裝位置。

 

1.3 儲存卷常用型別

  •  非永續性儲存
    •  emptyDir
    •  hostPath
  •  網路連線性儲存
    •  SANiSCSI
    •  NFSnfscfs
  •  分散式儲存
    •  glusterfsrbdcephfs
  •  雲端儲存
    •  EBSAzure Disk、阿里雲、gitRepo
$ kubectl explain pod.spec.volumes 查詢k8s支援的所有型別儲存卷

 

2、emptyDir儲存卷

2.1 emptyDir介紹

  使用emptyDir,當Pod分配到Node上時,將會建立emptyDir,並且只要Node上的Pod一直執行,Volume就會一直存。當Pod(不管任何原因)從Node上被刪除時,emptyDir也同時會刪除,儲存的資料也將永久刪除。

  常用於作為臨時目錄、或快取使用。

 

2.2 演示:建立emptyDir儲存卷

1)編寫yaml檔案,並建立

先建立一個名為html的儲存卷;再由2pod都掛載此儲存卷;

pod1基於此儲存卷作為nginx的主目錄;pod2向此儲存卷目錄寫入東西;

[root@master volumes]# vim vol-emptyDir-demo.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-demo
  namespace: default
  labels:
    app: myapp
    tier: frontend
  annotations:
    along.com/created-by: "cluster admin"
spec:
  volumes:
  - name: html
    emptyDir: {}
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html/
  - name: busybox
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: html
      mountPath: /data/
    command:
    - "/bin/sh"
    - "-c"
    - "while true; do echo $(date) >> /data/index.html; sleep 2; done"
[root@master volumes]# kubectl apply -f vol-emptyDir-demo.yaml
pod/pod-vol-demo created

  

2)驗證

---pod建立成功
[root@master ~]# kubectl get pods -o wide
NAME           READY     STATUS    RESTARTS   AGE       IP             NODE
pod-vol-demo   2/2       Running   0          13s       10.244.1.106   node1
---訪問業務,輸出是pod2的輸入
[root@master ~]# curl 10.244.1.106
Tue Jan 29 07:19:13 UTC 2019
Tue Jan 29 07:19:15 UTC 2019
Tue Jan 29 07:19:17 UTC 2019
Tue Jan 29 07:19:19 UTC 2019
Tue Jan 29 07:19:21 UTC 2019
Tue Jan 29 07:19:23 UTC 2019
Tue Jan 29 07:19:25 UTC 2019
Tue Jan 29 07:19:27 UTC 2019
Tue Jan 29 07:19:29 UTC 2019

  

3、hostPath儲存卷

3.1 emptyDir介紹

  hostPath允許掛載Node(宿主機)上的檔案系統到Pod裡面去。如果Pod需要使用Node上的檔案,可以使用hostPath

 

3.2 hostPath型別

行為
空字串(預設)用於向後相容,這意味著在安裝hostPath卷之前不會執行任何檢查。
DirectoryOrCreate 如果給定路徑中不存在任何內容,則將根據需要建立一個空目錄,許可權設定為0755,與Kubelet具有相同的組和所有權。
Directory 目錄必須存在於給定路徑中
FileOrCreate 如果給定路徑中不存在任何內容,則會根據需要建立一個空檔案,許可權設定為0644,與Kubelet具有相同的組和所有權。
File 檔案必須存在於給定路徑中
Socket UNIX套接字必須存在於給定路徑中
CharDevice 字元裝置必須存在於給定路徑中
BlockDevice 塊裝置必須存在於給定路徑中

 

3.2 演示:建立hostPath儲存卷

1)編寫yaml檔案,並建立

建立儲存卷,使用DirectoryOrCreate型別,node節點不存在會自動建立

[root@master volumes]# vim vol-hostpath-demo.yaml
apiVersion: v1
kind: Pod
metadata:
  name: vol-hostpath
  namespace: default
spec:
  volumes:
  - name: html
    hostPath:
      path: /data/pod/volume1/
      type: DirectoryOrCreate
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html/
[root@master volumes]# kubectl apply -f vol-hostpath-demo.yaml
pod/vol-hostpath created

  

2)查詢驗證

[root@master volumes]# kubectl get pods -o wide
NAME           READY     STATUS    RESTARTS   AGE       IP             NODE
vol-hostpath   1/1       Running   0          3s        10.244.1.111   node1
---在node1上查詢是否生產目錄
[root@node1 ~]# ll -d /data/pod/volume1/index.html 
-rw-r--r-- 1 root root 17 Sep 21 14:44 /data/pod/volume1/index.html

  

3)驗證儲存卷功能

---在node1上生成檔案
[root@node1 ~]# echo "node01.along.com" > /data/pod/volume1/index.html
---訪問pod內服務,顯示成功
[root@master volumes]# curl 10.244.1.111
node01.along.com

  

4)就算pod被刪除再重建,只要node還在,儲存卷就還在

[root@master volumes]# kubectl delete -f vol-hostpath-demo.yaml
pod "vol-hostpath" deleted
[root@master volumes]# kubectl apply -f vol-hostpath-demo.yaml
pod/vol-hostpath created
[root@master volumes]# kubectl get pods -o wide
NAME           READY     STATUS    RESTARTS   AGE       IP             NODE
vol-hostpath   1/1       Running   0          3s        10.244.1.112   node1
[root@master volumes]# curl 10.244.1.112
node01.along.com

  

4、共享儲存NFS儲存卷

4.1 NFS儲存卷介紹

  NFS Network File System的縮寫,即網路檔案系統。Kubernetes中通過簡單地配置就可以掛載NFSPod中,NFS中的資料是可以永久儲存的,同時NFS支援同時寫操作。Pod被刪除時,Volume被解除安裝,內容被保留。這就意味著NFS能夠允許我們提前對資料進行處理,而且這些資料可以在Pod之間相互傳遞。

 

4.2 演示:建立NFS儲存卷

4.2.1 在一臺伺服器搭建NFS

1)事前準備

修改k8s叢集服務的hosts檔案,使之能解析nfs伺服器

[root@master volumes]# vim /etc/hosts
192.168.130.103 master
192.168.130.104 node1
192.168.130.105 node2
192.168.130.106 nfs

k8s叢集伺服器,安裝nfs-utils 工具

$ yum -y install nfs-utils

  

2)在106伺服器上提供nfs服務

[root@nfs ~]# yum -y install nfs-utils
[root@nfs ~]# mkdir /data/volumes -p
[root@nfs ~]# vim /data/volumes/index.html
<h1>NFS stor</h1>
[root@nfs ~]# vim /etc/exports
/data/volumes	192.168.130.0/24(rw,no_root_squash)
[root@nfs ~]# systemctl start nfs

  

4.2.1 建立NFS儲存卷

1)編寫yaml檔案,並建立

[root@master volumes]# vim vol-nfs-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: vol-nfs
  namespace: default
spec:
  volumes:
  - name: html
    nfs:
      path: /data/volumes
      server: nfs
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html/
[root@master volumes]# kubectl apply -f vol-nfs-demo.yaml
pod/vol-nfs created

  

2)驗證,訪問服務成功

[root@master ~]# kubectl get pods -o wide
NAME      READY     STATUS    RESTARTS   AGE       IP             NODE
vol-nfs   1/1       Running   0          9s        10.244.1.115   node1
[root@master ~]# curl 10.244.1.115
<h1>NFS stor</h1>

刪除pod,再建立,也還存在資料。

 

5、一些不常用的儲存卷

5.1 gitRepo

1)介紹

gitRepo volumegit程式碼下拉到指定的容器路徑中

 

2)示例

apiVersion: v1
kind: Pod
metadata:
  name: server
spec:
  volumes:
  - name: git-volume
    gitRepo:
      repository: "git@github.com:alonghub/my-git-repository.git"
     revision: "22f1d8406d464b0c0874075539c1f2e96c253775"
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    volumeMounts:
    - name: git-volume
      mountPath: /usr/share/nginx/html/

  

5.2 glusterfs

  glusterfs,允許將Glusterfs(一個開源網路檔案系統)Volume安裝到pod中。不同於emptyDirPod被刪除時,Volume只是被解除安裝,內容被保留。味著glusterfs能夠允許我們提前對資料進行處理,而且這些資料可以在Pod之間切換

  注意::必須先執行自己的GlusterFS安裝,然後才能使用它。

  有關更多詳細資訊,請參閱GlusterFS示例

 

5.3 RBD

  RBD允許Rados Block Device格式的磁碟掛載到Pod中,同樣的,當pod被刪除的時候,rbd也僅僅是被解除安裝,內容保留,rbd能夠允許我們提前對資料進行處理,而且這些資料可以在Pod之間切換

  有關更多詳細資訊,請參閱RBD示例

 

5.4 cephfs

  cephfs Volume可以將已經存在的CephFS Volume掛載到pod中,與emptyDir特點不同,pod被刪除的時,cephfs僅被被解除安裝,內容保留。cephfs能夠允許我們提前對資料進行處理,而且這些資料可以在Pod之間切換

  提示:可以使用自己的Ceph伺服器執行匯出,然後在使用cephfs

  有關更多詳細資訊,請參閱CephFS示例

 

相關文章