K8S之存储卷
一、emptyDir
emptyDir:可实现Pod中的容器之间共享目录数据,但emptyDir存储卷没有持久化数据的能力,存储卷会随着Pod生命周期结束而一起删除
二、hostPath
hostPath:将Node节点上的目录/文件挂载到Pod容器的指定目录中,有持久化数据的能力,但只能在单个Node节点上持久化数据,不能实现跨Node节点的Pod共享数据
三、nfs
nfs:使用NFS服务将存储卷挂载到Pod容器的指定目录中,有持久化数据的能力,且也能实现跨Node节点的Pod共享数据
四、PV PVC
1.PV
PV:K8S在指定存储设备空间中逻辑划分创建的可持久化的存储资源对象
1.1创建PV的方式
手动根据配置文件创建的静态PV
通过StorageClass调用存储卷插件创建的动态PV
1.2PV的四种状态
PV状态 | 说明 |
---|---|
Available(可用) | 表示可用状态,PV 被创建出来了,还未被 PVC 绑定 |
Bound(已绑定) | 表示 PV 已经被 PVC 绑定,PV 与 PVC 是一对一的绑定关系 |
Released(已释放) | 表示 PVC 被删除,但是 PV 资源还未被回收 |
Failed(失败) | 表示 PV 自动回收失败 |
2.PVC
PVC:是对PV资源对象的请求和绑定,也是Pod能挂载使用的一种存储卷类型
3.创建静态的PV PVC
3.1创建步骤
创建使用 静态PV
1)准备好存储设备和共享目录
2)手动创建PV资源,配置 存储卷类型 访问模式(RWO RWX ROX RWOP) 存储空间大小 回收策略(Retain Recycle Delete)等
3)创建PVC资源,配置请求PV资源的访问模式(必要条件,必须是PV能支持的访问模式) 存储空间大小(默认就近选择大于等于指定大小的PV)来绑定PV
4)创建Pod和Pod控制器资源挂载PVC存储卷,配置存储卷类型为 persistentVolumeClaim ,并在容器配置中定义存储卷挂载点目录
3.2创建过程
1.部署nfs服务器
通过vim /etc/exports
/opt/data/ 192.168.111.0/24(rw,no_root_squash,sync)
通过exportfs -arv 在线发布
2.准备pv的yaml文件
apiVersion: v1
kind: PersistentVolume ##类型为pv
metadata:
name: pv01 ##pv名称
spec:
capacity:
storage: 1Gi ##pv存储卷大小
volumeMode: Filesystem
accessModes: ##访问模式
- ReadWriteOnce
- ReadWriteMany
#persistentVolumeReclaimPolicy: Recycle
#storageClassName: slow
nfs: ##pv持久卷的类型
path: /opt/pv/v1 ## 挂载路径
server: 192.168.111.40 ## nfs服务器类型
3.准备pvc的yaml文件
apiVersion: v1
kind: PersistentVolumeClaim ##类型为pvc
metadata:
name: mypvc-1 ##pvc名称
spec:
accessModes: ##访问模式
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests: ##请求资源量
storage: 2Gi
#storageClassName: slow
4.准备pod的yaml文件,挂载pvc存储卷
apiVersion: v1
kind: Pod
metadata:
name: mypod-1
spec:
containers:
- name: mypod-1
image: nginx
volumeMounts: ##pod的容器内存储卷挂载路径
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: mypvc-1 ##指定pvc的存储卷名称
4.创建动态PV PVC
4.1创建步骤
创建使用 动态PV
1)准备好存储设备和共享目录
2)如果是外置存储卷插件,需要先创建serviceaccount账户(Pod使用的账户)和做RBAC授权(创建角色授予相关资源对象的操作权限,再将账户和角色进行绑定),使serviceaccount账户具有对PV PVC StorageClass等资源的操作权限
3)创建外置存储卷插件provisioner的Pod,配置中使用serviceaccount账户作为Pod的用户,并设置相关环境变量参数
4)创建StorageClass(SC)资源,配置中引用存储卷插件的插件名称(PROVISIONER_NAME)
---------------- 以上操作是一劳永逸的,以后只需要创建PVC时设置StorageClass就可以自动调用存储卷插件动态生成PV资源 ----------------
5)创建PVC资源,配置中设置 StorageClass资源名称 访问模式 存储空间大小。创建PVC资源会自动创建相关的PV资源。
6)创建Pod资源挂载PVC存储卷,配置存储卷类型为 persistentVolumeClaim ,并在容器配置中定义存储卷挂载点目录
4.2创建过程
1.部署nfs服务器
通过vim /etc/exports
/opt/data/ 192.168.111.0/24(rw,no_root_squash,sync)
通过exportfs -arv 在线发布
2.准备serviceaccount账户(Pod使用的账户)和做RBAC授权
vim nfs-client-rbac.yaml
#创建 Service Account 账户,用来管理 NFS Provisioner 在 k8s 集群中运行的权限
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
---
#创建集群角色
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: nfs-client-provisioner-clusterrole
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
---
#集群角色绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: nfs-client-provisioner-clusterrolebinding
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: default
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-clusterrole
apiGroup: rbac.authorization.k8s.io
kubectl apply -f nfs-client-rbac.yaml
3.使用 Deployment 来创建 NFS Provisioner
NFS Provisioner(即 nfs-client),有两个功能:一个是在 NFS 共享目录下创建挂载点(volume),另一个则是将 PV 与 NFS 的挂载点建立关联。
#由于 1.20 版本启用了 selfLink,所以 k8s 1.20+ 版本通过 nfs provisioner 动态生成pv会报错,解决方法如下:
vim /etc/kubernetes/manifests/kube-apiserver.yaml
spec:
containers:
- command:
- kube-apiserver
- --feature-gates=RemoveSelfLink=false #添加这一行
- --advertise-address=192.168.80.20
......
kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
kubectl delete pods kube-apiserver -n kube-system
kubectl get pods -n kube-system | grep apiserver
#创建 NFS Provisioner
vim nfs-client-provisioner.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
name: nfs-client-provisioner
spec:
replicas: 1
selector:
matchLabels:
app: nfs-client-provisioner
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner #指定Service Account账户
containers:
- name: nfs-client-provisioner
image: quay.io/external_storage/nfs-client-provisioner:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: nfs-storage #配置provisioner的Name,确保该名称与StorageClass资源中的provisioner名称保持一致
- name: NFS_SERVER
value: stor01 #配置绑定的nfs服务器
- name: NFS_PATH
value: /opt/k8s #配置绑定的nfs服务器目录
volumes: #申明nfs数据卷
- name: nfs-client-root
nfs:
server: stor01
path: /opt/k8s
kubectl apply -f nfs-client-provisioner.yaml
kubectl get pod
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-cd6ff67-sp8qd 1/1 Running 0 14s
4.创建 StorageClass,负责建立 PVC 并调用 NFS provisioner 进行预定的工作,并让 PV 与 PVC 建立关联
vim nfs-client-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-client-storageclass
provisioner: nfs-storage #这里的名称要和provisioner配置文件中的环境变量PROVISIONER_NAME保持一致
parameters:
archiveOnDelete: "false" #false表示在删除PVC时不会对数据目录进行打包存档,即删除数据;为ture时就会自动对数据目录进行打包存档,存档文件以archived开头
kubectl apply -f nfs-client-storageclass.yaml
kubectl get storageclass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
nfs-client-storageclass nfs-storage Delete Immediate false 43s
5.创建pvc资源
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-nfs-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-client-storageclass
resources:
requests:
storage: 1Gi
6.创建pod挂载pvc存储卷
apiVersion: v1
kind: Pod
metadata:
name: test-storageclass-pod
spec:
containers:
- name: dongtaipvc
image: nginx:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs-pvc
mountPath: /mnt
restartPolicy: Never
volumes:
- name: nfs-pvc
persistentVolumeClaim:
claimName: test-nfs-pvc
piVersion: v1
kind: Pod
metadata:
name: test-storageclass-pod
spec:
containers:
- name: dongtaipvc
image: nginx:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs-pvc
mountPath: /mnt
restartPolicy: Never
volumes:
- name: nfs-pvc
im:
claimName: test-nfs-pvc
piVersion: v1
kind: Pod
metadata:
name: test-storageclass-pod
spec:
containers:
- name: dongtaipvc
image: nginx:latest
imagePullPolicy: IfNotPresent
volumeMounts:- name: nfs-pvc
mountPath: /mnt
restartPolicy: Never
volumes:
- name: nfs-pvc
- name: nfs-pvc