前边我们讲了deployment来管理pod容器的副本数量,如果挂掉之后容器再次启动就可以了,但是如果要是启动的是mysql集群、zookeeper集群、etcd这种集群,里面都有id号,这种有关联的,如果一旦挂掉之后,在启动之后呢,集群id是否会变化呢?答案是肯定会变的。
那有没有另外的一种控制器模式吗?当然k8s会提供的--【statefulset】
那什么场景需要使用StatefulSet呢?官方给出的建议是,如果你部署的应用满足以下一个或多个部署需求,则建议使用StatefulSet。
1)稳定的、唯一的网络标识。
2)稳定的、持久的存储。
3)有序的、优雅的部署和伸缩。
4)有序的、优雅的删除和停止。
5)有序的、自动的滚动更新。
statefulset和deployment的区别
image.png分类
K8s有状态应用部署分为两步:
- Headless Service: Headless Service 其实和service差不多,只不过定义的这个叫无头服务,它们之间唯一的区别就是将Cluster ip 设置为了none,不会帮你配置ip
- StatefulSet:需要在pod模板中定义servicename。spec. serviceName。
Headless Service案例-不需要创建演示
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
clusterIP: None
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 9376
部署服务
kubectl create -f headless-svc.yaml
kubectl get svc
怎么去访问?我们给它定义一个标识。创建完之后会有这个标识符,它会使用这个DNS来解析这个名称,
来相互的访问,headless就不会通过ip去访问了,必须通过名称去访问。
statefulSet案例-不需要创建演示
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: nginx-statefulset
namespace: default
spec:
serviceName: my-service
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name:
nginx image: nginx:latest
ports:
- containerPort: 80
总结
Pod会被顺序部署和顺序终结:StatefulSet中的各个 Pod会被顺序地创建出来,每个Pod都有一个唯一的ID,在创建后续 Pod 之前,首先要等前面的 Pod 运行成功并进入到就绪状态。删除会销毁StatefulSet 中的每个 Pod,并且按照创建顺序的反序来执行,只有在成功终结后面一个之后,才会继续下一个删除操作。
Pod具有唯一网络名称:Pod具有唯一的名称,而且在重启后会保持不变。通过Headless服务,基于主机名,每个 Pod 都有独立的网络地址,这个网域由一个Headless 服务所控制。这样每个Pod会保持稳定的唯一的域名,使得集群就不会将重新创建出的Pod作为新成员。
Pod能有稳定的持久存储:StatefulSet中的每个Pod可以有其自己独立的PersistentVolumeClaim对象。即使Pod被重新调度到其它节点上以后,原有的持久磁盘也会被挂载到该Pod。
Pod能被通过Headless服务访问到:客户端可以通过服务的域名连接到任意Pod。
网友评论