storageclass
为什么要有service account
https://www.cnblogs.com/cosmos-wong/p/16867388.html
storageclass资源可以通过apiserver自动创建pv资源,用到service account
一.StorageClass持久化存储介绍
1.是什么
StorageClass又称为PV动态供给,是k8s1.4之后引入的一个新资源,主要实现了存储卷PV按需创建,动态创建。一旦有pvc资源,storageclass会自动创建pv
2.为什么用
以前静态的PV和PVC都需要手动来创建,因为pv和pvc一一对应,一个pv一旦被绑定就不会再被其他pvc绑定,因此当pvc逐渐增多,pv也会同比增加,这时候就需要自动创建pv,就要用到stroageclass
3.和pv、pvc关系
- StorageClass创建的pvc,只要pvc不删除,即使控制器删除、pod删除重建还是会找到原来的pvc,并且持久化数据,一旦pvc删除,下次重建statefulset控制器,重新使用StorageClass创建pvc,pvc的路径就会发生改变,当然pvc一般是不会删除的
- StorageClass可以配合Statefulset控制器为每一个有状态的Pod自动创建PVC并进行挂载,使每一个有状态的pod数据都实现持久化
- StorageClass只能配合statefulset为每个Pod自动创建PVC,因为只有statefulset有volumeClaimTemplates配置选项
StorageClass依赖一个自动配置程序,比如我们的后端存储是nfs,那么就需要一个nfs-client的自动配置程序,如果是gfs,就需要gfs-client自动配置程序,也称为Provisione,StorageClass也是靠这个Provisione自动配置程序来实现自动创建PV持久卷
自动创建的PV以{namespace}-${pvcname}-${pvname}进行命名到服务器上创建相应的目录
当pv被回收后会以archieved-${namespace}-${pvcname}-${pvname}格式存在服务器上
storageclass自动创建的pv命名规则:pvc-${PVC_UID}
当程序删除后,PVC、PV不会消失
4.部署步骤
1.编写nfs-client-provisioner程序的rbac授权角色账号
2.编写nfs-client-provisioner程序的deployment资源文件,与rbac账号进行绑定,使nfs-client-provisioner对pv、pvc有增删改查权限(这是server account存在的原因)
3.创建一个StorageClass资源关联nfs-client,自动创建PV时,就将PV存储到了nfs-client对应的nfs存储上
4.编写一个PVC yaml文件,验证是否能自动创建PV
5.编写一个无状态的yaml文件,使用PVC挂载数据
6.在statefulset里定义StorageCLass,实现每个pod都使用单独的pvc存储
5.原理
一旦有pvc资源文件,storageclass资源会去找自动配置程序也就是nfs-client-provisioner,由nfs-client-provisioner去创建一个PV,并将PV的数据存储在对应的nfs设备上,然后再从PV中分出一个PVC-1,最后挂载到Pod上实现持久化存储
二.部署storageclass
具体文件参考:https://github.com/kubernetes-retired/external-storage/tree/master/nfs-client
1.用户角色授权
创建角色授权是为了让pod(内含nfs-client-provisioner工具)对pv和pvc有操作权限
#创建名称为nfs-client-provisioner的serviceaccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
namespace: storage-class
---
#声明角色对pv、pvc等资源的权限
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-client-provisioner-runner
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
- 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
namespace: storage-class
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
namespace: storage-class
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
namespace: storage-class
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: storage-class
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io
2.nfs-client-provisioner资源
创建nfs-client-provisioner工具
kind: Deployment
apiVersion: apps/v1
metadata:
name: nfs-client-provisioner
namespace: storage-class
spec:
replicas: 1
selector:
matchLabels:
app: nfs-client-provisioner
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
#绑定service account,使得自动化配置工具能访问pv、pvc等资源
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
# 下载nfs-client-provisioner工具
image: quay.io/external_storage/nfs-client-provisioner:latest
env:
- name: PROVISIONER_NAME #给nfs-client-provisioner起个名字
value: nfs-storage-01
- name: NFS_SERVER
value: 192.168.181.141 #nfs server地址
- name: NFS_PATH
value: /data/storagedata #nfs共享路径
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes #具体挂载路径
volumes: #定义一个nfs类型的volume,将nfs挂载到容器中
- name: nfs-client-root
nfs:
server: 192.168.181.141
path: /data/storagedata
3.storageclass资源
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-storageclass
provisioner: nfs-storage-01 #匹配找到env中PROVISIONER_NAME的值,通过其创建pv
reclaimPolicy: Retain #回收策略
storageclass资源通过provisioner绑定2中的nfs-client-provisioner资源,nfs-client-provisioner资源通过serviceAccountName绑定1中的用户进而对pvc、pv进行操作
4.创建所有资源
1.创建资源
[root@k8s-master1 storageclass]# kubectl apply -f ./
2.查看nfs-client-provisioner资源的状态
[root@k8s-master1 storageclass]# kubectl get pod -n storage-class
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-554cc7d84d-j4966 1/1 Running 0 35m
3.查看storageclass资源的状态
[root@k8s-master1 storageclass]# kubectl get sc -n storage-class
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
nfs-storageclass nfs-storage-01 Retain Immediate false 7s
以下5、6、7都是对上面资源的测试
5.手动创建pvc测试
5.1创建pvc资源
1.编写yaml文件
[root@k8s-master1 storageclass]# vim test-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-pvc
spec:
storageClassName: nfs-storageclass #指定storageclass的名称
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Mi
2.创建资源
[root@k8s-master1 storageclass]# kubectl create -f test-pvc.yaml
persistentvolumeclaim/test-pvc created
5.2查看nfs-client日志输出
可以看到日志最后一行的输出,产生一个事件信息,一个类型为pvc、命名空间为default、名称为test-pvc、UID为4bd5e8d9-1b38-48a8-a04a-1261eaa0b00f的pvc通过storageclass建立了,storageclass为test-pvc自动创建了一个名为pvc-4bd5e8d9-1b38-48a8-a04a-1261eaa0b00f的pv
storageclass自动创建的pv命名规则:pvc-${PVC_UID}
5.3查看pv、pvc状态
pv创建成功后,会在2中nfs存储路径创建一个{namespace}-${pvcname}-${pvname}这样命名规则的目录存储pvc的数据
6.使用deployment资源引用创建的PVC资源
1.编写yaml文件
[root@k8s-master1 storageclass]# vim nginx-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-pv
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx-pv
image: nginx:1.17.1
volumeMounts:
- name: nginx-data
mountPath: /usr/share/nginx
volumes:
- name: nginx-data
persistentVolumeClaim:
claimName: test-pvc #指定pvc
readOnly: false
2.创建资源
[root@k8s-master1 storageclass]# kubectl create -f nginx-deploy.yaml
deployment.apps/nginx-pv created
3.进入容器产生数据
[root@k8s-master1 storageclass]# kubectl exec -it nginx-pv-56646f947b-twq2m bash
root@nginx-pv-56646f947b-twq2m:/# cd /usr/share/nginx/
root@nginx-pv-56646f947b-twq2m:/usr/share/nginx# for i in {1..10}
> do
> echo "this is web${i}" >> index.html
> sleep 1
> done
4.查看nfs存储上是否有数据产生
[root@k8s-master2 /data2/k8s/storageclass]# ll default-test-pvc-pvc-4bd5e8d9-1b38-48a8-a04a-1261eaa0b00f/
总用量 4
-rw-r--r-- 1 root root 131 5月 18 14:05 index.html
7.使用StatefulSet控制器引入StorageClass
1.使用statfulset部署nginx,每个pod使用不同的pvc存储数据。
2.如果我们使用手动指定pvc的方式,当我们pod为多实例的时候,多个pod使用的是一个pvc。但是我们使用statefulset时,storageclass会为我们每一个Pod创建一个pv和pvc(造成数据隔离,因为在不同的主机)
3.statefulset使用storageclass,需要用到volumeClaimTemplates配置项,volumeClaimTemplates配置项是statfulset控制器独有的,因此需要配置在statefulset.spec下,volumeClaimTemplates下的配置和pvc调用storageclass一致,定义好volumeClaimTemplates后,直接在pod中定义volumeMounts,填写volumeClaimTemplates中的pvc名称,即可对每个Pod分配一个pvc进行存储
7.1创建statefulset资源
[root@k8s-master1 storageclass]# vim nginx-statfuleset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx-storage-stat
spec:
replicas: 3
serviceName: "nginx"
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.17.1
volumeMounts:
- name: nginx-storage-test-pvc
mountPath: /usr/share/nginx/html
volumeClaimTemplates: #在statfulset.spec下定义pvc模板,里面的配置参数和pvc的一致
- metadata: #定义元数据
name: nginx-storage-test-pvc #pvc的名称,要与volumeMounts中的名称一致
spec: #定义属性
storageClassName: nfs-storageclass #指定使用哪个storageclass
accessModes: #访问模式为多主机可读写
- ReadWriteMany
resources: #分配的资源大小
requests:
storage: 1Gi
[root@k8s-master1 storageclass]# kubectl create -f nginx-statfuleset.yaml
statefulset.apps/nginx-storage-stat created
[root@k8s-master1 storageclass]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-storage-stat-0 1/1 Running 0 9m51s
nginx-storage-stat-1 1/1 Running 0 9m46s
nginx-storage-stat-2 1/1 Running 0 9m41s
7.2查看是否为每个pod分配了pvc
使用satefuleset部署的pod会在nfs目录下生成对应不同的pod目录,pod0目录挂载在pod0上,pod1目录挂载在pod1上,数据隔离
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律