文章目錄
六、Kubernetes Storage (Kubernetes 存儲)
臨時存儲:emptydir
半持久化存儲:hostpath
持久化存儲:pvc,pv,nfs
分佈式存儲: glusterfs,rbd,cephfs,雲存儲(EBS,等)
查看K8s支持多少種存儲: kubectl explain pods.spec.volumes
K8S的存儲系統從基礎到高級又大致分爲三個層次:普通Volume,Persistent Volume 和動態存儲供應。
1.Volume
K8s中的卷壽命與封裝它的pod相同。卷比pod中所有容器的生命週期都要長,當這個容器重啓時數據仍然可以保存。Pod不存在,卷也不復存在
-
容器中的Volume
容器的 Volume,其實就是將一個宿主機上的目錄,跟一個容器裏的目錄綁定掛載在了一起。
-
持久化 Volume
宿主機上的目錄,具備“持久性”。即:這個目錄裏面的內容,既不會因爲容器的刪除而被清理掉,也不會跟當前的宿主機綁定。這樣,當容器被重啓或者在其他節點上重建出來之後,它仍然能夠通過掛載這個 Volume,訪問到這些內容。
卷類型
empityDir
hostPath
local
nfs
iscsi
persistentVolume
PersistentVolumeClain
projectd
rbd
secret
vsphereVolume
2.PV(Persistent Volume)
PV 描述的是持久化存儲卷,主要定義的是一個持久化存儲在宿主機上的目錄,比如一個 NFS 的掛載目錄。
通常由運維人員創建
- 例子1
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs
spec:
storageClassName: manual
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
server: 192.168.217.149
path: "/"
2.1 PV訪問模式
PV可以以資源提供者支持的方式掛載到主機上。供應商具有不同的功能,每個PV訪問模式都將被設置爲該卷支持的特定模式。例如NFS可以支持多個讀寫客戶端,但特定的NFS PV可能以只讀方式導出到服務器上,每個PV都有一套自己的用來描述特定功能的訪問模式。
- ReadwriteOnce(RWO) 該卷可以被單個節點以讀寫模式掛載
- ReadOnlyMany(ROX) 該卷可以被多個節點以只讀模式掛載
- ReadWriteMany(ROX) 該卷可以被多個節點以讀寫模式掛載
2.2 PVC(Persistent Volume Claim)
PVC是用戶存儲的請求。描述的則是Pod所希望使用的持久化存儲的屬性。比如Volume存儲的大小、可讀寫權限等等。
通常由開發人員創建
- 例子2
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs
spec:
accessModes:
- ReadWriteMany
storageClassName: manual
resources:
requests:
storage: 1Gi
2.3 綁定
用戶根據所需存儲空間大小和訪問模式創建(或在動態部署中已創建)一個PVC。Kubernetes的Master節點循環監控新產生的PVC,找到與之匹配的PV(如果有的話),並把他們綁定在一起。動態配置時,循環會一直將PV與這個PVC綁定,直到PV完全匹配PVC。避免PVC請求和得到的PV不一致。綁定一旦形成,PersistentVolumeClaim綁定就是獨有的,不管是使用何種模式綁定的。
如果找不到匹配的volume,用戶請求會一直保持未綁定狀態。在匹配的volume可用之後,用戶請求將會被綁定。
Volume Controller:管理多個控制循環,將PV與PVC進行綁定(PV名稱寫入PVC對象的spec.volumeName)
-
第一個條件,當然是 PV 和 PVC 的 spec 字段。比如,PV 的存儲(storage)大小,就必須滿足 PVC 的要求。
-
第二個條件,則是 PV 和 PVC 的 storageClassName 字段必須一樣。
-
例子3
apiVersion: v1
kind: Pod
metadata:
name: nginx-nfs
labels:
role: web-frontend
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
volumeMounts:
- name: nfs
mountPath: "/usr/share/nginx/html"
volumes:
- name: nfs
persistentVolumeClaim:
claimName: nfs
2.4 處理PV流程
2.4.1 兩階段
1)第一階段Attach
- 當一個 Pod 調度到一個節點上之後,kubelet 就要負責爲這個 Pod 創建它的 Volume 目錄。默認情況下,kubelet 爲 Volume 創建的目錄是如下所示的一個宿主機上的路徑
/var/lib/kubelet/pods/<Pod的ID>/volumes/kubernetes.io~<Volume類型>/<Volume名字>
- 接下來,kubelet 要做的操作就取決於你的 Volume 類型了
gcloud compute instances attach-disk <虛擬機名字> --disk <遠程磁盤名字>
2)第二階段Mount
Attach 階段完成後,爲了能夠使用這個遠程磁盤,kubelet 還要進行第二個操作,即:格式化這個磁盤設備,然後將它掛載到宿主機指定的掛載點上。
- 通過lsblk命令獲取磁盤設備ID
- 格式化成ext4格式:sudo mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard
- 掛載到掛載點:sudo mkdir -p /var/lib/kubelet/pods/<Pod的ID>/volumes/kubernetes.io~<Volume類型>/<Volume名字>
將宿主機目錄與pod定義VolumeMount目錄關聯
docker run -v /var/lib/kubelet/pods/<Pod的ID>/volumes/kubernetes.io~<Volume類型>/<Volume名字>
2.5 PV生命週期
一個PV創建完後狀態會變成Available,等待被PVC綁定。一旦被PVC邦定,PV的狀態會變成Bound,就可以被定義了相應PVC的Pod使用。Pod使用完後會釋放PV,PV的狀態變成Released。變成Released的PV會根據定義的回收策略做相應的回收工作。有三種回收策略,Retain、Delete 和 Recycle。Retain就是保留現場,K8S什麼也不做,等待用戶手動去處理PV裏的數據,處理完後,再手動刪除PV。Delete 策略,K8S會自動刪除該PV及裏面的數據。Recycle方式,K8S會將PV裏的數據刪除,然後把PV的狀態變成Available,又可以被新的PVC綁定使用。
Provisioning ——-> Binding ——–>Using——>Releasing——>Reclaiming
2.5.1 Provisioning
這裏有兩種PV的提供方式:靜態或者動態
Static
集羣管理員創建多個PV。 它們攜帶可供集羣用戶使用的真實存儲的詳細信息。 它們存在於Kubernetes API中,可用於消費。
Dynamic
當管理員創建的靜態PV都不匹配用戶的PersistentVolumeClaim時,集羣可能會嘗試爲PVC動態配置卷。 此配置基於StorageClasses:PVC必須請求一個類,並且管理員必須已創建並配置該類才能進行動態配置。 要求該類的聲明有效地爲自己禁用動態配置
2.5.2 Binding
在動態配置的情況下,用戶創建或已經創建了具有特定數量的存儲請求和特定訪問模式的PersistentVolumeClaim。 主機中的控制迴路監視新的PVC,找到匹配的PV(如果可能),並將它們綁定在一起。 如果爲新的PVC動態配置PV,則循環將始終將該PV綁定到PVC。 否則,用戶總是至少得到他們要求的內容,但是卷可能超出了要求。 一旦綁定,PersistentVolumeClaim綁定是排他的,不管用於綁定它們的模式。
如果匹配的卷不存在,PVC將保持無限期。 隨着匹配卷變得可用,PVC將被綁定。 例如,提供許多50Gi PV的集羣將不匹配要求100Gi的PVC。 當集羣中添加100Gi PV時,可以綁定PVC。
2.5.3 Using
Pod使用PVC作爲卷。 集羣檢查聲明以找到綁定的卷並掛載該卷的卷。 對於支持多種訪問模式的卷,用戶在將其聲明用作pod中的卷時指定所需的模式。
一旦用戶有聲明並且該聲明被綁定,綁定的PV屬於用戶,只要他們需要它。 用戶通過在其Pod的卷塊中包含persistentVolumeClaim來安排Pods並訪問其聲明的PV。
2.5.4 Releasing
當用戶完成卷時,他們可以從允許資源回收的API中刪除PVC對象。 當聲明被刪除時,卷被認爲是“釋放的”,但是它還不能用於另一個聲明。 以前的索賠人的數據仍然保留在必須根據政策處理的捲上.
2.5.5 Reclaiming
PersistentVolume的回收策略告訴集羣在釋放其聲明後,該卷應該如何處理。 目前,卷可以是保留,回收或刪除。 保留可以手動回收資源。 對於那些支持它的卷插件,刪除將從Kubernetes中刪除PersistentVolume對象,以及刪除外部基礎架構(如AWS EBS,GCE PD,Azure Disk或Cinder卷)中關聯的存儲資產。 動態配置的卷始終被刪除
2.5.6 回收策略
- Retain – 手動重新使用
- Recycle – 基本的刪除操作 (“rm -rf /thevolume/*”)
- Delete – 關聯的後端存儲卷一起刪除,後端存儲例如AWS EBS, GCE PD或OpenStack Cinder
目前只有NFS和HostPath支持回收,AWS EBS, GCE PD和Cinder volumes只支持刪除。
2.5.7 卷的狀態
- Available –閒置狀態,沒有被綁定到PVC
- Bound – 綁定到PVC
- Released – PVC被刪掉,資源沒有被在利用
- Failed – 自動回收失敗
2.6 StorageClass
- 人工管理PV的方式:Static Provisionning
- 自動創建PV的機制:Dynamic Provisioning:通過StorageClass實現
2.6.1 StorageClass
-
作用就是創建PV模板
PV的屬性。比如存儲類型,Volume的大小等等
創建這種PV需要用到的存儲插件。如Ceph等等
-
例子(Rook-Ceph)
StorageCalss定義
apiVersion: ceph.rook.io/v1beta1
kind: Pool
metadata:
name: replicapool
namespace: rook-ceph
spec:
replicated:
size: 3
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: block-service
provisioner: ceph.rook.io/block
parameters:
pool: replicapool
#The value of "clusterNamespace" MUST be the same as the one in which your rook cluster exist
clusterNamespace: rook-ceph
kubectl create -f sc.yaml
PVC定義
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: claim1
spec:
accessModes:
- ReadWriteOnce
storageClassName: block-service
resources:
requests:
storage: 30Gi
kubectl create -f pvc1.yaml
kubectl describe pvc claim1
2.7 PV類型
PV類型以插件形式實現。K8s目前支持如下插件類型:
NFS
RBD(Ceph Block Device)
CephFS
Cinder
Glusterfs
HostPath
VMware
GCEPersistentDisk
AWSElasticStore
AzureFile
Fibre Channel
FlexVolume
ISCSI
等
https://kubernetes.io/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes
2.8 實戰1
基於NFS類型的PV
1)首先創建NFS服務
-
yum install nfs-utils rpcbind -y
nfs-utils所有節點都需要安裝
-
systemctl restart rpcbind nfs
-
編輯共享配置文件
/etc/exports寫入/mnt/share *(rw)
exportfs -r生效
[NFS共享目錄] [NFS客戶端地址1(參數1,參數2,參數3……)] [客戶端地址2(參數1,參數2,參數3……)]
mkdir /mnt/share
chmod 777 /mnt/share
showmount -e
2)創建PV
vim pv1.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs
spec:
storageClassName: manual
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
nfs:
server: 192.168.217.149
path: "/mnt/share"
kubectl get pv
kubectl describe pv nfs
3)創建PVC
vim pvc1.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs
spec:
accessModes:
- ReadWriteMany
storageClassName: manual
resources:
requests:
storage: 1Gi
kubectl get pvc
kubectl describe pvc nfs
4)創建pod調用pvc
apiVersion: v1
kind: Pod
metadata:
name: nginx-nfs
labels:
role: web-frontend
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
volumeMounts:
- name: nfs
mountPath: "/usr/share/nginx/html"
volumes:
- name: nfs
persistentVolumeClaim:
claimName: nfs
查看
[root@kubernetes01 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-nfs 1/1 Running 0 6m10s
在/mnt/share/1寫入
[root@kubernetes01 ~]# echo hello >/mnt/share/1
[root@kubernetes01 ~]# cat /mnt/share/1
hello
進入pod查看
[root@kubernetes01 ~]# kubectl exec -it nginx-nfs /bin/bash
root@nginx-nfs:/# ls
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
root@nginx-nfs:/# ls /usr/share/nginx/html/
1
root@nginx-nfs:/# echo nginx > /usr/share/nginx/html/2
root@nginx-nfs:/# ls /usr/share/nginx/html/
1 2
root@nginx-nfs:/# cat /usr/share/nginx/html/1
hello
root@nginx-nfs:/# cat /usr/share/nginx/html/2
nginx
root@nginx-nfs:/# exit
exit
退出查看
[root@kubernetes01 ~]# cat /mnt/share/1
hello
[root@kubernetes01 ~]# cat /mnt/share/2
nginx
刪除/mnt/share/1
[root@kubernetes01 ~]# cd /mnt/share
[root@kubernetes01 share]# ls
1 2
[root@kubernetes01 share]# rm -rf 1
[root@kubernetes01 share]# ls
2
回到pod查看
[root@kubernetes01 share]# kubectl exec -it nginx-nfs /bin/bash
root@nginx-nfs:/# ls /usr/share/nginx/html/
2
2.9 實戰2
基於NFS的動態PV
NFS StorageClass
https://github.com/kubernetes-incubator/external-storage/blob/master/nfs/deploy/kubernetes
接着實戰1的環境
先做點準備工作
mkdir /nfs3
chmod 777 /nfs3
在/etc/exports寫入/nfs3 *(rw)
exportfs -r生效
1)創建RBAC授權rbac.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-provisioner-runner
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "update", "patch"]
- apiGroups: [""]
resources: ["services", "endpoints"]
verbs: ["get"]
- apiGroups: ["extensions"]
resources: ["podsecuritypolicies"]
resourceNames: ["nfs-provisioner"]
verbs: ["use"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-provisioner
subjects:
- kind: ServiceAccount
name: nfs-provisioner
namespace: default
roleRef:
kind: ClusterRole
name: nfs-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-provisioner
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-provisioner
subjects:
- kind: ServiceAccount
name: nfs-provisioner
namespace: default
roleRef:
kind: Role
name: leader-locking-nfs-provisioner
apiGroup: rbac.authorization.k8s.io
2)serviceaccount.yaml文件
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-provisioner
3)創建Storageclass類storageclass-nfs.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: nfs
provisioner: example.com/nfs
4)創建nfs的deployment,修改相應的nfs服務器ip及掛載路徑即可。deployment-nfs.yaml
拉取鏡像registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner
docker pull registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner
deployment-nfs.yaml文件內容
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: nfs-provisioner
spec:
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs-provisioner
spec:
serviceAccount: nfs-provisioner
containers:
- name: nfs-provisioner
image: registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: example.com/nfs
- name: NFS_SERVER
value: 192.168.217.149
- name: NFS_PATH
value: /nfs3
volumes:
- name: nfs-client-root
nfs:
server: 192.168.217.149
path: /nfs3
kubectl get pod
5)創建測試claim
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-claim1
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Mi
storageClassName: nfs
kubectl get pvc
6)創建一個測試的Pod使用這個PVC,編寫test-pod.yaml文件如下
kind: Pod
apiVersion: v1
metadata:
name: test-pod
spec:
containers:
- name: test-pod
image: busybox
command:
- "/bin/sh"
args:
- "-c"
- "touch /mnt/SUCCESS && exit 0 || exit 1"
volumeMounts:
- name: nfs-pvc
mountPath: "/mnt"
restartPolicy: "Never"
volumes:
- name: nfs-pvc
persistentVolumeClaim:
claimName: test-claim1
查看Pod狀態是否變爲Completed。如果是,則應該能在NFS系統的共享路徑中看到一個SUCCESS文件。
這樣,StorageClass動態創建PV的功能就成功實現了。
[root@kubernetes01 ~]# ls /nfs3/default-test-claim1-pvc-bab1c62f-8080-11ea-811d-000c29bec19e/
SUCCESS
7)創建StatefulSet案例
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx1"
replicas: 2
volumeClaimTemplates:
- metadata:
name: test
annotations:
volume.beta.kubernetes.io/storage-class: "nfs"
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
template:
metadata:
labels:
app: nginx1
spec:
serviceAccount: nfs-provisioner
containers:
- name: nginx1
image: nginx
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: "/persistentvolumes"
name: test
測試
進入web-0測試
[root@kubernetes01 ~]# ls /nfs3/default-test-web-0-pvc-306e26d2-8081-11ea-811d-000c29bec19e/
[root@kubernetes01 ~]# kubectl exec -it web-0 /bin/bash
root@web-0:/# ls /persistentvolumes/
root@web-0:/# echo hello > /persistentvolumes/1
root@web-0:/# exit
exit
回到宿主機kubernetes01
[root@kubernetes01 ~]# ls /nfs3/default-test-web-0-pvc-306e26d2-8081-11ea-811d-000c29bec19e/
1
[root@kubernetes01 ~]# cat /nfs3/default-test-web-0-pvc-306e26d2-8081-11ea-811d-000c29bec19e/1
hello
在回到web-0
[root@kubernetes01 ~]# kubectl exec -it web-0 /bin/bash
root@web-0:/# ls /persistentvolumes/
1 2
root@web-0:/# cat /persistentvolumes/2
web0
root@web-0:/# rm -rf /persistentvolumes/2
root@web-0:/# rm -rf /persistentvolumes/1
root@web-1:/# exit
exit
這時宿主機也沒有了、
而web-1和web-0是隔離的,並不互相影響。
3.Local Persistent Volume
“本地”持久化存儲,直接使用宿主機上的本機磁盤目錄,而不依賴於遠程存儲服務,來提供“持久化”的容器Volume。
3.1 應用場景
- 分佈式數據存儲:MongoDB
- 分佈式文件系統:GlusterFS,Ceph
- 進行數據緩存的分佈式應用
3.2 實現原理
-
將本地硬盤抽象成PV:一個PV一塊盤?
-
Pod正常調度到指定Node
在開始使用 Local Persistent Volume 之前,你首先需要在集羣裏配置好磁盤或者塊設備。
實現方法
- 第一種,你的宿主機掛載並格式化一個可用的本地磁盤,這也是最常規的操作;
- 第二種,對於實驗環境,你其實可以在宿主機上掛載幾個 RAM Disk(內存盤)來模擬本地磁盤。
3.3 實戰
採用第二種
1)在kubernetes02宿主機上創建掛載點,用RAM Disk模擬本地磁盤
# 在kubernetes02上執行
$ mkdir /mnt/disks
$ for vol in vol1 vol2 vol3; do
mkdir /mnt/disks/$vol
mount -t tmpfs $vol /mnt/disks/$vol
done
2)創建本地磁盤對應PV:local-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /mnt/disks/vol1
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- kubernetes02
kubectl create -f local-pv.yaml
kubectl get pv
3)創建StorageClass描述此PV:local-sc.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
provisioner: kubernetes.io/no-provisioner:因爲 Local Persistent Volume 目前尚不支持 Dynamic Provisioning,所以它沒辦法在用戶創建 PVC 的時候,就自動創建出對應的 PV。也就是說,我們前面創建 PV 的操作,是不可以省略的。
volumeBindingMode=WaitForFirstConsumer:延遲綁定,當你提交了 PV 和 PVC 的 YAML 文件之後,Kubernetes 就會根據它們倆的屬性,以及它們指定的 StorageClass 來進行綁定。只有綁定成功後,Pod 才能通過聲明這個 PVC 來使用對應的 PV。
Pod 聲明 PVC pvc1,node Affinity: node2
local PV: pv1,pv2
pv1:磁盤所在的節點node1。。。。pvc1和pv1綁定了。
pv2:磁盤所在的節點node2
#kubectl create Pod
所以pvc的綁定不能夠提前
4)創建PVC:local-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: example-local-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: local-storage
kubectl create -f local-pvc.yaml
kubectl get pvc
5)編寫pod使用這個PVC pod.yaml
kind: Pod
apiVersion: v1
metadata:
name: example-pv-pod
spec:
volumes:
- name: example-pv-storage
persistentVolumeClaim:
claimName: example-local-claim
containers:
- name: example-pv-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: example-pv-storage
6)測試文件寫入
[root@kubernetes01 ~]# kubectl exec -it example-pv-pod /bin/bash
root@example-pv-pod:/usr/share/nginx/html# ls
root@example-pv-pod:/usr/share/nginx/html# echo hello > test.txt
root@example-pv-pod:/usr/share/nginx/html# ls
test.txt
# 在kubernetes02上
[root@kubernetes02 ~]# ls /mnt/disks/vol1
test.txt
[root@kubernetes02 ~]# cat /mnt/disks/vol1/test.txt
hello
7)刪除pod測試
[root@kubernetes01 ~]# kubectl delete -f pod.yaml
# 回到kubernetes02
[root@kubernetes02 ~]# ls /mnt/disks/vol1
hello test.txt
這時會發現原來數據還在
再次創建pod.yaml
[root@kubernetes01 ~]# kubectl apply -f pod.yaml
pod/example-pv-pod created
[root@kubernetes01 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
example-pv-pod 1/1 Running 0 25s
[root@kubernetes01 ~]# kubectl exec -it example-pv-pod /bin/bash
root@example-pv-pod:/# ls /usr/share/nginx/html/
hello test.txt
root@example-pv-pod:/#
這時會發現上次pod創建的數據還在,神奇。。。。
root@example-pv-pod:/# echo shenqi > /usr/share/nginx/html/zhenshenqi
# 回到kubernetes02
[root@kubernetes02 ~]# ls /mnt/disks/vol1
hello test.txt zhenshenqi
確實神奇。。。
4.總結
4.1 Volume
單節點Volume是最簡單的普通Volume,它和Docker的存儲卷類似,使用的是Pod所在K8S節點的本地目錄。具體有兩種,一種是 emptyDir,是一個匿名的空目錄,由Kubernetes在創建Pod時創建,刪除Pod時刪除。另外一種是 hostPath,與emptyDir的區別是,它在Pod之外獨立存在,由用戶指定路徑名。這類和節點綁定的存儲卷在Pod遷移到其它節點後數據就會丟失,所以只能用於存儲臨時數據或用於在同一個Pod裏的容器之間共享數據。
4.2 PV
普通Volume和使用它的Pod之間是一種靜態綁定關係,在定義Pod的文件裏,同時定義了它使用的Volume。Volume 是Pod的附屬品,我們無法單獨創建一個Volume,因爲它不是一個獨立的K8S資源對象。
而Persistent Volume 簡稱PV是一個K8S資源對象,所以我們可以單獨創建一個PV。它不和Pod直接發生關係,而是通過Persistent Volume Claim,簡稱PVC來實現動態綁定。Pod定義裏指定的是PVC,然後PVC會根據Pod的要求去自動綁定合適的PV給Pod使用。
4.3 PVC
4.4 LPV
4.5 PV和普通Volume的區別是什麼
普通Volume和使用它的Pod之間是一種靜態綁定關係,在定義Pod的文件裏,同時定義了它使用的Volume。Volume 是Pod的附屬品,我們無法單獨創建一個Volume,因爲它不是一個獨立的K8S資源對象。
而Persistent Volume 簡稱PV是一個K8S資源對象,所以我們可以單獨創建一個PV。它不和Pod直接發生關係,而是通過Persistent Volume Claim,簡稱PVC來實現動態綁定。Pod定義裏指定的是PVC,然後PVC會根據Pod的要求去自動綁定合適的PV給Pod使用。
PV的訪問模式有三種:
第一種,ReadWriteOnce:是最基本的方式,可讀可寫,但只支持被單個Pod掛載。
第二種,ReadOnlyMany:可以以只讀的方式被多個Pod掛載。
第三種,ReadWriteMany:這種存儲可以以讀寫的方式被多個Pod共享。不是每一種存儲都支持這三種方式,像共享方式,目前支持的還比較少,比較常用的是NFS。在PVC綁定PV時通常根據兩個條件來綁定,一個是存儲的大小,另一個就是訪問模式。