是k8s中常见的pod控制器类型之一
ReplicaSet:即RS
Deployment
DaemonSet:即DS
StatefulSet
Job
Cronjob
我们在生产中常用的副本(pod)控制器如Deployment,DaemonSet,RS都是使用于无状态服务,其所管理的Pod的启停顺序,IP,Pod名称都是随机的,被管理的Pod更新时,这些都会发生变化,而我们在管理如mysql,redis,kafka,consul这些集群是为了管理方便,就可以使用
有状态服务statefulSet
Kubernetes中StatefulSet是专为有状态服务如mysql、redis、kafka、consul等集群准备的集合,管理所有有状态服务。
注:无状态服务同样可以使用statefulset控制器
简单理解(个人理解)
无状态服务里随机的参数(Pod的启停顺序、IP、Pod名称)在有状态服务里都不是随机的,有顺序的
详细解释
无状态服务(Stateless Services):
1.在 Kubernetes 中,无状态服务通常以 Deployment 或者 ReplicaSet 的方式进行部署和管理。
2.无状态服务的实例可以随意扩展和收缩,因为它们之间是相互替换的,而且不需要关注特定实例的状态。
3.无状态服务可以使用水平扩展来应对高负载,Kubernetes 可以根据实际负载自动添加或移除实例。
有状态服务(Stateful Services):
1.在 Kubernetes 中,有状态服务通常以 StatefulSet 的方式进行部署和管理。
2.StatefulSet 提供了稳定的网络标识和持久化存储的能力,确保每个实例都有唯一的标识并且可以使用持久化卷来保存状态数据。
3.有状态服务的实例通常需要按照确定的顺序部署和扩展,因为它们的状态数据可能会影响到服务的行为。
主要用来管理有状态应用的控制器。
用来管理某Pod集合的部署和扩缩,并为这些 Pod 提供持久存储和持久标识符。
1.稳定的网络标识:StatefulSet 中的每个 Pod 都有一个稳定的网络标识符(例如 hostname),这使得这些 Pod 可以有确定的网络身份,并且可以被其他应用程序依赖和访问。
2.有序部署和扩展:StatefulSet 保证 Pod 的部署和扩展是按照确定的顺序进行的,每个 Pod 都有一个唯一的标识符,这对于需要有序启动和停止的应用程序非常重要。
3.持久化存储:StatefulSet 支持使用持久卷(PersistentVolume)来存储 Pod 的状态数据,确保即使 Pod 被重新调度到其他节点,其状态数据也不会丢失。
4.自主管理的标识符:StatefulSet 可以为每个 Pod 分配一个自主管理的标识符,例如在有状态服务中使用的索引或者名称。这些标识符可以在 Pod 重新启动或者重新调度后保持不变。
5.有状态服务的更新:StatefulSet 支持有状态服务的滚动更新,确保在更新过程中不会破坏服务的可用性,并且可以保持有状态服务的稳定性。
一个完整的StatefulSet应用由三个部分组成:
headless service、
StatefulSet controller、
volumeClaimTemplate。
headless service(无头服务)
简单来说就是没有群集ip
Ip | 主机名 | cpu | 内存 | 硬盘 |
---|---|---|---|---|
192.168.10.11 | master | 1cpu双核 | 2G | 40G |
192.168.10.12 | node01 | 1cpu双核 | 2G | 40G |
192.168.10.13 | node02 | 1cpu双核 | 2G | 40G |
192.168.10.17 | nfs | 1cpu1核 | 1G | 40G |
虚拟机 centos7.9
master node01 node02 已部署k8s集群
版本 1.18.0
nfs服务器部署nfs
由于nfs是新创建的虚拟机需要关闭防火墙,关闭沙盒
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/sysconfig/selinux
所有主机都需要安装nfs
yum -y install nfs-utils rpcbind
其次在nfs主机上
mkdir /nfsdata
vim /etc/exports
输入
/nfsdata *(rw,sync,no_root_squash)
systemctl start rpcbind
systemctl start nfs-server
systemctl enable rpcbind
systemctl enable nfs-server
showmount -e
看到这个nfs就部署成功了
yaml文件内容详见,这里不再过多记述
链接: storageclass详细解释与应用
创建账号、创建权限、给账号关联权限
[root@master ~]# kubectl apply -f account.yaml
通过中间件将访问账号与共享存储关联
[root@master ~]# kubectl apply -f nfs-deployment.yaml
配置storageclass与中间件关联
[root@master ~]# kubectl apply -f storageclass.yaml
为什么用headless service无头服务?
在用Deployment时,每一个Pod名称是没有顺序的,是随机字符串,因此是Pod名称是无序的,但是在statefulset中要求必须是有序,每一个pod不能被随意取代,pod重建后pod名称还是一样的。
在有状态服务中,pod名称是pod唯一性的标识符,必须持久稳定有效。这时候要用到无头服务,它可以给每个Pod一个唯一的名称。
**为什么用volumeClaim Template?
对于有状态的副本集都会用到持久存储,特别是对于分布式系统来讲,它的最大特点是数据是不一样的,所以各个节点不能使用同一存储卷,每个节点有自已的专用存储,
但是如果在Deployment中的Pod template里定义的存储卷,是所有副本集共用一个存储卷,数据是相同的,因为是基于模板来的,
而statefulset中每个Pod都要自已的专有存储卷,所以statefulset的存储卷就不能再用Pod模板来创建了,于是statefulSet使用volumeClaimTemplate,称为卷申请模板,它会为每个Pod生成不同的pvc,并绑定pv,从而实现各pod有专用存储。
[root@master yaml]# vim nfs-deployment.yaml
apiVersion: v1
kind: Service
metadata:
name: headless-svc
labels:
app: headless-svc
spec:
ports:
- name: myweb
port: 80
selector:
app: headless-pod
clusterIP: None
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: statefulset
spec:
serviceName: headless-svc
replicas: 3
selector:
matchLabels:
app: headless-pod
template:
metadata:
labels:
app: headless-pod
spec:
containers:
- name: myweb
image: nginx:1.20
imagePullPolicy: IfNotPresent
volumeMounts:
- name: test-storage
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: test-storage
annotations:
volume.beta.kubernetes.io/storage-class: storageclass
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
[root@master yaml]# kubectl apply -f statefulset.yaml
[root@master yaml]# kubectl get pv,pvc
从上面可以看到
storageclass自动创建了PV
volumeClaimTemplate自动创建了PVC
现在测试每一个Pod是否有自己独特的数据持久化目录,也就是说,每一个Pod内的数据是不是都是不一样的
分别在对应的PV下,模拟创建不同的数据。
[root@nfs ~]# echo 000 > /nfsdata/default-test-storage-statefulset-0-pvc-6ff2b4bf-789a-4fd3-987e-72db4fb2fa09/testfile
[root@nfs ~]# echo 111 > /nfsdata/default-test-storage-statefulset-1-pvc-7076ef24-3ea7-419a-abed-4dc27886681a/testfile
[root@nfs ~]# echo 222 > /nfsdata/default-test-storage-statefulset-2-pvc-bc5df9e7-183e-4c70-9574-e8cb48823bae/testfile
查看对应Pod的数据持久化目录,可以看出,每个Pod的内容都不一样
[root@master yaml]# kubectl exec -it statefulset-0 -- cat /usr/share/nginx/html/testfile
000
[root@master yaml]# kubectl exec -it statefulset-1 -- cat /usr/share/nginx/html/testfile
111
[root@master yaml]# kubectl exec -it statefulset-2 -- cat /usr/share/nginx/html/testfile
222
可以看到是不一样的
实验完成
如果对您有帮助就点个赞吧