目录
一、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