一、statefulset简介
statefulset是用来管理有效状态应用的工作负载API对象,也是一种POD控制器,那为什么要放在PV/PVC之后再简介呢?这是因为statefulset是必须也有持久化数据,每个POD所对应的PV都是不一样的。相对于Deployment所创建的POD是无状态的,那statefulset是属于有状态的,即可以保留POD的状态信息。其特点有:
• 1、稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现
• 2、稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现
• 3、有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现
• 4、有序收缩,有序删除(即从N-1到0)
• 5、有序的滚动更新
在svc服务最后有个无头服务那就是headless service这东西有什么用?这是因为statefulset的特性所决定的:在statefulset中是要求有序的,每一个pod的名称必须是固定的。当节点挂了,重建之后的标识符是不变的,每一个节点的节点名称是不能改变的。pod名称是作为pod识别的唯一标识符,必须保证其标识符的稳定并且唯一。为了实现标识符的稳定,这时候就需要一个headless service 解析直达到pod,还需要给pod配置一个唯一的名称。
二、statefulset实例
1、通过nfs创建共享存储
SQL 1、在一台服务器创建nfs共享存储 yum install -y nfs-common nfs-utils rpcbind mkdir /data/nfs{0..3} chmod 755 /data/nfs{0..3} chown nfsnobody /data/nfs{0..3} cat >/etc/exports <<EOF /home/k8s/nfs *(rw,sync,no_root_squash) EOF systemctl start rpcbind && systemctl enable rpcbind systemctl start nfs && systemctl enable nfs ###查看共享服务器和路径 [root@k8s-master ~]# showmount -e 172.16.4.169 Export list for 172.16.4.169: /home/k8s/nfs *
2、在其他服务器上进行挂载 [root@k8s-node1 ~]# mount -t nfs 172.16.4.169:/home/k8s/nfs /home/k8s/nfs/ [root@k8s-node1 ~]# df -h 172.16.4.169:/home/k8s/nfs 447G 7.6G 440G 2% /home/k8s/nfs [root@k8s-node1 ~]# date > /home/k8s/nfs/index.html [root@k8s-node1 ~]# cat /home/k8s/nfs/index.html Thu May 12 19:26:48 CST 2022 [root@k8s-node1 ~]#
|
2、statefulset的yml
2.1、创建一个PV
YAML [root@k8s-master statefulset]# cat pv.yml apiVersion: v1 kind: PersistentVolume metadata: name: pv-volume spec: capacity: storage: 50Gi volumeMode: Filesystem accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Recycle storageClassName: slow mountOptions: - hard - nfsvers=4.1 nfs: path: /home/k8s/nfs server: 172.16.4.169 [root@k8s-master statefulset]# kubectl apply -f pv.yml persistentvolume/pv-volume created [root@k8s-master statefulset]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv-volume 50Gi RWO Recycle Available slow 7s
|
2.2、创建statefulset
YAML [root@k8s-master statefulset]# cat statefulset.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: 3 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.9.1 ports: - containerPort: 80 name: web volumeMounts: - name: www mountPath: /usr/share/nginx/html
volumeClaimTemplates: - metadata: name: www spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "slow" resources: requests: storage: 5Gi [root@k8s-master statefulset]# kubectl apply -f statefulset.yaml service/nginx created statefulset.apps/web created [root@k8s-master statefulset]# kubectl get statefulset NAME READY AGE web 0/3 10s
|
由于StatefulSet是2个副本,但是看到只创建了web-0。在创建web-1时出错了。这是由于没有可用的PV了。所以一个POD是绑定一个PVC的,每个POD所对应的存储空间是不一样的。
YAML ##在创建一个新的pv1 [root@k8s-master statefulset]# cat pv0.yml apiVersion: v1 kind: PersistentVolume metadata: name: pv-volume1 spec: capacity: storage: 8Gi volumeMode: Filesystem accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Recycle storageClassName: slow mountOptions: - hard - nfsvers=4.1 nfs: path: /home/k8s/nfs server: 172.16.4.169 [root@k8s-master statefulset]# kubectl apply -f pv0.yml persistentvolume/pv-volume1 created
|
2.3、查看对应的服务
PowerShell [root@k8s-master statefulset]# kubectl get pod,statefulset NAME READY STATUS RESTARTS AGE pod/myapp-deploy-786f88884c-89srx 1/1 Running 0 2d2h pod/nginx-demo 1/1 Running 0 24h pod/nginx-deployment-644898db96-d7k77 1/1 Running 0 2d2h pod/nginx-deployment-644898db96-rcxt5 1/1 Running 0 2d2h pod/nginx-tcp-liveness-probe 0/1 Running 0 2d2h pod/web-0 1/1 Running 0 19m pod/web-1 1/1 Running 0 18m
NAME READY AGE statefulset.apps/web 2/2 19m [root@k8s-master statefulset]# kubectl get pv,pvc NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/pv-volume 50Gi RWO Recycle Bound default/www-web-0 slow 23m persistentvolume/pv-volume1 8Gi RWO Recycle Bound default/www-web-1 slow 9m22s persistentvolume/task-pv-volume 50Gi RWO Retain Bound default/pvc-claim manual 12d
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/pvc-claim Bound task-pv-volume 50Gi RWO manual 12d persistentvolumeclaim/www-web-0 Bound pv-volume 50Gi RWO slow 19m persistentvolumeclaim/www-web-1 Bound pv-volume1 8Gi RWO slow 18m
|
2.4、statefulset总结
• 匹配 Pod name ( 网络标识 ) 的模式为:$(statefulset名称)-$(序号),从零开始,比如上面的示例:web-0,web-1, web-2
• StatefulSet 为每个 Pod 副本创建了一个 DNS 域名,这个域名的格式为: $(podname).(headless server name),也就意味着服务间是通过Pod域名来通信而非 Pod IP,因为当Pod所在Node发生故障时, Pod 会 被飘移到其它 Node 上,Pod IP 会发生变化,但是 Pod 域名不会有变化
• StatefulSet 使用 Headless 服务来控制 Pod 的域名,这个域名的 FQDN 为:$(service name).$(namespace).svc.cluster.local
• 根据 volumeClaimTemplates,为每个 Pod 创建一个 pvc,pvc 的命名规则匹配模式: (volumeClaimTemplates.name)-(pod_name),比如上面的 volumeMounts.name=www, Pod name=web-[0-2],因此创建出来的 PVC 是 www-web-0、www-web-1、www-web-2
• 删除 Pod 不会删除其 pvc,手动删除 pvc 将自动释放 pv
Statefulset的启停顺序:
• 有序部署:部署StatefulSet时,如果有多个Pod副本,它们会被顺序地创建(从0到N-1),并且,在下一个 Pod运行之前所有之前的Pod必须都是Running和Ready状态。
• 有序删除:当Pod被删除时,它们被终止的顺序是从N-1到0。
• 有序扩展:当对Pod执行扩展操作时,与部署一样,它前面的Pod必须都处于Running和Ready状态。