Kubernetes之十三---存儲卷詳解

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 類型決定的。

  要使用Volume,pod需要指定Volume的類型和內容(spec.volumes字段),和映射到容器的位置(spec.containers.volumeMounts字段)。

  容器中的進程可以看成由Docker鏡像和卷組成的文件系統視圖。Docker鏡像位於文件系統層次結構的根目錄下,任何卷都安裝在圖像中的指定路徑上。卷無法裝入其他卷或具有到其他卷的硬鏈接。Pod中的每個容器必須獨立指定每個卷的安裝位置。

 

1.3 存儲卷常用類型

  •  非持久性存儲
    •  emptyDir
    •  hostPath
  •  網絡連接性存儲
    •  SAN:iSCSI
    •  NFS:nfs,cfs
  •  分佈式存儲
    •  glusterfs、rbd、cephfs
  •  雲端存儲
    •  EBS、Azure Disk、阿里雲、gitRepo
1
$ 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的存儲卷;再由2個pod都掛載此存儲卷;

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
[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)驗證效果

[root@master volumes]# kubectl apply -f vol-emptyDir-demo.yaml
pod/pod-vol-demo created
[root@master volumes]# kubectl get pods -o wide
NAME                            READY   STATUS    RESTARTS   AGE     IP            NODE    NOMINATED NODE   READINESS GATES
myapp-deploy-798dc9b584-97qb9   1/1     Running   7          4d9h    10.244.1.61   node1   <none>           <none>
myapp-deploy-798dc9b584-qctz4   1/1     Running   7          4d9h    10.244.2.59   node2   <none>           <none>
myapp-deploy-798dc9b584-tww7g   1/1     Running   7          4d9h    10.244.2.60   node2   <none>           <none>
pod-vol-demo                    2/2     Running   0          7s      10.244.2.62   node2   <none>           <none>
tomcat-deploy-8f6c5dd96-jncvk   1/1     Running   3          3d21h   10.244.1.60   node1   <none>           <none>
tomcat-deploy-8f6c5dd96-pd7jf   1/1     Running   3          3d21h   10.244.2.61   node2   <none>           <none>
tomcat-deploy-8f6c5dd96-prlv8   1/1     Running   3          3d21h   10.244.1.62   node1   <none>           <none>
[root@master volumes]# curl 10.244.2.62
Sun Aug 2 12:20:27 UTC 2020
Sun Aug 2 12:20:29 UTC 2020
Sun Aug 2 12:20:31 UTC 2020
Sun Aug 2 12:20:33 UTC 2020
Sun Aug 2 12:20:35 UTC 2020
Sun Aug 2 12:20:37 UTC 2020
Sun Aug 2 12:20:39 UTC 2020
Sun Aug 2 12:20:41 UTC 2020

  

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節點不存在會自動創建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[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)查詢驗證

1
2
3
4
5
6
[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.63   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)驗證存儲卷功能

1
2
3
4
5
---在node1上生成文件
[root@node1 ~]# echo "welcome to shanghai" > /data/pod/volume1/index.html
---訪問pod內服務,顯示成功
[root@master volumes]# curl 10.244.1.63
welcome to shanghai

  

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

1
2
3
4
5
6
7
8
9
[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
welcome to shanghai

  

4、共享存儲NFS存儲卷

4.1 NFS存儲卷介紹

  NFS 是Network File System的縮寫,即網絡文件系統。Kubernetes中通過簡單地配置就可以掛載NFS到Pod中,而NFS中的數據是可以永久保存的,同時NFS支持同時寫操作。Pod被刪除時,Volume被卸載,內容被保留。這就意味着NFS能夠允許我們提前對數據進行處理,而且這些數據可以在Pod之間相互傳遞。

 

4.2 演示:創建NFS存儲卷

4.2.1 在一臺服務器搭建NFS

(1)事前準備

① 修改k8s集羣服務和NFS服務器的hosts文件,使之能解析nfs服務器

[root@master ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.7.101 master
192.168.7.102 node1
192.168.7.103 node2
192.168.7.104 nfs

 

② 在k8s集羣服務器以及需要共享的NFS主機上,都安裝nfs-utils 工具,注意:如果k8s集羣上也要使用nfs服務器,也需要安裝,如果不需要就不需要安裝

1
$ yum -y install nfs-utils

  

(2)在104服務器上提供nfs服務

1
2
3
4
5
6
7
[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.7.0/24(rw,no_root_squash) # 共享掛載目錄,一定要加上no_root_squash選項,否則K8s集羣在root權限下,也無法下載鏡像
[root@nfs ~]# systemctl start nfs

 

(3)需要在每個node節點上掛載nfs服務器進行測試,測試掛載效果:

[root@node2 ~]# mount -t nfs 192.168.7.104:/data/volumes /mnt  # 在node2上測試掛載,如果能掛載就OK
[root@node2 ~]# mount  # 可以查看掛載到哪個主機上的信息
nfs:/data/volumes on /mnt type nfs4 (rw,relatime,vers=4.1,rsize=262144,wsize=262144,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.7.103,local_lock=none,addr=192.168.7.104)
[root@node2 ~]# umount /mnt  # 掛載成功後,就取消掛載,此處只是爲了試驗掛載效果

  

4.2.1 創建NFS存儲卷

(1)編寫yaml文件,並創建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[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    NOMINATED NODE   READINESS GATES
myapp-deploy-798dc9b584-97qb9   1/1     Running   7          4d10h   10.244.1.61   node1   <none>           <none>
myapp-deploy-798dc9b584-qctz4   1/1     Running   7          4d10h   10.244.2.59   node2   <none>           <none>
myapp-deploy-798dc9b584-tww7g   1/1     Running   7          4d10h   10.244.2.60   node2   <none>           <none>
pod-vol-demo                    2/2     Running   0          17m     10.244.2.62   node2   <none>           <none>
tomcat-deploy-8f6c5dd96-jncvk   1/1     Running   3          3d21h   10.244.1.60   node1   <none>           <none>
tomcat-deploy-8f6c5dd96-pd7jf   1/1     Running   3          3d21h   10.244.2.61   node2   <none>           <none>
tomcat-deploy-8f6c5dd96-prlv8   1/1     Running   3          3d21h   10.244.1.62   node1   <none>           <none>
vol-hostpath                    1/1     Running   0          12m     10.244.1.63   node1   <none>           <none>
vol-nfs                         1/1     Running   0          22s     10.244.2.63   node2   <none>           <none>
[root@master ~]# curl 10.244.2.63
<h1>NFS stor</h1>

刪除pod,再創建,也還存在數據。

 

5、一些不常用的存儲卷

5.1 gitRepo

(1)介紹

gitRepo volume將git代碼下拉到指定的容器路徑中

 

(2)示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: v1
kind: Pod
metadata:
  name: server
spec:
  volumes:
  - name: git-volume
    gitRepo:
      repository: "[email protected]: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中。不同於emptyDir,Pod被刪除時,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。

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