为什么需要存储卷
容器部署过程中一般有以下三种数据:

数据卷概述
数据卷类型大致分类:
- 
本地(hostPath,emptyDir等)
 
- 
网络(NFS,Ceph,GlusterFS等)
 
- 
公有云(AWS EBS等)
 
- 
K8S资源(configmap,secret等)
 
支持的数据劵类型:https://kubernetes.io/docs/concepts/storage/volumes/
数据卷:emptyDir
emptyDir卷:是一个临时存储卷,与Pod生命周期绑定一起,如果 Pod删除了卷也会被删除。
应用场景:Pod中容器之间数据共享
示例:Pod内容器之前共享数据
vim emptyDir.yaml
apiVersion: v1 kind: Pod metadata:   name: emptydir-pod spec:   containers:   - name: write     image: centos     command: ["bash","-c","for i in {1..100};do echo $i >> /data/hello;sleep 1;done"]     volumeMounts:     - name: data       mountPath: /data   - name: read     image: centos     command: ["bash","-c","tail -f /data/hello"]     volumeMounts:     - name: data       mountPath: /data
    volumes:   - name: data     emptyDir: {}
 
   | 
 
验证查看
kubectl apply -f emptyDir.yaml  kubectl get pod  kubectl exec -it emptydir-pod -c write -- bash   
  kubectl exec -it emptydir-pod -c read -- bash    
 
 
 
  kubectl get pod -o wide  
  docker ps -l          /var/lib/kubelet/pods/53d07406-364b-4d85-90b9-e3a6dca15427/volumes/kubernetes.io~empty-dir/data
 
   | 
 
数据卷:hostPath
hostPath卷:挂载Node文件系统(Pod所在节点)上文件或者目 录到Pod中的容器。
应用场景:Pod中容器需要访问宿主机文件
示例:将宿主机/tmp目录挂载到容器/data目录
vim hostpath.yaml
apiVersion: v1 kind: Pod metadata:   name: hostpath-pod spec:   containers:   - name: busybox     image: busybox     args:     - /bin/sh     - -c     - sleep 36000     volumeMounts:     - name: data       mountPath: /data
    volumes:   - name: data     hostPath:       path: /tmp       type: Directory
 
   | 
 
验证查看
kubectl apply -f hostpath.yaml  kubectl get pod -o wide      kubectl exec -it hostpath-pod -- sh
 
  在pod所在节点的/tmp目录下创建文件,验证pod中/data目录下能否看见 touch /tmp/xiaozhe.txt 
   | 
 
数据卷:NFS
NFS数据卷:提供对NFS挂载支持,可以自动将NFS共享 路径挂载到Pod中
NFS:是一个主流的文件共享服务器。

 yum install nfs-utils
 
  mkdir -p /nfs/kubernetes
 
  vim /etc/exports /nfs/kubernetes *(rw,no_root_squash)
 
  systemctl start nfs systemctl enable nfs
 
  mount -t nfs 192.168.0.13:/nfs/kubernetes /mnt/
 
  touch /mnt/index.html ls /nfs/kubernetes/
 
  | 
 
示例:将网站程序通过NFS数据卷共享,让所有Pod使用
vim nfs.yaml
apiVersion: apps/v1 kind: Deployment metadata:   name: nfs-deployment spec:   selector:     matchLabels:       app: nfs-nginx   replicas: 3   template:     metadata:       labels:         app: nfs-nginx     spec:       containers:       - name: nginx         image: nginx         volumeMounts:         - name: wwwroot           mountPath: /usr/share/nginx/html         ports:         - containerPort: 80
        volumes:       - name: wwwroot         nfs:           server: 192.168.0.13           path: /nfs/kubernetes
 
   | 
 
验证查看
kubectl apply -f nfs.yaml  kubectl get pod -o wide
 
  echo hello > index.html curl 10.244.36.74      hello
   | 
 
持久卷概述
PersistentVolume(PV):对存储资源创建和使用的抽象,使得存储作为集群中的资源管理 • PersistentVolumeClaim(PVC):让用户不需要关心具体的Volume实现细节
PV与PVC使用流程

支持持久卷的存储插件:https://kubernetes.io/docs/concepts/storage/persistent-volumes/
vim pv.yaml
apiVersion: v1 kind: PersistentVolume metadata:   name: my-pv spec:   capacity:     storage: 5Gi   accessModes:     - ReadWriteMany   nfs:     path: /nfs/kubernetes     server: 192.168.0.13
 
   | 
 
vim pvc-deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata:   name: pvc-deployment spec:   selector:     matchLabels:       app: pvc-nginx   replicas: 3   template:     metadata:       labels:         app: pvc-nginx     spec:       containers:       - name: nginx         image: nginx         volumeMounts:         - name: wwwroot           mountPath: /usr/share/nginx/html         ports:         - containerPort: 80
        volumes:       - name: wwwroot         persistentVolumeClaim:           claimName: my-pvc --- apiVersion: v1 kind: PersistentVolumeClaim metadata:   name: my-pvc spec:   accessModes:     - ReadWriteMany   resources:     requests:       storage: 5Gi
 
   | 
 
验证访问
kubectl apply -f pv.yaml  kubectl apply -f pvc-deployment.yaml  kubectl get pv,pvc kubectl get pod -o wide      curl 10.244.169.139          hello
   | 
 

PV 生命周期
ACCESS MODES(访问模式):
AccessModes 是用来对 PV 进行访问模式的设置,用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:
- 
ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载
 
- 
ReadOnlyMany(ROX):只读权限,可以被多个节点挂载
 
- 
ReadWriteMany(RWX):读写权限,可以被多个节点挂载
 
RECLAIM POLICY(回收策略):
目前 PV 支持的策略有三种:
- 
Retain(保留): 保留数据,需要管理员手工清理数据
 
- 
Recycle(回收):清除 PV 中的数据,效果相当于执行 rm -rf /ifs/kuberneres/*
 
- 
Delete(删除):与 PV 相连的后端存储同时删除
 
STATUS(状态):
一个 PV 的生命周期中,可能会处于4中不同的阶段:
- 
Available(可用):表示可用状态,还未被任何 PVC 绑定
 
- 
Bound(已绑定):表示 PV 已经被 PVC 绑定
 
- 
Released(已释放):PVC 被删除,但是资源还未被集群重新声明
 
- 
Failed(失败): 表示该 PV 的自动回收失败
 
现在PV使用方式称为静态供给,需要K8s运维工程师提前创 建一堆PV,供开发者使用。

在nfs服务器共享目录下创建多个目录,供下面引用不同的pv匹配不同的pv目录
cd /nfs/kubernetes/ mkdir pv{2,3,4} cd pv2/ echo 222 >index.html cd ../pv4/ echo 444 >index.html    
   | 
 
vim pv234.yaml
apiVersion: v1 kind: PersistentVolume metadata:   name: pv2 spec:   capacity:     storage: 3Gi   accessModes:     - ReadWriteMany   nfs:     path: /nfs/kubernetes/pv2     server: 192.168.0.13 --- apiVersion: v1 kind: PersistentVolume metadata:   name: pv3 spec:   capacity:     storage: 5Gi   accessModes:     - ReadWriteMany   nfs:     path: /nfs/kubernetes/pv3     server: 192.168.0.13 --- apiVersion: v1 kind: PersistentVolume metadata:   name: pv4 spec:   capacity:     storage: 10Gi   accessModes:     - ReadWriteMany   nfs:     path: /nfs/kubernetes/pv4     server: 192.168.0.13
 
   | 
 
vim pvc234-deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata:   name: pvc234-deployment spec:   selector:     matchLabels:       app: pvc234-nginx   replicas: 3   template:     metadata:       labels:         app: pvc234-nginx     spec:       containers:       - name: nginx         image: nginx         volumeMounts:         - name: wwwroot           mountPath: /usr/share/nginx/html         ports:         - containerPort: 80
        volumes:       - name: wwwroot         persistentVolumeClaim:           claimName: pv2 --- apiVersion: v1 kind: PersistentVolumeClaim metadata:   name: pv2 spec:   accessModes:     - ReadWriteMany   resources:     requests:       storage: 8Gi
 
   | 
 
验证查看
kubectl apply -f pv234.yaml  kubectl apply -f pvc234-deployment.yaml  kubectl get pv,pvc
   | 
 

从上面pvc234-deployment.yaml 文件配置可以看到,配置文件指定的pvc是pv2,使用最大容量是8Gi,但是pv2的容量可以看到是3Gi,并不满足你要使用的容量,但是为了尽可能的分配给你,所以它将pv4指定了给你使用,pv4的容量是10Gi。
访问
kubectl get pod -o wide     curl 10.244.36.76         444                      
   | 
 
PV 动态供给(StorageClass)
PV静态供给明显的缺点是维护成本太高了!
因此,K8s开始支持PV动态供给,使用StorageClass对象实现。

支持动态供给的存储插件:https://kubernetes.io/docs/concepts/storage/storage-classes/

部署NFS实现自动创建PV插件:
git clone https://github.com/kubernetes-incubator/external-storage  cd nfs-client/deploy  kubectl apply -f rbac.yaml  kubectl apply -f deployment.yaml  kubectl apply -f class.yaml 
  kubectl get sc  
   | 
 
nfs-client.zip
#修改deployment.yaml 修改里面NFS服务器地址与共享目录

vim sc-deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata:   name: sc-deployment spec:   selector:     matchLabels:       app: sc-nginx   replicas: 3   template:     metadata:       labels:         app: sc-nginx     spec:       containers:       - name: nginx         image: nginx         volumeMounts:         - name: wwwroot           mountPath: /usr/share/nginx/html         ports:         - containerPort: 80
        volumes:       - name: wwwroot         persistentVolumeClaim:           claimName: nfs-pvc --- apiVersion: v1 kind: PersistentVolumeClaim metadata:   name: nfs-pvc spec:   storageClassName: "managed-nfs-storage"     accessModes:     - ReadWriteMany   resources:     requests:       storage: 12Gi
 
   | 
 
kubectl apply -f sc-deployment.yaml  kubectl get pv,pvc
   | 
 

从上图可以看出当我们使用kubectl创建一个deployment时,它会请求managed-nfs-storage(nfs存储类),然后managed-nfs-storage调用nfs-client-provisioner插件(pod),帮我们自动创建pv。
访问
 cd /nfs/kubernetes/default-nfs-pvc-pvc-2a62f7d8-b356-45d0-87cb-018c10447595 echo sc > index.html kubectl get pod -o wide curl 10.244.169.142       sc
 
  | 
 
删除deployment
kubectl delete -f sc-deployment.yaml
   | 
 
在nfs服务器上的共享目录查看



从上面可以看出,nfs的回收策略是deployment删除后端的存储也同时删除,但是当我们把deployment删除之后,数据共享目录还在,并没有删除,它只是帮我们把数据共享目录归档了,如果要删除需要修改class.yaml 配置文件中的archiveOnDelete为false,这时就会帮我们删除后端数据共享目录。

kubectl apply -f class.yaml   kubectl delete -f sc-deployment.yaml    kubectl apply -f sc-deployment.yaml    
 
  cd /nfs/kubernetes/default-nfs-pvc-pvc-d5ca3b6e-7045-4868-8fdf-17063bc19e13 echo 123456 > index.html kubectl get pod -o wide curl 10.244.169.142       123456
 
  kubectl delete -f sc-deployment.yaml  
   | 
 
Q:PV与PVC什么关系?
A:一对一
Q:PVC与PV怎么匹配的?
A:访问模式和存储容量
Q:容量匹配策略
A:匹配就近的符合的容量(向上)
Q:存储容量是真的用于限制吗?
A:存储容量取决于后端存储,容量字段主要还是用于匹配
1、使用Ingress暴露应用对外访问
2、创建一个configmap,使用环境变量和数据卷方式引用
3、创建一个pv,再创建一个pod使用该pv
4、配置PV自动供给,再创建一个pod使用该pv
注:自由发挥,实现需求即可