emptyDir
使用emptyDir的存储方式,就是在物理机上随机地产生一个目录,然后把这个目录挂载到容器目录/xxx(不存在会自动创建)。这种存储是临时性的,是以内存为介质,并非是永久性的。在删除pod的时候,emptyDir对应的目录也会被一起删除。类似docker创建容器时的命令docker run -v /xx
#以下yaml定义了两个emptyDir类型的volume,分别挂载在demo1,demo2两个容器的/data目录下
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
aa: aa
name: demo
spec:
volumes:
- name: volume1
emptyDir: {}
- name: volume2
emptyDir: {}
containers:
- args:
- sh
- -c
- echo "hello pod"; sleep 10000
image: busybox
imagePullPolicy: IfNotPresent
name: demo1
volumeMounts:
- mountPath: /data
name: volume1
resources: {}
- name: demo2
image: busybox
imagePullPolicy: IfNotPresent
command: ['sh','-c','sleep 5000']
volumeMounts:
- mountPath: /data
name: volume1
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
hostPath
使用hostPath的存储方式,类似于在创建docker容器时的docker run -v /data:/xx, 把物理机的目录/data映射到容器的/xx目录里,如果删除了这个pod,数据仍然是保留的。如果/xx目录不存在,会自动在容器里创建,同样如果是物理机的/data目录不存在的话也会自动创建。
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
purpose: demonstrate-envars
name: demo
spec:
volumes:
- name: volume1
hostPath:
path: /data
containers:
- args:
- sh
- -c
- echo "hello pod"; sleep 10000
image: busybox
imagePullPolicy: IfNotPresent
name: demo1
volumeMounts:
- mountPath: /containerdata
name: volume1
resources: {}
- name: demo2
image: busybox
imagePullPolicy: IfNotPresent
command: ['sh','-c','sleep 5000']
volumeMounts:
- mountPath: /poddata
name: volume1
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
nfs存储
用nfs作为共享存储可以实现pod数据的共享。
持久性存储
Persistent Volume(持久性卷,pv)与指定后端存储关联,pv不属于任何namespace,全局可见。用户登录到自己的namespace之后,只要创建pvc(Persistent Volume Claim持久性卷声明),pvc会自动和pv进行绑定。一个pv只能和一个pvc进行绑定。
root@k8sdbamaster:/data/volume# cat pv1.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv01
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
nfs:
path: /xx
server: 10.99.00.11
accessModes有以下三种值,一定要确保pvc和pv的accessMode一致
ReadWriteOnce(RWO):仅允许单个节点挂载读写
ReadOnlyMany(ROX): 允许多个节点挂载只读
ReadWriteMany(RWX): 允许多个节点挂载读写
pv的回收策略persistentReclimPolicy,删除pvc之后pc是否会释放
Recycle: 删除pvc之后,会生成一个pod回收数据,删除pv里的数据,删除pvc之后,pv可复用,pv状态由Released变成available. pv中数据也被删除了。
Retain: 不回收数据,删除pvc之后,pv依然不可用,pv状态长期保持为Released。需要手动删除pv,然后重新创建,但是删除pv的时候并不会删除里面的数据
--删除pvc,查看pv状态,先是Release,然后就变成available
root@k8sdbamaster:/data/volume# kubectl delete -f pvc1.yaml
persistentvolumeclaim "pvc01" deleted
root@k8sdbamaster:/data/volume# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv01 5Gi RWO Recycle Released nsvolume/pvc01 xx 42m
root@k8sdbamaster:/data/volume# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv01 5Gi RWO Recycle Available xx 43m
查看pv属性
root@k8sdbamaster:~# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv01 5Gi RWO Recycle Available 4m4s
root@k8sdbamaster:~# kubectl describe pv pv01
pvc(PersistentVolumeClaim)是基于namespace创建的,不同的namespace里的pvc是相互隔离的。 pvc通过storage的大小和accessModes的值与pv进行绑定,即如果pvc里的storage的大小,accessModes的值与pv里的storage的大小和accessModes的值都一样的话,那么pvc和pv进行绑定。
在pv和pvc的accessModes相同的情况下,只有pv的storage大小大于等于pvc的storage的大小的时候才能绑定。在有多个pvc的情况下,可以通过storageClassName进行控制。
root@k8sdbamaster:/data/volume# kubectl get pvc -n nsvolume
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc01 Bound pv01 5Gi RWO 15s
如果要在pod中使用pvc的话,需要在pod的yaml文件中创建pvc类型的卷,然后在pod中的容器中挂载这个卷就可以
kind: Pod
metadata:
creationTimestamp: null
labels:
run: nginx1
name: nginx1
namespace: nsvolume
spec:
volumes:
- name : myv
persistentVolumeClaim:
claimName: pvc01
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx1
volumeMounts:
- mountPath: "/mnt"
name: myv
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
创建一个类型为pvc的卷,关联到名字为pvc01的pvc上
如果创建的pod状态一直是ContainerCreating,且通过kubectl describe pod查看有如下报错,可以查看物理机上nfs是否安装,可通过sudo apt install nfs-kernel-server来修复此问题。
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m25s default-scheduler Successfully assigned nsvolume/nginx1 to k8sdbaworker1
Warning FailedMount 17s (x9 over 2m25s) kubelet MountVolume.SetUp failed for volume "pv01" : mount failed: exit status 32
Mounting command: mount
动态卷供应
在持久性存储的时候需要先创建pv,然后创建pvc。如果在不同的namespace中同时要创建不同的pvc,就需要提前把pv都创建好,这样才能为pvc提供存储。 现在可以通过storageClass(sc)来解决问题。 最终效果是,只要创建好storageClass,用户创建pvc的时候, storageClass会自动创建出一个pv和这个pvc绑定。
创建存储类型为hostPath的持久性存储
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv10
spec:
capacity:
storage: 2Gi
volumeMode: Filesystem
storageClassName: cka
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
hostPath:
path: /pv10
通过kubectl在pod的container中写入数据
root@k8sdbamaster:/data/volume# kubectl exec -it pod-pvc -- bash -c "echo hi > /data/testnew.txt"