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:通过此字段将存储卷挂接到容器中
PV是系统管理员设置的存储,它是群集的一部分,是一种资源,所以它有独立于Pod的生命周期。
PVC是用户存储的请求。它与Pod相似,Pod消耗节点的CPU和内存资源,PVC则消耗PV资源,可以生命特定的容量大小和访问模式。
PV和PVC遵循如下的生命周期管理
配置
PV有两种配置方式:静态或动态
- 静态
管理员创建静态一些PV,它们带有可供集群用户使用的实际存储的细节,它们存在于Kubernetes API中,可用于消费; - 动态
当管理员创建的静态 PV 都不匹配用户的PersistentVolumeClaim
时,集群可能会尝试动态地为 PVC 创建卷。此配置基于StorageClasses
:PVC 必须请求存储类,并且管理员必须创建并配置该类才能进行动态创建。声明该类为""
可以有效地禁用其动态配置。
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就正常了。