官方文档:
https://kubernetes.io/zh/docs/concepts/storage/storage-classes/
PV是运维人员来创建的,开发操作PVC,可是大规模集群中可能会有很多PV,如果这些PV都需要运维手动来处理这也是一件很繁琐的事情,所以就有了动态供给概念,也就是Dynamic Provisioning。而我们上面的创建的PV都是静态供给方式,也就是Static Provisioning。而动态供给的关键就是StorageClass,它的作用就是创建PV模板。
每个 StorageClass 都包含 provisioner、parameters 和 reclaimPolicy 字段, 这些字段会在 StorageClass 需要动态分配 PersistentVolume 时会使用到。
StorageClass属性
provisioner存储分配器:用来决定使用哪个卷插件使用PV,该字段必须指定,可以指定内部分配器,也可以指定外部分配器。
reclaimPolicy回收策略:由 StorageClass 动态创建的 PersistentVolume 会在类的 reclaimPolicy 字段中指定回收策略,可以是 Delete 或者 Retain。如果 StorageClass 对象被创建时没有指定 reclaimPolicy,它将默认为 Delete。通过 StorageClass 手动创建并管理的 PersistentVolume 会使用它们被创建时指定的回收政策。
一、NFS Client Provisioner
是一个动态存储分配器,使用NFS作为存储,自动创建pv及对应的pvc,其本身不提供NFS作为储存需要外部现有一套NFS存储服务。
1、NFS动态分配PV示例
nfs服务端:
[root@server4 ~]# cd /mnt/nfs/
[root@server4 nfs]# showmount -e
Export list for server4:
/mnt/nfs *
(1)rbac授权官方文档:
https://github.com/kubernetes-incubator/external-storage/blob/master/nfs-client/deploy/rbac.yaml
[wjjk8s@server1 pv]$ kubectl create -f rbac.yaml
(2)nfs部署
https://github.com/kubernetes-incubator/external-storage/blob/master/nfs-client/deploy/deployment.yaml
[wjjk8s@server1 nfsclass]$ vim deployment.yaml
(3)动态卷声明
[wjjk8s@server1 nfsclass]$ vim class.yaml
[wjjk8s@server1 nfsclass]$ kubectl apply -f .
[wjjk8s@server1 nfsclass]$ kubectl get pv #没有专门创建pv
No resources found in default namespace.
[wjjk8s@server1 nfsclass]$ kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
managed-nfs-storage westos.org/nfs Delete Immediate false 2m51s
(4)测试
[wjjk8s@server1 nfsclass]$ vim pvc.yaml
[wjjk8s@server1 nfsclass]$ kubectl apply -f pvc.yaml
persistentvolumeclaim/test-claim created
[wjjk8s@server1 nfsclass]$ kubectl get all
[wjjk8s@server1 nfsclass]$ kubectl get pv #自动创建pv,删除pvc后pv即不存在
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-55cc42fb-a718-4601-aae2-9196efe28046 100Mi RWX Delete Bound default/test-claim managed-nfs-storage 57s
(5)删除在服务端备份
[wjjk8s@server1 nfsclass]$ vim class.yaml #改成true即可
archiveOnDelete: "true"
(6)测试pod
[wjjk8s@server1 nfsclass]$ \vi pod.yaml
[wjjk8s@server1 nfsclass]$ kubectl apply -f pod.yaml
[root@server4 default-test-claim-pvc-55cc42fb-a718-4601-aae2-9196efe28046]# pwd
/mnt/nfs/default-test-claim-pvc-55cc42fb-a718-4601-aae2-9196efe28046
[root@server4 default-test-claim-pvc-55cc42fb-a718-4601-aae2-9196efe28046]# echo westos > index.html
[wjjk8s@server1 nfsclass]$ curl 10.244.2.103
westos
二、没有指定名词提供持久卷
默认的StorageClass将被用于动态的为没有特定StorageClass需求的persistentvolumeclaims(pvc)配置存储:
[wjjk8s@server1 nfsclass]$ vim pvc.yaml
#annotations:
#volume.beta.kubernetes.io/storage-class: "managed-nfs-storage"
[wjjk8s@server1 nfsclass]$ kubectl apply -f pvc.yaml
[wjjk8s@server1 nfsclass]$ kubectl get pvc #没有指定名称,没有匹配pvc创建失败
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
test-claim Pending 29s
解决方法:
[wjjk8s@server1 nfsclass]$ kubectl patch storageclass managed-nfs-storage -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
storageclass.storage.k8s.io/managed-nfs-storage patched
[wjjk8s@server1 nfsclass]$ kubectl get sc #default
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
managed-nfs-storage (default) westos.org/nfs Delete Immediate false 30m
[wjjk8s@server1 nfsclass]$ kubectl delete -f pvc.yaml
persistentvolumeclaim "test-claim" deleted
[wjjk8s@server1 nfsclass]$ kubectl apply -f pvc.yaml
persistentvolumeclaim/test-claim created
[wjjk8s@server1 nfsclass]$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
test-claim Bound pvc-f6776ccd-7e5b-4c30-9519-69391436d172 100Mi RWX managed-nfs-storage 2s
**三、StatefulSet如何通过headless service维持pod的拓扑状态:*
StatefulSet 是用来管理有状态应用的工作负载 API 对象。StatefulSet 用来管理 Deployment 和扩展一组 Pod,并且能为这些 Pod 提供*序号和唯一性保证。
和 Deployment 相同的是,StatefulSet 管理了基于相同容器定义的一组 Pod。但和 Deployment 不同的是,StatefulSet 为它们的每个 Pod 维护了一个固定的 ID。这些 Pod 是基于相同的声明来创建的,但是不能相互替换:无论怎么调度,每个 Pod 都有一个永久不变的 ID。
1、创建无头服务headless service
[wjjk8s@server1 statefulset]$ vim headless.yaml
[wjjk8s@server1 statefulset]$ kubectl apply -f headless.yaml
2、创建StatefulSet控制器
[wjjk8s@server1 statefulset]$ \vi deployment.yaml
[wjjk8s@server1 statefulset]$ kubectl apply -f deployment.yaml
#Pod 提供序号和唯一性保证
[wjjk8s@server1 statefulset]$ kubectl get pod
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 46s
web-1 1/1 Running 0 27s
pod重建后ip更改,使用序号访问:
[wjjk8s@server1 statefulset]$ kubectl run test --image=busyboxplus -it
nslookup web-0.nginx.default.svc.cluster.local
curl web-0.nginx
3、挂接存储
[wjjk8s@server1 statefulset]$ kubectl apply -f state.yaml
The StatefulSet "web" is invalid: spec: Forbidden: updates to statefulset spec for fields other than 'replicas', 'template', and 'updateStrategy' are forbidden
#改为0回收一下即可
[wjjk8s@server1 statefulset]$ kubectl get pod #会一个一个创建,且会为每一个pod创建一个pv
StatefulSet还会为每一个Pod分配并创建一个同样编号的PVC。这样,kubernetes就可以通过Persistent Volume机制为这个PVC绑定对应的PV,从而保证每一个Pod都拥有一个独立的Volumea
在删除StatefulSet类型的文件时,将replicas设置为0,会自动回收pod
4、kubectl的弹性伸缩
首先,想要弹缩的StatefulSet. 需先清楚是否能弹缩该应用.
[wjjk8s@server1 statefulset]$ kubectl get statefulset
NAME READY AGE
web 0/2 7m50s
方式一:改变StatefulSet副本数量
kubectl scale statefulsets <stateful-set-name> --replicas=<new-replicas>
方式二:更改yaml文件
如果StatefulSet开始由 kubectl apply 或 kubectl create --save-config 创建,更新StatefulSet manifests中的 .spec.replicas(更改replicas的数目), 然后执行命令 kubectl apply:
kubectl apply -f <stateful-set-file-updated>
方式三:命令 kubectl edit 编辑该字段:
kubectl edit statefulsets <stateful-set-name>
方式四:使用 kubectl patch
kubectl patch statefulsets <stateful-set-name> -p '{"spec":{"replicas":<new-replicas>}}'