目錄
一、volume類型
#爲了持久化保存容器的數據,可以使用 Kubernetes Volume。
Volume 的生命週期獨立於容器,Pod 中的容器可能被銷燬和重建,但 Volume 會被保留。
#本質上,Kubernetes Volume 是一個目錄,當 Volume 被 mount 到 Pod,Pod 中的所有容器都可以訪問這個 Volume。Kubernetes Volume 也支持多種 backend 類型,包括 emptyDir、hostPath、GCE Persistent Disk、AWS Elastic Block Store、NFS、Ceph 等,完整列表可參考 https://kubernetes.io/docs/concepts/storage/volumes/#types-of-volumes
一、emptyDir
#emptyDir 是最基礎的 Volume 類型。一個 emptyDir Volume是master上的一個共享空目錄。
emptyDir Volume 的生命週期與 Pod 一致。
Pod 中的所有容器都可以共享 Volume,它們可以指定各自的 mount 路徑。
#emptyDir是master上創建的臨時目錄,其優點是能夠方便地爲 Pod 中的容器提供共享存儲,不需要額外的配置。但它不具備持久性,如果 Pod 不存在了,emptyDir 也就沒有了。根據這個特性,emptyDir 特別適合 Pod 中的容器需要臨時共享存儲空間的場景,比如以下的生產者消費者用例。
1.1、創建目錄
[root@manage01 kubernetes]# mkdir /opt/kubernetes/volume/
[root@manage01 volume]# vi volume-emptydir.yaml
1.2、創建emptydir
#創建producer-consumer Pod 包含兩個容器 producer和 consumer,它們共享一個 Volume。
#producer 負責往 Volume 中寫數據,consumer 則是從 Volume 讀取數據。
volume-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
name: producer-consumer
spec:
containers:
- name: producer
image: busybox
volumeMounts:
- name: shared-volume
mountPath: /producer_dir
args:
- /bin/sh
- -c
- echo "hello world" > /producer_dir/hello; sleep 30000
- name: consumer
image: busybox
volumeMounts:
- name: shared-volume
mountPath: /consumer_dir
args:
- /bin/sh
- -c
- cat /consumer_dir/hello; sleep 30000
volumes:
- name: shared-volume
emptyDir: {}
1.3、執行
[root@manage01 volume]# kubectl apply -f volume-emptydir.yaml
pod/producer-consumer created
[root@manage01 volume]# kubectl get pod
NAME READY STATUS RESTARTS AGE
producer-consumer 2/2 Running 0 17m
#kubectl logs 顯示容器 consumer 成功讀到了 producer 寫入的數據,驗證了兩個容器共享 emptyDir Volume。
[root@manage01 volume]# kubectl logs producer-consumer consumer
hello world
三、hostPath
#hostPath Volume 的作用是將 Docker Host 文件系統中已經存在的目錄 mount 給 Pod 的容器。大部分應用都不會使用 hostPath Volume,因爲這實際上增加了 Pod 與節點的耦合,限制了 Pod 的使用。不過那些需要訪問 Kubernetes 或 Docker 內部數據(配置文件和二進制庫)的應用則需要使用 hostPath。
#當運行的容器需要訪問Docker內部結構時,如使用hostPath映射/var/lib/docker到容器;
當在容器中運行cAdvisor時,可以使用hostPath映射/dev/cgroups到容器中;
[root@manage01 volume]# cat volume-hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-volume
spec:
containers:
- name: nginx-volume
image: nginx
volumeMounts:
- name: html
mountPath: /opt
volumes:
- name: html
hostPath:
path: /data
type: DirectoryOrCreate
[root@manage01 volume]# kubectl apply -f volume-emptydir.yaml
[root@manage01 volume]# kubectl exec -it pod/nginx-volume bash
#需要注意的是/data目錄可能掛載隨機節點上面
四、pv&&pvc
PersistenVolume(PV,持久卷):對存儲抽象實現,使得存儲作爲集羣中的資源。
PersistenVolumeClaim(PVC,持久卷申請):PVC消費PV的資源
Pod申請PVC作爲捲來使用,集羣通過PVC查找綁定的PV,並Mount給Pod。
#使用了PV後,可以把nfs或glusterfs等網絡文件系統事先創建PV數據卷,然後用pvc關聯起來,在使用的時候直接指定pvc即可,這樣可以省去指定網絡存儲IP和地址的麻煩。說白了持久卷技術首先通過異地存儲,安全持久性較好,通過pvc申請pv機制,是的用戶或者開發人員直接通過pvc申請空間即可,我只要知道我需要10G空間就夠了,通過pvc傳達下去,至於給我分配哪塊空間或者怎麼分配沒必要知道,可降低開發與運維之間耦合。
nfs服務器實現持久化
4.1、搭建nfs服務器
#nfs服務端部署配置啓動
[root@node02 /]# mkdir -p /nfsdata/pv1 && chmod -R 755 /nfsdata
[root@node02 /]# yum install -y nfs-utils rpcbind
[root@node02 /]# cat /etc/exports
/nfsdata *(rw,no_root_squash,no_all_squash,sync)
[root@node02 /]# systemctl start rpcbind && systemctl enable rpcbind
[root@node02 /]# systemctl start nfs && systemctl enable nfs
#nfs客戶端部署測試
[root@manage01 volume]# yum install -y nfs-utils
[root@manage01 volume]# showmount -e 192.168.192.130
Export list for 192.168.192.130:
/nfsdata *
4.2、創建pv&&pvc
#創建pv和pvc
[root@manage01 volume]# cat nfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
labels:
#相當於標籤供pvc調用
release: "nfs"
spec:
capacity:
#指定pv容量爲5G
storage: 5Gi
accessModes:
#PV能以read-write模式mount到單個節點
- ReadWriteMany
#Retain–需要管理員手工回收。
#Recycle–清除PV中的數據,效果相當於執行rm -rf /volume/*。
#Delete–刪除Storage Provider上的對應存儲資源,例如AWS EBS、GCE PD、Azure Disk等
persistentVolumeReclaimPolicy: Recycle
nfs:
#nfs服務器對應的目錄和ip
path: /nfsdata/pv1
server: 192.168.192.130
[root@manage01 volume]# cat nfs-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc001
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
selector:
matchLabels:
release: "nfs"
#查詢結果
[root@manage01 volume]# kubectl create -f nfs-pv.yaml
[root@manage01 volume]# kubectl create -f nfs-pvc.yaml
[root@manage01 volume]# kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/nfs-pv 5Gi RWX Recycle Bound default/pvc001 17s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/pvc001 Bound nfs-pv 5Gi RWX 13s
4.3、創建容器關聯pvc
#創建容器並指定pvc,用來分配pv空間
[root@manage01 volume]# cat nfs-pvc-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-pvc
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: haha
mountPath: /usr/share/nginx/html
ports:
- containerPort: 80
volumes:
- name: haha
persistentVolumeClaim:
claimName: pvc001
可能出現的錯誤:
error: error validating "nfs-pvc-deployment.yaml": error validating data: ValidationError(Deployment.spec): missing required field "selector" in io.k8s.api.apps.v1.DeploymentSpec; if you choose to ignore these errors, turn validation off with --validate=false
解決方法:https://stackoverflow.com/questions/59480373/
[root@manage01 volume]# kubectl create -f nfs-pvc-deployment.yaml
4.4、測試結果
此時,nginx容器/usr/share/nginx/html目錄與nfs服務器(192.168.192.130)/nfsdata/pv1目錄關聯
#nfs服務器創建文件,nginx容器目錄同步成功
[root@node02 pv1]# touch index.html && echo "hello,k8s-nfs01" > index.html
[root@manage01 volume]# kubectl exec -it nginx-deployment-pvc-57578c86fc-fb9v9 bash
root@nginx-deployment-pvc-57578c86fc-fb9v9:/# cat /usr/share/nginx/html/index.html
hello,k8s-nfs01
#nginx容器創建文件,nfs服務器目錄同步成功
root@nginx-deployment-pvc-57578c86fc-fb9v9:/usr/share/nginx/html# touch index2.html
[root@node02 pv1]# ll
-rw-r--r-- 1 root root 0 3月 13 23:34 index2.html
-rw-r--r-- 1 root root 16 3月 13 23:32 index.html
#刪除pod,對存儲卷無影響
[root@manage01 volume]# kubectl delete deployment.apps/nginx-deployment-pvc
[root@node02 pv1]# ll
-rw-r--r-- 1 root root 0 3月 13 23:34 index2.html
-rw-r--r-- 1 root root 16 3月 13 23:32 index.html
#刪除pv後,存儲卷數據也清理成功(之前Recycle處理機制配置的原因)
[root@manage01 volume]# kubectl delete persistentvolumeclaim/pvc001
[root@manage01 volume]# kubectl delete persistentvolume/nfs-pv
[root@node02 pv1]# ll
總用量 0