对比Deployment用于部署无状态服务,StatefulSet通常用于管理有状态的应用程序,同样基于Pod模板管理其Pod,但与Deployment最大的不同在于StatefulSet始终将一系列不变的名字分配给其Pod,且每个Pod都对应一个特有的持久化存储标识,也就是无论怎么调度,每个Pod都有一个永久不变的ID。
StatefulSet可以应用于以下应用场景:
(1)稳定的、唯一的网络标识符;
(2)稳定的、持久的存储;
(3)有序的、优雅的部署和扩缩;
(4)有序的,自动的滚动更新。
比如Redis的主从部署,就比较适合于StatefulSet,因为主节点的ID不变,从节点可以固定得指向主节点。
1. 定义一个StatefulSet
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: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
name: web
StatefulSet依赖一个Headless Service(无头服务),也就是clusterIP为none,用于控制网络域。
2. 创建StatefulSet
kubectl apply -f 文件名.yml
[root@k8s-master1 statefulSet]# kubectl apply -f 01-create-statefulset.yml
service/nginx created
statefulset.apps/web created
注:更新和删除操作与Deployment类似,比如更新可以用kubectl replace -f,删除可以用kubectl delete -f。
3. 查看StatefulSet
kubectl get statefulset
或者kubectl get sts
[root@k8s-master1 statefulSet]# kubectl get statefulset
NAME READY AGE
web 2/2 76s
[root@k8s-master1 statefulSet]# kubectl get sts
NAME READY AGE
web 2/2 81s
查看StatefulSet配置信息:kubectl get statefulset 名称 -o yaml
查看pods信息:kubectl get pods
[root@k8s-master1 statefulSet]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 113s
web-1 1/1 Running 0 75s
(1)有序索引
对于有N个副本的StatefulSet,其每个Pod将被分配一个从0到N-1的整数序号。
(2)稳定的网络ID
StatefulSet 中的每个 Pod 根据 StatefulSet 的名称和 Pod 的序号派生出它的主机名。 组合主机名的格式为(序号)。例如上面的通过kubectl get pods查询出来的web-0和web-1。
4. 部署和扩缩
- 对于包含 N 个 副本的 StatefulSet,当部署 Pod 时,它们是依次创建的,顺序为 0…N-1。
- 当删除 Pod 时,它们是逆序终止的,顺序为 N-1…0。
- 在将扩缩操作应用到 Pod 之前,它前面的所有 Pod 必须是 Running 和 Ready 状态。
- 在一个 Pod 终止之前,所有的继任者必须完全关闭。
我们在测试的时候,可以通过kubectl get pods -w 来观察pod的变化。
[root@k8s-master1 ~]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 10m
web-1 1/1 Running 0 10m
web-2 1/1 Running 0 82s
web-2 1/1 Terminating 0 93s
web-2 0/1 Terminating 0 94s
web-2 0/1 Terminating 0 95s
web-2 0/1 Terminating 0 95s
web-1 1/1 Terminating 0 10m
web-1 0/1 Terminating 0 10m
web-1 0/1 Terminating 0 10m
web-1 0/1 Terminating 0 10m
5. 更新策略
通过.spec.updateStrategy.type来配置StatefulSet的更新策略,有两种策略类型,具体如下:
(1)OnDelete: 手动删除Pod之后,StatefulSet才会创建新的Pod。
(2)RollingUpdate:
updateStrategy:
rollingUpdate:
partition: 0
type: RollingUpdate
这个StatefulSet默认的更新策略,StatefulSet对其管理的Pod执行自动的滚动更新,其中partition用于指定更新的序号范围,比如上面配置的0,表示所有的Pod需要大于等于0的,都更新。
我们可以利用该功能做灰度发布,也就是更新Pod时,我们指定某一些partition,但测试没有问题之后,再全量更新。