对比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 的序号派生出它的主机名。 组合主机名的格式为(StatefulSet名称)(StatefulSet 名称)-(序号)。例如上面的通过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,但测试没有问题之后,再全量更新。

打赏
支付宝 微信
上一篇 下一篇