侧边栏壁纸
  • 累计撰写 45 篇文章
  • 累计创建 15 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

【kubernetes】有状态应用管理 StatefulSet

Administrator
2024-11-30 / 0 评论 / 0 点赞 / 27 阅读 / 4887 字 / 正在检测是否收录...

StatefulSet常用于部署有状态的且需要有序启动的应用程序。和Deployment类似,一个StatefulSet也同样管理着基于相同容器规范的Pod,不同的是,StatefulSet为每个Pod维护了一个粘性标识。

一般StatefulSet用于有以下一个或者多个需求的应用程序:

  • 需要稳定的独一无二的网络标识;

  • 需要持久化数据;

  • 需要有序的,优雅的部署和扩展;

  • 需要有序的自动滚动更新。

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:
  serviceName: "nginx"  # 和Deployment的区别之一
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: registry.cn-beijing.aliyuncs.com/jiangxiaonan/nginx:1.22.1
        ports:
        - containerPort: 80
          name: web

Service定义了一个名字为Nginx的Headless Service,创建的Service格式为nginx-0.nginx.defaule.svc.cluster.local,其他的类似,因为没有指定Namespace(命名空间),所以默认部署在defaule;

StatefulSet定义了一个名字为web的StatefulSet, replicas表示部署Pod的副本数, 本实例为2。

在 StatefulSet 中 必 须 设 置 Pod 选 择 器 ( .spec.selector ) 用 来 匹 配 其 标 签(.spec.template.metadata.labels)。

当 StatefulSet 控制器创建 Pod 时,它会添加一个标签 statefulset.kubernetes.io/pod-name,该标签的值为 Pod 的名称,用于匹配 Service。

2. 创建 StatefulSet

kubectl create -f sts-web.yaml   # 也可以使用-n 部署到其他 namespace
# kubectl get sts
NAME   READY   AGE
web    2/2     10m
# kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   169d
nginx        ClusterIP   None         <none>        80/TCP    11m
kubectl get po -l app=nginx
NAME                                READY   STATUS    RESTARTS   AGE
web-0                               1/1     Running   0          8m54s
web-1                               1/1     Running   0          8m52s

StatefulSet 创建 Pod 流程:

StatefulSet 管理的 Pod 部署和扩展规则如下:
1. 对于具有N个副本的StatefulSet,将按顺序从0到N-1开始创建Pod;
2. 当删除Pod时,将按照N-1到0的反顺序终止;
3. 在缩放Pod之前,必须保证当前的Pod是Running(运行中)或者Ready(就绪);
4. 在终止Pod之前,它所有的继任者必须是完全关闭状态。

3. StatefulSet 扩容和缩容

和 Deployment 类似,可以通过更新 replicas 字段扩容/缩容 StatefulSet,也可以使用 kubectlscale、 kubectl edit 和 kubectl patch 来扩容/缩容一个 StatefulSet。

可以直接修改副本数,例如:

kubectl scale sts web --replicas=5

# 或者使用patch命令
kubectl patch sts web -p '{"spec":{"replicas":3}}'

查看扩容后 Pod 的状态:

kubectl get po

也可使用以下命令动态查看:

kubectl get pods -w -l app=nginx

4. StatefulSet 更新策略

  • On Delete 策略

OnDelete 更新策略实现了传统(1.7 版本之前)的行为,它也是默认的更新策略。 当我们选择这个更新策略并修改 StatefulSet 的.spec.template 字段时, StatefulSet 控制器不会自动更新 Pod,必须手动删除 Pod 才能使控制器创建新的 Pod。

  • RollingUpdate 策略

RollingUpdate(滚动更新) 更新策略会自动更新一个 StatefulSet 中所有的 Pod,采用与序号索引相反的顺序进行滚动更新。

  • 分段更新

StatefulSet可以使用RollingUpdate更新策略的partition参数来分段更新一个StatefulSet。分段更新将会使StatefulSet中其余的所有Pod(序号小于分区)保持当前版本,只更新序号大于等于分区的Pod,利用此特性可以简单实现金丝雀发布(灰度发布)或者分阶段推出新功能等。

kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":2}}}}'

说明:有了partition参数不会自动更新,需要手动删除pod进行更新。

5. 删除StatefulSet

删除StatefulSet有两种方式,级联删除和非级联删除。使用非级联删除方式删除StatefulSet时,StatefulSet的Pod不会被删除;使用级联删除时,StatefulSet和他的Pod都会被删除。

级联删除:

kubectl delete statefulset web

非级联删除:

kubectl delete statefulset web --cascade=false # 采用非级联删除

说明:在级联删除的基础上,加上--cascade=false即为非级联删除。

使用非级联删除方式删除StatefulSet,它管理的Pod变成了“孤儿”Pod,因此单独删除Pod时,该Pod不会被重建。

0
博主关闭了所有页面的评论