当前位置 : 主页 > 操作系统 > centos >

K8S-Statefulset控制器

来源:互联网 收集:自由互联 发布时间:2023-08-21
一、statefulset简介 statefulset是用来管理有效状态应用的工作负载API对象,也是一种POD控制器,那为什么要放在PV/PVC之后再简介呢?这是因为statefulset是必须也有持久化数据,每个POD所对应

一、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配置一个唯一的名称。​

K8S-Statefulset控制器_Pod


二、statefulset实例

1、通过nfs创建共享存储

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

[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

[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所对应的存储空间是不一样的。​

##在创建一个新的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、查看对应的服务

[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状态。

上一篇:配置haproxy负载均衡群集
下一篇:没有了
网友评论