由于容器和Pod是短暂的,会被频繁销毁和创建,容器销毁时,内部的文件系统也会被清理。为了持久化保存容器的数据,可以使用Kubernates
Volume
emptyDir Volume
emptyDir是Host上的一个空目录,对于容器是持久化的,对于Pod不是。emptyDir
Volume的生命周期与Pod一致
适用场景:
Pod中的容器需要通过文件传递数据
 
Pod中的容器临时共享存储空间
 
hostPath Volume
hostPath
Volume将Host文件系统中已有的目录mount给Pod的容器,这样会将Pod与节点耦合,限制了Pod的创建
适用场景:需要访问kubernetes或docker内部数据(配置文件或二进制文件)的应用
云存储
如Elastic Block Store
PV&PVC
Persistent
Volume(PV)是外部存储系统中的一块空间,由管理员创建和维护。具有持久性,生命周期独立于Pod
Persistent Volume
Claim(PVC)是对PV的申请,由普通账号创建和维护,需要为Pod分配存储资源时,用户创建一个PVC,指明存储资源的小大和访问权限等信息
k8s支持的PV类型有:EBS,Ceph,NFS等
Think:为什么不直接为Pod创建云存储空间,而是通过PV-PVC
NFS
NFS(network file
system)通过网络,使不同的机器不同的系统实现文件共享。NFS客户端可以将NFS服务器共享的目录挂载到本地的文件系统中,访问目录如同访问本地目录一样
创建NFS服务器
在node1节点安装nfs服务
1 2 3 4 5 6 7 8 9 10 11
   | # 安装nfs服务组件 yum install nfs-utils -y mkdir /home/work/nfs cat > /etc/exports <<EOF /home/work/nfs 192.168.174.0/24(rw,sync,no_root_squash) EOF systemctl start rpcbind systemctl start nfs cd /etc exportfs -r netstat -ntlp
   | 
 
客户端配置
搜索网络中可用的共享目录 showmount -e node1
创建本地目录并挂载共享目录
1 2 3
   | mkdir /home/work/mnt mount -t nfs node1:/home/work/nfs /home/work/mnt cd /home/work/mnt && ll
   | 
 
创建PV
编写配置文件 nfs-pv1.yml,手动创建PV的方式叫静态供给
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 38 39 40 41 42 43 44
   | apiVersion: v1 kind: PersistentVolume metadata:     name: pv-nginx-html spec:     capacity:         storage: 2Gi     accessModes:         - ReadWriteMany     persistentVolumeReclaimPolicy: Retain     storageClassName: nginx-html     nfs:         path: /home/work/nfs/nginx/html         server: node1 --- apiVersion: v1 kind: PersistentVolume metadata:     name: pv-nginx-log spec:     capacity:         storage: 2Gi     accessModes:         - ReadWriteMany     persistentVolumeReclaimPolicy: Retain     storageClassName: nginx-log     nfs:         path: /home/work/nfs/nginx/log         server: node1 --- apiVersion: v1 kind: PersistentVolume metadata:     name: pv-nginx-conf spec:     capacity:         storage: 2Gi     accessModes:         - ReadWriteMany     persistentVolumeReclaimPolicy: Retain     storageClassName: nginx-conf     nfs:         path: /home/work/nfs/nginx/conf         server: node1
   | 
 
说明:
- capacity指定PV容量
 
- accessModes 指定访问模式:
- ReadWriteOnce:可读可写,只支持被单个节点挂载
 
- ReadOnlyMany:只读,可被多个节点挂载
 
- ReadWriteMany:可读可写,被多个节点挂载
 
 
- persistentVolumeReclaimPolicy 指定PV的回收策略:
- Retain:管理员手动清理
 
- Recycle:删除数据(NFS和HostPath支持)
 
- Delete:删除存储资源(EBS等云存储支持)
 
 
- storageClassName 指定PV的类型为nfs
 
- nfs的path需要是nfs服务器是存在的路径
 
创建pv1:Kubectl apply -f nfs-pv1.yml
查看pv:kubectl get pv
创建pvc
编写配置文件 nfs-pvc1.yml
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
   | kind: PersistentVolumeClaim apiVersion: v1 metadata:     name: nginx-html-pvc spec:     accessModes:         - ReadWriteMany     resources:         requests:             storage: 1Gi     storageClassName: nginx-html --- kind: PersistentVolumeClaim apiVersion: v1 metadata:     name: nginx-conf-pvc spec:     accessModes:         - ReadWriteMany     resources:         requests:             storage: 1Gi     storageClassName: nginx-conf --- kind: PersistentVolumeClaim apiVersion: v1 metadata:     name: nginx-log-pvc spec:     accessModes:         - ReadWriteMany     resources:         requests:             storage: 1Gi     storageClassName: nginx-log
   | 
 
创建pvc:kubectl apply -f nfs-pvc1.yml
查看pvc:kubectl get pvc
在Pod中使用存储
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 38 39 40 41 42 43
   | apiVersion: apps/v1 kind: Deployment metadata:   labels:     app: nginx   name: nginx-deployment spec:   replicas: 2   selector:     matchLabels:       app: nginx   template:     metadata:       labels:         app: nginx     spec:       containers:       - name: nginx         image: nginx:1.7.9         ports:         - containerPort: 80         volumeMounts:         - name: nginx-log           mountPath: /var/log/nginx         - name: nginx-html           mountPath: /etc/nginx/html         - name: nginx-conf-d           mountPath: /etc/nginx/conf.d       tolerations:       - key: "key"         operator: "Equal"         value: "nginx"         effect: "NoSchedule"       volumes:       - name: nginx-log         persistentVolumeClaim:           claimName: nginx-log-pvc       - name: nginx-html         persistentVolumeClaim:           claimName: nginx-html-pvc       - name: nginx-conf-d         persistentVolumeClaim:           claimName: nginx-conf-pvc
   | 
 
这样,将容器内nginx的html、conf、log挂载到nfs服务器上,方便编写页面、修改配置、查看日志
Think:多个应用要挂载路径可能很多,需要创建很多的PV和PVC,管理很不方便,而且PV一般由管理员创建,PVC由开发人员创建,如果每个挂载路径都要要求管理员创建PV,效率低下,不便于管理,该如何解决
Think:在nfs中修改nginx配置文件后,需要重启Pod才可以让配置生效,如果让Pod按照顺序先后重启,而不是全部同时重启
回收PV
kubectl delete pvc {pvc_name}
PV 动态供给
静态供给的缺点有:
- 需要提前创建PV,还需要在nfs等共享存储上提前创建目录,管理员的工作增加,效率低;
 
- 维护成本高
 
为了解决上面的问题,使用动态共给
https://kubernetes.io/docs/concepts/storage/storage-classes/#nfs
安装动态pv
使用helm安装nfs-client-provisioner:helm install nfs-client-provisioner stable/nfs-client-provisioner --set nfs.server=node1 --set nfs.path=/home/work/nfs --set storageClass.defaultClass=true --set image.repository=rkevin/nfs-subdir-external-provisioner --set image.tag=fix-k8s-1.20
验证
1 2 3 4 5 6 7 8 9 10 11 12 13
   | cat > test-pvc.yaml << EOF apiVersion: v1 kind: PersistentVolumeClaim metadata:   name: test-nfs-pvc spec:   accessModes:   - ReadWriteMany   storageClassName: nfs-client   resources:     requests:       storage: 1Gi EOF
   | 
 
image-20220417035033623
image-20220417035117442
image-20220417035331218
无需手动创建pv
存在问题
- 为什么不直接为Pod创建云存储空间,而是通过PV-PVC(创建的云存储空间是一次性创建很大一块空间,应用是很多的,每个应用都挂载到一个独立的云存储空间不利于管理和维护,容易造成空间的浪费)
 
- 挂载路径太多,PV&PVC不便于管理,如何解决(答案:PV的动态供给)
 
- 重启nginx服务,如何不全部同时重启,防止服务不可用