linux|在K8S中使用PVC持久卷

一、系统环境
CentOS Linux release 7.9.2009 (Core)
kubectl-1.20.4-0.x86_64
kubelet-1.20.4-0.x86_64
kubeadm-1.20.4-0.x86_64
kubernetes-cni-0.8.7-0.x86_64
二、k8s架构

master 192.168.10.127
node01 192.168.10.124
node02 192.168.10.125
node03 192.168.10.126
nfs 192.168.10.143
在这里我使用一台独立的服务器做网络存储存储,具体逻辑:
NFS==>PV==>PVC
三、基本概念
Volumn
由于容器本身是非持久化的,因此需要解决在容器中运行应用程序遇到的一些问题。首先,当容器崩溃时,kubelet将重新启动容器,但是写入容器的文件将会丢失,容器将会以镜像的初始状态重新开始;第二,在通过一个Pod中一起运行的容器,通常需要共享容器之间一些文件。Kubernetes通过卷解决上述的两个问题。
在Docker有卷的概念卷,但Docker中存储卷只是磁盘的或另一个容器中的目录,并没有对其生命周期进行管理。Kubernetes的存储卷有自己的生命周期,它的生命周期与使用的它Pod生命周期一致。因此,相比于在Pod中运行的容器来说,存储卷的存在时间会比的其中的任何容器都长,并且在容器重新启动时会保留数据。当然,当Pod停止存在时,存储卷也将不再存在。在Kubernetes支持多种类型的卷,而Pod可以同时使用各种类型和任意数量的存储卷。在Pod中通过指定下面的字段来使用存储卷:
  • spec.volumes:通过此字段提供指定的存储卷
  • spec.containers.volumeMounts:通过此字段将存储卷挂接到容器中
Persistent Volumn(PV)
PV是系统管理员设置的存储,它是群集的一部分,是一种资源,所以它有独立于Pod的生命周期。
PVC是用户存储的请求。它与Pod相似,Pod消耗节点的CPU和内存资源,PVC则消耗PV资源,可以生命特定的容量大小和访问模式。
PV和PVC遵循如下的生命周期管理
配置
PV有两种配置方式:静态或动态
  • 静态
    管理员创建静态一些PV,它们带有可供集群用户使用的实际存储的细节,它们存在于Kubernetes API中,可用于消费;
  • 动态
    当管理员创建的静态 PV 都不匹配用户的 PersistentVolumeClaim 时,集群可能会尝试动态地为 PVC 创建卷。此配置基于 StorageClasses:PVC 必须请求存储类,并且管理员必须创建并配置该类才能进行动态创建。声明该类为 "" 可以有效地禁用其动态配置。
要启用基于存储级别的动态存储配置,集群管理员需要启用 API server 上的 DefaultStorageClass 准入控制器。例如,通过确保 DefaultStorageClass 位于 API server 组件的 --admission-control 标志,使用逗号分隔的有序值列表中,可以完成此操作。有关 API server 命令行标志的更多信息,请检查 kube-apiserver 文档。
绑定
一旦用户创建或已经创建了具有特定存储量的 PersistentVolumeClaim 以及某些访问模式。Kubernetes控制器会监视到新的 PVC,并寻找匹配的 PV,并将它们绑定在一起。如果为新的 PVC 动态调配 PV,则控制器会始终将该 PV 绑定到 PVC。总之,用户总会得到他们所请求的存储,但是容量可能超出请求的数量。一旦 PV 和 PVC 绑定后,PersistentVolumeClaim 绑定是排他性的,不管它们是如何绑定的。 PVC 跟 PV 绑定是一对一的映射。
如果没有匹配的PV,PVC将无限期地保持未绑定状态。随着匹配PV的可用,PVC将被绑定。例如,配置了许多 50Gi PV的集群将不会匹配请求 100Gi 的PVC。将100Gi PV 添加到群集时,则可以绑定到该 PVC。
使用
Pod 使用PVC作为卷。集群检查PVC以查找绑定的卷并为集群挂载该卷。对于支持多种访问模式的卷,用户指定在使用声明作为容器中的卷时所需的模式(读写、只读)。
用户生命了PVC,并且该PVC是绑定的,则只要用户需要,绑定的 PV 就属于该用户。用户通过在 Pod 的 volume 配置中包含persistentVolumeClaim来调度 Pod 并访问用户声明的 PV。
四、安装NFS服务
1、安装软件,所有机器都需要安装以下软件
#yum -y install nfs-utils rpcbind

2、配置服务
创建共享目录
#mkdir -p /share/ #chmod 777 /share/#echo "/share 192.168.10.0/24(rw,sync,no_root_squash)" >>/etc/exports

192.168.10.0/24共享目录的客户端ip地址
(rw,sync) ,其中rw代表拥有读写的权限,sync代表数据同步写入NFS服务器端的硬盘中。也可以用async,async是大数据时使用,是先写到缓存区,再写到磁盘里。
no_root_squash:登入 NFS 主机使用分享目录的使用者,如果是 root 的话,那么对于这个分享的目录来说,他就具有 root 的权限!这个项目『极不安全』,不建议使用!

root_squash:在登入 NFS 主机使用分享之目录的使用者如果是 root 时,那么这个使用者的权限将被压缩成为匿名使用者,通常他的 UID 与 GID 都会变成 nobody 那个系统账号的身份。
【linux|在K8S中使用PVC持久卷】#查看共享目录
#exportfs -rvexporting 192.168.10.0/24:/share

3、启动服务
systemctl enable rpcbind systemctl enable nfs systemctl enable nfs-lock systemctl enable nfs-idmapsystemctl start rpcbind systemctl start nfs systemctl start nfs-lock systemctl start nfs-idmap

4、测试nfs目录挂载
登录192.168.10.124,挂载nfs文件系统,成功后就能进入/mnt
#mount -t nfs 192.168.10.143:/share /mnt #mount -a #df -hT192.168.10.143:/share47G2.1G43G5% /mnt

五、创建PV和pvc
需要在所有k8s节点安装 nfs 客户端程序,必须在所有节点都安装 nfs 客户端,否则可能会导致 PV 挂载不上的问题。
安装命令如下:
yum -y installnfs-utils rpcbind

1、创建pv
登录到k8s的master服务器上
pv-nfs.yaml
apiVersion: v1 kind: PersistentVolume metadata: name: pv-nfs labels: type: nfs spec: capacity: storage: 5Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Recycle storageClassName: nfs nfs: path: "/share" server: 192.168.10.143 #k8s-nfs matser readOnly: false

##创建pv
#kubectl create -f pv-nfs.yamlpersistentvolume/pv-nfs created

#查看创建好的pv状态,而此时的状态是Available状态,等pvc建好后,变会变成Bond状态
# kubectl get pv NAMECAPACITYACCESS MODESRECLAIM POLICYSTATUSCLAIMSTORAGECLASSREASONAGE pv-nfs5GiRWXRecycleAvailablenfs92s

2、创建pvc
登录master服务器
pvc-nfs02.yaml
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-nfs spec: accessModes: - ReadWriteMany resources: requests: storage: 5Gi storageClassName: nfs

#创建pvc,创建好pvc后再看pv状态就变成Bound
# kubectl create -f pvc-nfs02.yaml# kubectl get pvc NAMESTATUSVOLUMECAPACITYACCESS MODESSTORAGECLASSAGE pvc-nfsBoundpv-nfs5GiRWXnfs7s# kubectl get pv NAMECAPACITYACCESS MODESRECLAIM POLICYSTATUSCLAIMSTORAGECLASSREASONAGE pv-nfs5GiRWXRecycleBounddefault/pvc-nfsnfs4m11s

六、使用PVC
使用之前的nginx配置文件,进行修改
nginx-pvc-dep.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-pvc-php74 spec: selector: matchLabels: app: nginx-pvc-php74 replicas: 1 # tells deployment to run 2 pods matching the template template: metadata: labels: app: nginx-pvc-php74 spec: containers: - name: nginx-pvc image: registry-op.test.cn/nginx2:1.14.1 ports: - containerPort: 80 resources: requests: cpu: 100m memory: 30Mi limits: cpu: 100m memory: 30Mi volumeMounts: - mountPath: /etc/nginx/nginx.conf name: nginx-php74 subPath: nginx.conf - mountPath: "/var/www/html" ##挂载容器中的目录到pvc nfs中的目录 name: storage##增加storage volumes: - name: nginx-php74 configMap: name: nginx-php-configmap items: - key: nginx_php_conf path: nginx.conf - name: storage##与前面对应 persistentVolumeClaim:##pvc声明 claimName: pvc-nfs##创建好的pvc lab name imagePullSecrets: - name: registry-op.test.cn

这里使用 nginx 镜像,将容器的 /var/www/html 目录通过 volume 挂载到名为 pvc-nfs 的 PVC 上面
创建好后,可以在存储服务器上的“/share”目录下放一个文件,然后用浏览器访问试一下能否访问到,如果可以说明pvc就正常了。

    推荐阅读