Kubernetes-StatefulSet
StatefulSet
StatefulSet(有状态集,缩写为sts)常用于部署有状态的且需要有序启动的应用程序,比如在进行SpringCloud项目容器化时,Eureka的部署时比较适合用StatefulSet部署方式的,可以给每个Eureka实例创建一个唯一且固定的标识符,并且每个Eureka实例无需配置多余的Service,其余Spring Boot应用可以直接通过Eureka的Headless Service即可进行注册。
- Eureka的statefulset的资源名称时eureka,eureka-0 eureka-1 eureka-2
- Service:headless service,没有ClusterIP eureka-svc
- Eureka-0,eureka-svc.NAMESPACE_NAME eureka1.eureka-svc...
StatefulSet主要用于管理有状态应用程序的工作负载API对象。比如再生产环境中,可以部署ElasticSearch集群、MongoDB集群或者需要持久化的RabbitMQ集群、Redis集群、Kafka集群和Zookeeper集群。
和Deployment类似,一个StatefulSet也同样管理着基于相同容器规范的Pod。不同的是,StatefulSet为灭个Pod都有一个持久的标识符,再重新调度时也会保留,一般格式为 StatefulSetName-Number。比如定义一个名字是Redis-Sentinel的StatefulSet,指定创建三个Pod,那么创建出来的Pod名字就为Redis-Sentinel-0、Redis-Sentinel-1、Redis-Sentinel-2。而StatefulSet创建的Pod一般使用Headless Service(无头服务)进行通信,和普通的Service的区别在于Headless Service没有ClusterIP,它使用的是Endpoint进行互相通信,Headless一般的格式为:
- statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local
说明:
- serviceName为Headless Service的名字,创建StatefulSet时,必须指定Headless Service名称;
- 0..N-1 为Pod所在的序号,从0开始到N-1;
- statefulSetName为StatefulSet的名字;
- namespace为服务所在的命名空间;
- .cluster.local为Cluster Domain(集群域)。
# 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: nginx-statefulset
namespace: default
spec:
serviceName: nginx
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
每个Pod都具有唯一标识符
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-statefulset-0 1/1 Running 0 64s
nginx-statefulset-1 1/1 Running 0 46s
nginx-statefulset-2 1/1 Running 0 27s
sts的svc是没有ClusterIP的
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 24h
nginx ClusterIP None <none> 80/TCP 86s
更新策略:
Partition: 2 #标识符小于2的不会被更新级联删除,同时删除所有statefulset中的pod
$ kubectl delete sts nginx-statefulset
statefulset.apps "nginx-statefulset" deleted
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-statefulset-0 1/1 Terminating 0 36m
nginx-statefulset-1 1/1 Terminating 0 35m
nginx-statefulset-2 1/1 Terminating 0 35m
非级联删除,直接删除sts,Pod变成了孤儿Pod,此时删除Pod不会被重建
$ kubectl delete sts nginx-statefulset --cascade=false
warning: --cascade=false is deprecated (boolean value) and can be replaced with --cascade=orphan.
statefulset.apps "nginx-statefulset" deleted
$ kubectl get sts
No resources found in default namespace.
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-statefulset-0 1/1 Running 0 89s
nginx-statefulset-1 1/1 Running 0 71s
nginx-statefulset-2 1/1 Running 0 52s
$ kubectl delete pod nginx-statefulset-0 nginx-statefulset-1 nginx-statefulset-2
pod "nginx-statefulset-0" deleted
pod "nginx-statefulset-1" deleted
pod "nginx-statefulset-2" deleted
$ kubectl get pods
No resources found in default namespace.