什么是StorageClass
-
StatefulSet是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为无状态服务而设计),其应用场景包括:
-
稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现
-
稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现
-
有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现
-
有序收缩,有序删除(即从N-1到0)
-
从上面的应用场景可以发现,StatefulSet由以下几个部分组成:
-
用于定义网络标志(DNS domain)的Headless Service
-
用于创建PersistentVolumes的volumeClaimTemplates
-
定义具体应用的StatefulSet
StatefulSet中每个Pod的DNS格式为statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local
,其中
-
serviceName为Headless Service的名字
-
0…N-1为Pod所在的序号,从0开始到N-1
-
statefulSetName为StatefulSet的名字
-
namespace为服务所在的namespace,Headless Servic和StatefulSet必须在相同的namespace
-
.cluster.local为Cluster Domain
使用 StatefulSet
StatefulSet 适用于有以下某个或多个需求的应用:
-
稳定,唯一的网络标志。
-
稳定,持久化存储。
-
有序,优雅地部署和 scale。
-
有序,优雅地删除和终止。
-
有序,自动的滚动升级。
在上文中,稳定是 Pod (重新)调度中持久性的代名词。 如果应用程序不需要任何稳定的标识符、有序部署、删除和 scale,则应该使用提供一组无状态副本的 controller 来部署应用程序,例如 Deployment 或 ReplicaSet 可能更适合您的无状态需求。
为什么需要StorageClass
在一个大规模的Kubernetes集群里,可能有成千上万个PVC,这就意味着运维人员必须实现创建出这个多个PV,此外,随着项目的需要,会有新的PVC不断被提交,那么运维人员就需要不断的添加新的,满足要求的PV,否则新的Pod就会因为PVC绑定不到PV而导致创建失败.而且通过
PVC
请求到一定的存储空间也很有可能不足以满足应用对于存储设备的各种需求,而且不同的应用程序对于存储性能的要求可能也不尽相同,比如读写速度、并发性能等,为了解决这一问题,Kubernetes
又为我们引入了一个新的资源对象:StorageClass,通过 StorageClass
的定义,管理员可以将存储资源定义为某种类型的资源,比如快速存储、慢速存储等,用户根据 StorageClass
的描述就可以非常直观的知道各种存储资源的具体特性了,这样就可以根据应用的特性去申请合适的存储资源了
StorageClass部署流程
-
要使用 StorageClass,我们就得安装对应的自动配置程序,比如我们这里存储后端使用的是 nfs,那么我们就需要使用到一个 nfs-client 的自动配置程序,我们也叫它 Provisioner,这个程序使用我们已经配置好的 nfs 服务器,来自动创建持久卷,也就是自动帮我们创建 PV。
搭建StorageClass+NFS,大致有以下几个步骤:
1.创建一个可用的NFS Serve
2.创建Service Account.这是用来管控NFS provisioner在k8s集群中运行的权限
3.创建StorageClass.负责建立PVC并调用NFS provisioner进行预定的工作,并让PV与PVC建立管理
4.创建NFS provisioner.有两个功能,一个是在NFS共享目录下创建挂载点(volume),另一个则是建了PV并将PV与NFS的挂载点建立关联
创建StorageClass
部署NFS
-
在所有节点中执行
yum -y install nfs-utils rpcbind
systemctl enable rpcbind && systemctl start nfs
systemctl enable nfs-server && systemctl start rpcbind
-
创建共享目录
# 创建共享目录
mkdir /home/data
# 设置环境变量
vi /etc/exports
# 添加以下内容
/home/data *(insecure,rw,sync,no_subtree_check,no_root_squash)
# 重启服务
systemctl restart nfs
创建目录
添加nfs-subdir-external-provisioner仓库
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
查看nfs-subdir-external-provisioner所有版本
helm search repo nfs-subdir-external-provisioner --versions
拉取文件
helm pull nfs-subdir-external-provisioner/nfs-subdir-external-provisioner --version 4.0.14
Error: Get "https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/releases/download/nfs-subdir-external-provisioner-4.0.14/nfs-subdir-external-provisioner-4.0.14.tgz": unexpected EOF
根据报错去下载这个包
解压chart包
tar -xzvf nfs-subdir-external-provisioner-4.0.14.tgz
打开values配置文件
vi nfs-subdir-external-provisioner/values.yaml
修改如下参数
replicaCount: 3 # 第1行,副本个数,根据自身需求设置,建议3个
image: registry.cn-beijing.aliyuncs.com/xngczl/nfs-subdir-external-provisione
repository: # 第5行,设置镜像仓库
tag: v4.0.0 # 第6行,镜像版本
nfs:
server: 192.168.1.101 # 第11行,nfs server端地址
path: /home/data # 第12行,nfs目录
storageClass:
defaultClass: true # 第27行,设置为默认存储类,如果不设置,使用存储类时需要指定
name: nfs-storage # 第31行,设置存储类资源名称
创建命名空间
kubectl create namespace nfs-storage
安装nfs-subdir-external-provisioner
helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner -n nfs-storage
查看pod
kubectl get pod -n nfs-storage
测试
创建PVC的yaml文件
cat > test-pvc.yaml << EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-pvc
spec:
storageClassName: nfs-storage # 指定存储类,如果设置了默认,可以去掉
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
EOF
创建pvc,会自动相应的pv
kubectl apply -f test-pvc.yaml -n nfs-storage
查看pvc和pv是否创建
kubectl get pvc,pv -n nfs-storage
关于StorageClass回收策略对数据的影响
第一种
# 配置
archiveOnDelete: "false"
reclaimPolicy: Delete #默认没有配置,默认值为Delete
#结果
1.pod删除重建后数据依然存在,旧pod名称及数据依然保留给新pod使用
2.sc删除重建后数据依然存在,旧pod名称及数据依然保留给新pod使用
3.删除PVC后,PV被删除且NFS Server对应数据被删除
第二种
#配置
archiveOnDelete: "false"
reclaimPolicy: Retain
#结果
1.pod删除重建后数据依然存在,旧pod名称及数据依然保留给新pod使用
2.sc删除重建后数据依然存在,旧pod名称及数据依然保留给新pod使用
3.删除PVC后,PV不会别删除,且状态由Bound变为Released,NFS Server对应数据被保留
4.重建sc后,新建PVC会绑定新的pv,旧数据可以通过拷贝到新的PV中
第三种
#配置
archiveOnDelete: "ture"
reclaimPolicy: Retain
#结果
1.pod删除重建后数据依然存在,旧pod名称及数据依然保留给新pod使用
2.sc删除重建后数据依然存在,旧pod名称及数据依然保留给新pod使用
3.删除PVC后,PV不会别删除,且状态由Bound变为Released,NFS Server对应数据被保留
4.重建sc后,新建PVC会绑定新的pv,旧数据可以通过拷贝到新的PV中
第四种
#配置
archiveOnDelete: "ture"
reclaimPolicy: Delete
#结果
1.pod删除重建后数据依然存在,旧pod名称及数据依然保留给新pod使用
2.sc删除重建后数据依然存在,旧pod名称及数据依然保留给新pod使用
3.删除PVC后,PV不会别删除,且状态由Bound变为Released,NFS Server对应数据被保留
4.重建sc后,新建PVC会绑定新的pv,旧数据可以通过拷贝到新的PV中
总结:除以第一种配置外,其他三种配置在PV/PVC被删除后数据依然保留