kubernetes持久化存储卷-StorageClass
存储卷回顾
- 存储卷介绍
pod有生命周期,生命周期结束后pod里的数据会消失(如配置文件,业务数据等)。
解决: 我们需要将数据与pod分离,将数据放在专门的存储卷上
pod在k8s集群的节点中是可以调度的, 如果pod挂了被调度到另一个节点,那么数据和pod的联系会中断。
解决: 所以我们需要与集群节点分离的存储系统才能实现数据持久化
简单来说: volume提供了在容器上挂载外部存储的能力
存储卷分类:
- 本地存储卷 (Volume)
- emptyDir 宿主机目录映射(临时存储),pod删除,数据也会被清除
- hostPath 宿主机目录映射(持久存储),pod删除,数据不会被清除
- 网络存储卷
- NAS类 nfs等
- SAN类 iscsi,FC等
- 分布式存储 glusterfs,cephfs,rbd,cinder等
- 云存储 aws,azurefile等
- PV(持久存储卷)与PVC(持久存储卷声明)
persistenvolume(PV) 是配置好的一段存储(可以是任意类型的存储卷)
- 也就是说将网络存储共享出来,配置定义成PV。
PersistentVolumeClaim(PVC)是用户pod使用PV的申请请求。
- 用户不需要关心具体的volume实现细节,只需要关心使用需求。
- pv与pvc之间的关系
- pv提供存储资源(生产者)
- pvc使用存储资源(消费者)
- 使用pvc绑定pv

静态供给:创建pv, 创建pvc,创建pod关联pvc
每次使用存储要提前先创建pv, 再创建pvc,比较麻烦,我们可以实现使用存储的动态供给特性。
- 静态存储需要用户申请PVC时保证容量和读写类型与预置PV的容量及读写类型完全匹配, 而动态存储则无需如此.
- 管理员无需预先创建大量的PV作为存储资源
Kubernetes从1.4版起引入了一个新的资源对象StorageClass(存储类),可用于将存储资源定义为具有显著特性的类(Class即模板)而不是具体的PV。
用户通过PVC直接向意向的类别发出申请,匹配由管理员事先创建的PV,或者由其按需为用户动态创建PV,这样就免去了需要先创建PV的过程。
PV对存储系统的支持可通过其插件来实现,
目前,官方插件是不支持NFS动态供给的,但是我们可以用第三方的插件来实现
补充:安装配置nfs服务
# 所有节点都安装nfs-utils工具包和rpc-bind服务。
yum install nfs-utils -y
nfs服务器的ip为192.168.10.14
[root@nfs ~]# systemctl stop firewalld
[root@nfs ~]# systemctl disable firewalld
[root@nfs ~]# setenforce 0
[root@nfs ~]# vim /etc/sysconfig/selinux
SELINUX=disabled
[root@nfs ~]# mkdir -p /data/nfs
[root@nfs ~]# vim /etc/exports
/data/nfs *(rw,sync,no_root_squash)
[root@nfs ~]# systemctl start nfs-server
[root@nfs ~]# systemctl enable nfs-server
[root@nfs ~]# showmount -e
Export list for 192.168.10.14:
/data/nfs *
[root@worker01 ~]# showmount -e 192.168.10.14
Export list for 192.168.10.11:
/data/nfs *
[root@worker02 ~]# showmount -e 192.168.10.14
Export list for 192.168.10.11:
/data/nfs *
- 下载并创建storageclass
[root@master01 ~]# wget https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/class.yaml
[root@master01 ~]# mv class.yaml storageclass-nfs.yml
[root@master01 ~]# cat storageclass-nfs.yml
apiVersion: storage.k8s.io/v1
kind: StorageClass # 类型
metadata:
name: nfs-client # 名称,要使用就需要调用此名称
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # 动态供给插件
parameters:
archiveOnDelete: "false" # 删除数据时是否存档,false表示不存档,true表示存档
[root@master01 ~]# kubectl apply -f storageclass-nfs.yml
[root@master01 ~]# kubectl get storageclass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
nfs-client k8s-sigs.io/nfs-subdir-external-provisioner Delete Immediate false 10s
# RECLAIMPOLICY pv回收策略,pod或pvc被删除后,pv是否删除还是保留,delete表示删除,但数据保留。
# VOLUMEBINDINGMODE Immediate 模式下PVC与PV立即绑定,主要是不等待相关Pod调度完成,不关心其运行节点,直接完成绑定。
- 下载配置清单文件,创建rbac(创建账号,并授权)
因为storage自动创建pv需要经过kube-apiserver,所以需要授权。
RBAC(Role-Based Access Control):基于角色的访问控制
- 定义:
RBAC(Role-Based Access Control,基于角色的访问控制)是一种访问控制模型,它通过将用户分配到不同的角色,并为每个角色定义权限,从而实现对资源的访问控制。用户通过其所属的角色获得相应的权限,而无需直接为每个用户分配权限。
- 核心组件:
用户(User):需要访问系统资源的主体,如员工、客户等。
角色(Role):一组权限的集合,代表用户在系统中的职责或身份。例如,“管理员”、“普通用户”等。
权限(Permission):允许用户对资源进行的操作,如“读取”、“写入”、“删除”等。
资源(Resource):系统中需要保护的对象,如文件、数据库、网络设备等。
[root@master01 ~]# wget https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/rbac.yaml
[root@master01 ~]# mv rbac.yaml storageclass-nfs-rbac.yaml
[root@master01 ~]# cat storageclass-nfs-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-client-provisioner-runner
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: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io
[root@master01 ~]# kubectl apply -f storageclass-nfs-rbac.yaml
- 创建动态供给的deployment
需要一个deployment来专门实现pv与pvc的自动创建
[root@master01 ~]# vim deploy-nfs-client-provisioner.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccount: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: registry.cn-beijing.aliyuncs.com/pylixm/nfs-subdir-external-provisioner:v4.0.0
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: k8s-sigs.io/nfs-subdir-external-provisioner
- name: NFS_SERVER
value: 192.168.10.14
- name: NFS_PATH
value: /data/nfs
volumes:
- name: nfs-client-root
nfs:
server: 192.168.10.14
path: /data/nfs
[root@master01 ~]# kubectl apply -f deploy-nfs-client-provisioner.yml
deployment.apps/nfs-client-provisioner created
[root@master01 ~]# kubectl get pods |grep nfs-client-provisioner
nfs-client-provisioner-5b5ddcd6c8-b6zbq 1/1 Running 0 34s
- 测试存储动态供给是否可用
# vim nginx-sc.yaml
---
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx"
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
imagePullSecrets:
- name: huoban-harbor
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: nginx:1.20
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "nfs-client"
resources:
requests:
storage: 1Gi
[root@master01 nfs]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-9c988bc46-pr55n 1/1 Running 0 95s
web-0 1/1 Running 0 95s
web-1 1/1 Running 0 61s
[root@nfs ~]# ls /data/nfs/
default-www-web-0-pvc-a78841fb-ec92-426d-a7db-a2bcb53c448e
default-www-web-1-pvc-0f6240e7-43a2-4605-be36-aaced8b2dc5b
[root@master01 ~]# kubectl delete -f nginx-svc.yaml
[root@nfs ~]# ls /data/nfs/
default-www-web-0-pvc-a78841fb-ec92-426d-a7db-a2bcb53c448e
default-www-web-1-pvc-0f6240e7-43a2-4605-be36-aaced8b2dc5b
更多推荐
所有评论(0)