html
node
mysql
非持久性存儲nginx
emptyDirgit
hostPathgithub
網絡鏈接性存儲web
SAN:iscsiredis
NFS:nfs、cfssql
分佈式存儲docker
glusterfs、cephfs、rbd
雲端存儲
awsElasticBlockStore、azureDisk、gitRepo
...... volumes: - name: data emptyDir: {} - name: example gitRepo: repository: https://github.com/ikubernetes/k8s_book.git revision: master directory:
...... volumeMounts: - name <string> -required- #指定要掛載的存儲卷的名稱,必選字段 mountPath <string> -required- #掛載點路徑,容器文件系統的路徑,必選字段 readOnly <boolean> #是否掛載爲只讀卷 subPath <string> #掛載存儲卷時使用的子路徑,及mountPath指定的路徑下使用一個子路徑做爲其掛載點。
spec: containers: - name: myapp image: ikubernetes/myapp:v1 volumeMounts: - name: data mountPath: /var/log/myapp/ - name: example mountPath: /webdata/example/
[root@k8s-master ~]# mkdir storage [root@k8s-master ~]# cd storage/
emptyDir的做用:
普通空間,基於磁盤的數據存儲
做爲從崩潰中恢復的備份點
存儲那些須要長久保存的數據,例如
web
服務中的數據
[root@k8s-master ~]# kubectl explain pod.spec.volumes.emptyDir medium <string>: #此目錄所在的存儲介質的類型,可取值爲「default」或「Memory」,默認爲default,表示使用節點的的默認存儲介質;Memory表示使用基於RAM的臨時的文件系統temfs,空間受限於內存,但性能很是好,一般用於爲容器中的應用提供緩存空間。 sizeLimit <string> #當前存儲卷的空間限額,默認值爲nil,表示不限制;不過,在medium字段值爲「Memory」時建議務一定義此限額。
emptyDir示例:
1)編輯資源清單文件
[root@k8s-master storage]# vim vol-emptydir.yaml apiVersion: v1 kind: Pod metadata: name: vol-emptydir-pod spec: volumes: #定義存儲卷 - name: html #定義存儲卷的名稱 emptyDir: {} #定義存儲卷的類型 containers: - name: nginx image: nginx:1.12 volumeMounts: #在容器中定義掛載存儲卷的名和路徑 - name: html mountPath: /usr/share/nginx/html - name: sidecar image: alpine volumeMounts: #在容器中定義掛載存儲卷的名和路徑 - name: html mountPath: /html command: ["/bin/sh", "-c"] args: - while true; do echo $(hostname) $(date) >> /html/index.html; sleep 10; done
2)建立並查看狀態
[root@k8s-master storage]# kubectl apply -f vol-emptydir.yaml pod/vol-emptydir-pod created [root@k8s-master storage]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES vol-emptydir-pod 2/2 Running 0 63s 10.244.2.79 k8s-node2 <none> <none>
3)訪問測試
[root@k8s-master storage]# curl 10.244.2.79 vol-emptydir-pod Wed Oct 9 03:32:43 UTC 2019 vol-emptydir-pod Wed Oct 9 03:32:53 UTC 2019 vol-emptydir-pod Wed Oct 9 03:33:03 UTC 2019 vol-emptydir-pod Wed Oct 9 03:33:13 UTC 2019 vol-emptydir-pod Wed Oct 9 03:33:23 UTC 2019 ...... #進入vol-emptydir-pod中的sidecar容器中查看掛載目錄下的index.html文件 [root@k8s-master storage]# kubectl exec vol-emptydir-pod -c sidecar -it -- /bin/sh / # ls bin etc html media opt root sbin sys usr dev home lib mnt proc run srv tmp var / # ls /html index.html / # cat /html/index.html vol-emptydir-pod Wed Oct 9 03:32:43 UTC 2019 vol-emptydir-pod Wed Oct 9 03:32:53 UTC 2019 vol-emptydir-pod Wed Oct 9 03:33:03 UTC 2019 ...... #進入vol-emptydir-pod中的nginx容器中查看掛載目錄下的index.html文件 [root@k8s-master storage]# kubectl exec vol-emptydir-pod -c nginx -it -- /bin/sh # cat /usr/share/nginx/html/index.html vol-emptydir-pod Wed Oct 9 03:32:43 UTC 2019 vol-emptydir-pod Wed Oct 9 03:32:53 UTC 2019 vol-emptydir-pod Wed Oct 9 03:33:03 UTC 2019 ......
hostPath字段說明:
[root@k8s-master storage]# kubectl explain pod.spec.volumes.hostPath path <string> -required- #指定工做節點上的目錄路徑 type <string> #指定存儲卷類型 type類型以下: DirectoryOrCreate 指定的路徑不存在時自動建立其權限爲0755的空目錄,屬主和屬組爲kubelet Directory 必須存在的目錄路徑 FileOrCreate 指定的路徑不存在時自動建立其權限爲0644的空文件,屬主和屬組爲kubelet File 必須存在的文件路徑 Socket 必須存在的Socket文件路徑 CharDevice 必須存在的字符設備文件路徑 BlockDevice 必須存在的塊設備文件路徑
hostPath示例:
1)編輯資源清單文件
[root@k8s-master storage]# vim vol-hostpath.yaml
2)建立並查看狀態
[root@k8s-master storage]# kubectl apply -f vol-hostpath.yaml pod/vol-hostpath-pod created [root@k8s-master storage]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES vol-hostpath-pod 1/1 Running 0 7s 10.244.1.83 k8s-node1 <none> <none>
3)經過上面查看pod被調度到節點1上面,查看節點1的目錄並建立測試文件
[root@k8s-node1 ~]# ll /data/pod/volume1/ 總用量 0 [root@k8s-node1 ~]# echo "<h1>kubernetes hostPath test</h1>" >> /data/pod/volume1/index.html
4)訪問測試,及刪除測試
[root@k8s-master storage]# curl 10.244.1.83 <h1>kubernetes hostPath test</h1> #刪除pod資源再次查看節點1上面的文件 [root@k8s-master storage]# kubectl delete -f vol-hostpath.yaml pod "vol-hostpath-pod" deleted [root@k8s-node1 ~]# ll /data/pod/volume1/ 總用量 4 -rw-r--r-- 1 root root 34 10月 9 16:09 index.html
[root@k8s-master ~]# kubectl explain pod.spec.volumes.nfs server <string> -required- #NFS服務器的IP地址或主機名,必選字段 path <string> -required- #NFS服務器導出(共享)的文件系統路徑,必選字段 readOnly <boolean> #是否以只讀方式掛載,默認爲false
[root@storage ~]# yum -y install nfs-utils #安裝軟件 [root@storage ~]# mkdir -p /data/k8s/v1 #建立共享目錄 [root@storage ~]# vim /etc/exports #編輯配置文件配置共享目錄 /data/k8s/v1 192.168.1.0/24(rw,no_root_squash) [root@storage ~]# systemctl start rpcbind #啓動rpcbind服務(nfs依賴服務) [root@storage ~]# systemctl start nfs #啓動nfs [root@k8s-node1 ~]# showmount -e 192.168.1.34 #k8s節點測試可否正常訪問到nfs服務器 Export list for 192.168.1.34: /data/k8s/v1 192.168.1.0/24
2)編輯資源清單文件
[root@k8s-master storage]# vim vol-nfs.yaml
3)建立並查看狀態
[root@k8s-master storage]# kubectl apply -f vol-nfs.yaml pod/vol-nfs-pod created [root@k8s-master storage]# kubectl get pods NAME READY STATUS RESTARTS AGE vol-nfs-pod 1/1 Running 0 45s [root@k8s-master storage]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES vol-nfs-pod 1/1 Running 0 51s 10.244.2.80 k8s-node2 <none> <none>
4)測試驗證
[root@k8s-master storage]# kubectl exec -it vol-nfs-pod redis-cli 127.0.0.1:6379> set mykey "hello test" OK 127.0.0.1:6379> get mykey "hello test 127.0.0.1:6379> bgsave Background saving started 127.0.0.1:6379> exit #爲了測試其數據持久化效果,下面刪除Pod資源vol-nfs-pod,並於再次從新建立後檢測數據是否依然可以訪問 [root@k8s-master storage]# kubectl delete -f vol-nfs.yaml pod "vol-nfs-pod" deleted [root@k8s-master storage]# kubectl apply -f vol-nfs.yaml pod/vol-nfs-pod created [root@k8s-master storage]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES vol-nfs-pod 1/1 Running 0 47s 10.244.1.84 k8s-node1 <none> <none> [root@k8s-master storage]# kubectl exec -it vol-nfs-pod redis-cli 127.0.0.1:6379> get mykey "hello test" 127.0.0.1:6379>
PersistentVolumeClaim
(PVC
)是用戶存儲的請求。它相似於Pod
。Pod
消耗節點資源,PVC
消耗存儲資源。Pod
能夠請求特定級別的資源(CPU
和內存)。權限要求能夠請求特定的大小和訪問模式。
雖然
PersistentVolumeClaims
容許用戶使用抽象存儲資源,可是常見的是,用戶須要具備不一樣屬性(如性能)的PersistentVolumes
,用於不一樣的問題。集羣管理員須要可以提供多種不一樣於PersistentVolumes
的PersistentVolumes
,而不只僅是大小和訪問模式,而不會使用戶瞭解這些卷的實現細節。對於這些需求,存在StorageClass
資源。
StorageClass
爲管理員提供了一種描述他們提供的存儲的「類」的方法。不一樣的類可能映射到服務質量級別,或備份策略,或者由集羣管理員肯定的任意策略。Kubernetes
自己對於什麼類別表明是不言而喻的。這個概念有時在其它存儲系統中稱爲「配置文件」
Provisioning—>Binding—>Using—>Releasing—>Recycling
供應準備Provisioning
Static:集羣管理員建立多個
PV
。它們攜帶可供集羣用戶使用的真實存儲的詳細信息。它們存在於Kubernetes API
中,可用於消費。Dynamic:當管理員建立的靜態
PV
都不匹配用戶的PersistentVolumesClaim
時,集羣可能會嘗試爲PVC
動態配置卷。此配置基於StorageClasses:PVC
必須請求一個類,而且管理員必須已經建立並配置該類才能進行動態配置。要求該類的聲明有效地位本身禁用動態配置。
綁定Binding
使用Using
釋放Releasing
回收Recycling
字段說明:
[root@k8s-master ~]# kubectl explain pv.spec capacity <map[string]string> #當前PV的容量;目前,capacity僅支持空間設定,未來應該還能夠指定IOPS和throughput。 accessModes <[]string> #訪問模式;儘管在PV層看起來並沒有差別,但存儲設備支持及啓用的功能特性卻可能不盡相同。例如NFS存儲支持多客戶端同時掛載及讀寫操做,但也多是在共享時僅啓用了只讀操做,其餘存儲系統也存在相似的可配置特性。所以,PV底層的設備或許存在其特有的訪問模式,用戶使用時必須在其特性範圍內設定其功能。參考:https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes - ReadWribeOnce:僅可被單個節點讀寫掛載;命令行中簡寫爲RWO。 - ReadOnlyMany:可被多個節點同時只讀掛載;命令行中簡寫爲ROX。 - ReadWriteMany:可被多個節點同時讀寫掛載;命令行中簡寫爲RWX。 persistentVolumeReclaimPolicy <string> #PV空間被釋放時的處理機制;可用類型僅爲Retain(默認)、Recycle或Delete,具體說明以下。 - Retain:保持不動,由管理員隨後手動回收。 - Recycle:空間回收,即刪除存儲卷目錄下的全部文件(包括子目錄和隱藏文件),目前僅NFS和hostPath支持此操做。 - Delete:刪除存儲卷,僅部分雲端存儲系統支持,如AWS EBS、GCE PD、Azure Disk和Cinder volumeMode <string> #卷模型,用於指定此卷可被用做文件系統仍是裸格式的塊設備;默認爲Filesystem。 storageClassName <string> #當前PV所屬的StorageClass的名稱;默認爲空值,即不屬於任何StorageClass。 mountOptions <[]string> #掛載選項組成的列表,如ro、soft和hard等。
字段說明:
PersistentVolumeClaim
是存儲卷類型的資源,它經過申請佔用某個PersistentVolume
而建立,它與PV
是一對一的關係,用戶無須關係其底層實現細節。申請時,用戶只須要指定目標空間的大小、訪問模式、PV
標籤選擇器和StorageClass
等相關信息便可。PVC
的Spec
字段的可嵌套字段具體以下:
[root@k8s-master ~]# kubectl explain pvc.spec accessModes <[]string> #當前PVC的訪問模式,其可用模式與PV相同 resources <Object> #當前PVC存儲卷鬚要佔用的資源量最小值;目前,PVC的資源限定僅指其空間大小 selector <Object> #綁定時對PV應用的標籤選擇器(matchLabels)或匹配條件表達式(matchEx-pressions),用於挑選要綁定的PV;若是同時指定了兩種挑選機制,則必須同時知足兩種選擇機制的PV才能被選出 storageClassName <string> #所依賴的存儲卷的名稱 volumeMode <string> #卷模型,用於指定此卷可被用做於文件系統仍是裸格式的塊設備;默認爲「Filesystem」 volumeName <string> #用於直接指定要綁定的PV的卷名
[root@k8s-master ~]# kubectl explain pod.spec.volumes.persistentVolumeClaim claimName <string> -required- #要調用的PVC存儲卷的名稱,PVC卷要與Pod在同一名稱空間中 readOnly <boolean> #是否將存儲卷掛載爲只讀模式,默認爲false。
(1)建立存儲卷對應的目錄 [root@storage ~]# mkdir /data/volumes/v{1..5} -p (2)修改nfs的配置文件 [root@storage ~]# vim /etc/exports /data/volumes/v1 192.168.1.0/24(rw,no_root_squash) /data/volumes/v2 192.168.1.0/24(rw,no_root_squash) /data/volumes/v3 192.168.1.0/24(rw,no_root_squash) /data/volumes/v4 192.168.1.0/24(rw,no_root_squash) /data/volumes/v5 192.168.1.0/24(rw,no_root_squash) (3)查看nfs的配置 [root@storage ~]# exportfs -arv exporting 192.168.1.0/24:/data/volumes/v5 exporting 192.168.1.0/24:/data/volumes/v4 exporting 192.168.1.0/24:/data/volumes/v3 exporting 192.168.1.0/24:/data/volumes/v2 exporting 192.168.1.0/24:/data/volumes/v1 (4)使配置生效 [root@storage ~]# showmount -e Export list for storage: /data/volumes/v5 192.168.1.0/24 /data/volumes/v4 192.168.1.0/24 /data/volumes/v3 192.168.1.0/24 /data/volumes/v2 192.168.1.0/24 /data/volumes/v1 192.168.1.0/24
(1)編寫資源清單文件 [root@k8s-master storage]# vim pv-nfs-demo.yaml apiVersion: v1 kind: PersistentVolume metadata: name: pv-nfs-001 labels: name: pv001 spec: nfs: path: /data/volumes/v1 server: 192.168.1.34 readOnly: false accessModes: ["ReadWriteOnce","ReadWriteMany"] capacity: storage: 2Gi persistentVolumeReclaimPolicy: Retain --- apiVersion: v1 kind: PersistentVolume metadata: name: pv-nfs-002 labels: name: pv002 spec: nfs: path: /data/volumes/v2 server: 192.168.1.34 readOnly: false accessModes: ["ReadWriteOnce"] capacity: storage: 5Gi persistentVolumeReclaimPolicy: Retain --- apiVersion: v1 kind: PersistentVolume metadata: name: pv-nfs-003 labels: name: pv003 spec: nfs: path: /data/volumes/v3 server: 192.168.1.34 readOnly: false accessModes: ["ReadWriteOnce","ReadWriteMany"] capacity: storage: 10Gi persistentVolumeReclaimPolicy: Retain --- apiVersion: v1 kind: PersistentVolume metadata: name: pv-nfs-004 labels: name: pv004 spec: nfs: path: /data/volumes/v4 server: 192.168.1.34 readOnly: false accessModes: ["ReadWriteOnce","ReadWriteMany"] capacity: storage: 15Gi persistentVolumeReclaimPolicy: Retain --- apiVersion: v1 kind: PersistentVolume metadata: name: pv-nfs-005 labels: name: pv005 spec: nfs: path: /data/volumes/v5 server: 192.168.1.34 readOnly: false accessModes: ["ReadWriteOnce","ReadWriteMany"] capacity: storage: 20Gi persistentVolumeReclaimPolicy: Retain (2)建立PV [root@k8s-master storage]# kubectl apply -f pv-nfs-demo.yaml persistentvolume/pv-nfs-001 created persistentvolume/pv-nfs-002 created persistentvolume/pv-nfs-003 created persistentvolume/pv-nfs-004 created persistentvolume/pv-nfs-005 created (3)查看PV [root@k8s-master storage]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv-nfs-001 2Gi RWO,RWX Retain Available 2s pv-nfs-002 5Gi RWO Retain Available 2s pv-nfs-003 10Gi RWO,RWX Retain Available 2s pv-nfs-004 15Gi RWO,RWX Retain Available 2s pv-nfs-005 20Gi RWO,RWX Retain Available 2s
(1)編寫資源清單文件 [root@k8s-master storage]# vim vol-nfs-pvc.yaml #建立PVC apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nfs-pvc spec: accessModes: ["ReadWriteMany"] resources: requests: storage: 6Gi #指定PVC大小爲6Gi selector: #這裏經過標籤選擇器指定了所使用的pv卷爲key爲name,value爲pv003的pv資源 matchLabels: name: pv003 --- #建立Pod apiVersion: v1 kind: Pod metadata: name: pvc-mysql labels: app: mysql spec: containers: - name: pvc-mysql-pod image: mysql:latest imagePullPolicy: IfNotPresent ports: - name: mysqlport containerPort: 3306 volumeMounts: - name: mysqldata mountPath: /var/lib/mysql env: - name: MYSQL_ROOT_PASSWORD value: "mysql" volumes: - name: mysqldata persistentVolumeClaim: #經過該字段定義使用pvc claimName: nfs-pvc #指定pvc的名稱 readOnly: false #關閉只讀 (2)建立PVC和Pod [root@k8s-master storage]# kubectl apply -f vol-nfs-pvc.yaml persistentvolumeclaim/nfs-pvc created pod/pvc-mysql created
[root@k8s-master storage]# kubectl get pvc #查看pvc,能夠看到該pvc使用的是pv-nfs-003資源 NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE nfs-pvc Bound pv-nfs-003 10Gi RWO,RWX 12s [root@k8s-master storage]# kubectl get pv #查看pv,能夠看出pv-nfs-003資源的狀態從Availabel變成了Bound NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv-nfs-001 2Gi RWO,RWX Retain Available 64m pv-nfs-002 5Gi RWO Retain Available 64m pv-nfs-003 10Gi RWO,RWX Retain Bound default/nfs-pvc 64m pv-nfs-004 15Gi RWO,RWX Retain Available 64m pv-nfs-005 20Gi RWO,RWX Retain Available 64m [root@k8s-master storage]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pvc-mysql 1/1 Running 0 31s 10.244.2.84 k8s-node2 <none> <none> [root@storage ~]# ls /data/volumes/v3/ #查看nfs服務器的pv3對應的共享目錄,裏面生成了mysql的數據。 auto.cnf ca-key.pem ib_buffer_pool ibtmp1 performance_schema server-key.pem binlog.000001 ca.pem ibdata1 #innodb_temp private_key.pem sys binlog.000002 client-cert.pem ib_logfile0 mysql public_key.pem undo_001 binlog.index client-key.pem ib_logfile1 mysql.ibd server-cert.pem undo_002
5)測試驗證
#(1)進入到pod鏈接容器mysql並建立一個數據庫 [root@k8s-master ~]# kubectl exec -it pvc-mysql -- mysql -u root -pmysql ...... mysql> mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 4 rows in set (0.01 sec) mysql> create database volumes; Query OK, 1 row affected (0.00 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | volumes | +--------------------+ 5 rows in set (0.00 sec) mysql> exit Bye #(2)刪除pvc和pod和pv [root@k8s-master storage]# kubectl delete -f vol-nfs-pvc.yaml #刪除pvc persistentvolumeclaim "nfs-pvc" deleted pod "pvc-mysql" deleted [root@k8s-master storage]# kubectl delete -f pv-nfs-demo.yaml #刪除pv(若是有pv在被使用的狀態,須要先刪除pvc方可刪除pv) persistentvolume "pv-nfs-001" deleted persistentvolume "pv-nfs-002" deleted persistentvolume "pv-nfs-003" deleted persistentvolume "pv-nfs-004" deleted persistentvolume "pv-nfs-005" deleted [root@storage ~]# ls /data/volumes/v3/ #上面刪除了pv和pvc,能夠看出存儲服務器上面的數據仍是存在 auto.cnf ca-key.pem ib_buffer_pool ibtmp1 performance_schema server-key.pem volumes binlog.000001 ca.pem ibdata1 #innodb_temp private_key.pem sys binlog.000002 client-cert.pem ib_logfile0 mysql public_key.pem undo_001 binlog.index client-key.pem ib_logfile1 mysql.ibd server-cert.pem undo_002 #(3)從新建立pv和pvc和pod驗證數據 [root@k8s-master storage]# kubectl apply -f pv-nfs-demo.yaml persistentvolume/pv-nfs-001 created persistentvolume/pv-nfs-002 created persistentvolume/pv-nfs-003 created persistentvolume/pv-nfs-004 created persistentvolume/pv-nfs-005 created [root@k8s-master storage]# kubectl apply -f vol-nfs-pvc.yaml persistentvolumeclaim/nfs-pvc created pod/pvc-mysql created [root@k8s-master ~]# kubectl exec -it pvc-mysql -- mysql -u root -pmysql mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | volumes | +--------------------+ 5 rows in set (0.00 sec) ### 測試說明: 若是刪除pvc不刪除pv,從新建立一樣的pvc,那麼pvc狀態會處於Pending狀態,由於pv的當前狀態爲Released。這也和上面定義的回收策略息息相關。