k8s--基础--21--Statefulset

2023-11-05

k8s–基础–21–Statefulset


1、概念

StatefulSet是为了解决有状态服务的问题而设计,对应Deployments和ReplicaSets是为无状态服务。

1.1、应用场景

  1. 稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据
    1. 基于PVC来实现
  2. 稳定的网络标志,即Pod重新调度后其PodName和HostName不变
    1. 基于Headless Service(即没有Cluster IP的Service)来实现
  3. 有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次进行(即从0到N-1,在下一个Pod运行之前的所有Pod必须都是Running和Ready状态)
    1. 基于init containers来实现
  4. 有序收缩,有序删除(即从N-1到0)

1.2、StatefulSet组成

  1. 通过Headless Service生成可解析的DNS记录
  2. 通过volumeClaimTemplates创建pvc和对应的pv绑定
  3. 定义StatefulSet来创建pod

2、StatefulSet和Deployment区别

2.1、相同点

  1. StatefulSet和Deployment 都管理了基于相同容器定义的一组Pod。
  2. StatefulSet和Deployment 都使用相同的工作模式

2.2、不同点

  1. StatefulSet 为它们的每个 Pod 维护了一个固定的ID。
    1. 这些 Pod 是基于相同的声明来创建的,但是不能相互替换
    2. 无论怎么调度,每个 Pod 都有一个永久不变的ID。
  2. Deployment 没有为它们的每个 Pod 维护一个固定的ID。
    1. 这些 Pod 能相互替换
    2. 每个 Pod 的ID不是固定
  3. 在deployment中创建的存储卷是一个共享的存储卷,不能适用于有状态应用。
    1. 多个pod使用同一个存储卷
    2. 多个pod存储数据是同步的
  4. 在statefulset中创建的存储卷不是一个共享的存储卷,适用于有状态应用。
    1. 每个pod都不会出现共享存储卷
    2. 每个pod的存储卷都不一样

3、StatefulSet中每个Pod的DNS格式

statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local

  1. serviceName:Headless Service的名字
  2. 0…N-1:Pod所在的序号,从0开始到N-1
  3. statefulSetName:StatefulSet的名字
  4. namespace:服务所在的namespace,Headless Servic和StatefulSet必须在相同的namespace
  5. svc.cluster.local:Cluster Domain

4、部署

4.1、涉及的命令

kubectl apply -f /root/test3/nginx-service.yaml
kubectl delete -f /root/test3/nginx-service.yaml

kubectl apply -f /root/test3/statefulset-nginx.yaml
kubectl delete -f /root/test3/statefulset-nginx.yaml


kubectl get svc nginx-service
kubectl describe svc nginx-service

kubectl get pods -w -l la_nginx=nginx

4.2、创建Service

vi  /root/test3/nginx-service.yaml

内容

 
apiVersion: v1
kind: Service
metadata: 
  name: nginx-service
  labels:
     la_nginx-service: nginx
spec:
  ports:
  - port: 80
    name: nginx-port
  clusterIP: None
  selector:
    la-nginx: nginx

4.2、创建pod

vi  /root/test3/statefulset-nginx.yaml

内容



apiVersion: apps/v1
kind: StatefulSet
metadata: 
  name: statefulset-nginx
spec:
  selector:
    matchLabels:
      la_nginx: nginx
  serviceName: "nginx"
  replicas: 2
  template:
    metadata: 
     labels:
       la_nginx: nginx
    spec: 
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: nginx
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests: 
          storage: 100Mi

4.3、为什么要使用volumeClaimTemplate

  1. 要适用有状态应用,需要保证statefulset定义中的每一个pod都不能使用同一个存储卷。
  2. volumeClainTemplate可以满足上面的要求
    1. 当在使用statefulset创建pod时,会自动生成一个PVC,从而请求绑定一个PV,这样每一个pod都有自己专用的存储卷。

4.3.1、Pod、PVC和PV对应的关系图

在这里插入图片描述

4.3.2、使用volumeClaimTemplate的前提

需要创建pv和pvc。

4.4、查看

4.4.1、 查看pod

 
[root@master1 test3]# kubectl get pods --show-labels
NAME                              READY   STATUS    RESTARTS   AGE     LABELS
statefulset-nginx-0               1/1     Running   0          64m     controller-revision-hash=statefulset-nginx-59bd4967d6,la_nginx=nginx,statefulset.kubernetes.io/pod-name=statefulset-nginx-0
statefulset-nginx-1               1/1     Running   0          64m     controller-revision-hash=statefulset-nginx-59bd4967d6,la_nginx=nginx,statefulset.kubernetes.io/pod-name=statefulset-nginx-1 

kubectl get pods -w -l la_nginx=nginx

在这里插入图片描述

4.4.2、 查看service

kubectl get svc nginx-service

在这里插入图片描述

4.4.3、查看statefulset

kubectl get statefulset statefulset-nginx 

在这里插入图片描述

4.4.4、查看PersistentVolumeClaims


kubectl get pvc -l la_nginx=nginx

在这里插入图片描述

StatefulSet控制器 自动创建了2个PersistentVolumeClaims,自动绑定到2个PersistentVolumes。

5、顺序创建 Pod

在这里插入图片描述

  1. 对于拥有N个副本的 StatefulSet,Pod被部署时是按照 {0…N-1}的序号顺序创建的。
  2. 注意:在nginx-0 Pod处于Running和Ready状态后,nginx-1 Pod才会被启动。

6、StatefulSet中的Pod

Pod拥有一个唯一的顺序索引和稳定的网络身份标识

6.1、顺序索引

在这里插入图片描述

  1. StatefulSet控制器分配给每个Pod的唯一顺序索引,Pod的名称的形式如下
    -

  2. 举例:上面StatefulSet拥有两个副本,所以它创建了两个Pod:nginx-0和nginx-1

6.2、稳定的网络身份标识

  1. 每个Pod都拥有一个基于其顺序索引的稳定的主机名
  2. 主机名:由statefulset的名称和有序索引组成

6.2.1、查看主机名

 
# 获取pod的主机名
kubectl exec statefulset-nginx-0  	-- sh -c 'hostname';  
kubectl exec statefulset-nginx-1 	-- sh -c 'hostname';  

在这里插入图片描述

6.2.2、查看集群内部的DNS地址(域名地址|SRV记录)

 
# 查看集群内部的DNS地址 
kubectl exec statefulset-nginx-0 -- hostname -f
kubectl exec statefulset-nginx-1 -- hostname -f

在这里插入图片描述

6.2.3、验证网络身份标识是稳定的

6.2.3.1、在一个终端中查看 StatefulSet的Pod。
kubectl get pods -w -l la_nginx=nginx
6.2.3.2、在另一个终端中删除StatefulSet中所有的Pod。
kubectl delete Pod -l la_nginx=nginx

6.2.3.3、等待StatefulSet重启它们,并且两个Pod都变成Running,Ready状态

在这里插入图片描述

6.2.3.4、查看集群内部的DNS地址

在这里插入图片描述

  1. Pod的序号、主机名、SRV条目和记录名称没有改变,但和Pod相关联的IP地址可能发生了改变,所以不要在其他应用中使用 StatefulSet中的Pod的IP 地址进行连接
  2. 通过查询Headless Service 的CNAME来连接一个StatefulSet的活动成员
    1. CNAME相关联的 SRV记录 只会包含StatefulSet中处于Running和Ready状态的Pod。
  3. 如果你的应用已经实现了用于测试liveness和readiness的连接逻辑,你可以使用Pod的SRV记录,因为他们是稳定的,并且当你的Pod的状态变为 Running 和 Ready 时,你的应用就能够发现它们的地址。以下是上面pod的SRV记录
    1. statefulset-nginx-0.nginx.default.svc.cluster.local
    2. statefulset-nginx-1.nginx.default.svc.cluster.local

7、部署和扩缩容

  1. 对于包含N个副本的StatefulSet,当部署Pod时,它们是依次创建的,顺序为 0…N-1。
  2. 当删除Pod 时,它们是逆序终止的,顺序为 N-1…0。
  3. 在将缩放操作应用到Pod之前,它前面的所有Pod必须是Running和Ready状态。
  4. 在Pod终止之前,所有的继任者必须完全关闭。

7.1、注意

  1. StatefulSet不应将pod.Spec.TerminationGracePeriodSeconds设置为0。
    1. 这种做法是不安全的,要强烈阻止。
    2. 更多的解释请参考
      https://kubernetes.io/docs/tasks/run-application/force-delete-stateful-set-pod/
      

7.2、案例说明

假设部署POD数量为3,对应的名称如下

statefulset-nginx-0
statefulset-nginx-1
statefulset-nginx-2

7.2.1、顺序部署pod

  1. statefulset-nginx被创建后,会按照statefulset-nginx-0、statefulset-nginx-1、statefulset-nginx-2的顺序部署Pod。

  2. 在 statefulset-nginx-0 进入 Running 和 Ready 状态前不会部署 statefulset-nginx-1。

  3. 在 statefulset-nginx-1 进入 Running 和 Ready 状态前不会部署 statefulset-nginx-2。

  4. 如果 statefulset-nginx-1 已经处于 Running 和 Ready 状态,而 statefulset-nginx-2 尚未部署,在此期间发生了 statefulset-nginx-0 运行失败,那么 statefulset-nginx-2 将不会被部署,要等到 statefulset-nginx-0 部署完成并进入 Running 和 Ready 状态后,才会部署 statefulset-nginx-2。

7.2.2、收缩Pod–>将 statefulset-nginx 收缩为 replicas=1

  1. 首先被终止的是 statefulset-nginx-2。
    1. 在 statefulset-nginx-2 没有被完全停止和删除前,statefulset-nginx-1 不会被终止。
  2. 当 statefulset-nginx-2 已被终止和删除、statefulset-nginx-1 尚未被终止,如果在此期间发生 statefulset-nginx-0 运行失败,那么就不会终止 statefulset-nginx-1,必须等到 statefulset-nginx-0 进入 Running 和 Ready 状态后才会终止 statefulset-nginx-1。

8、Statefulset 重点内容

8.1、Pod selector

必须设置StatefulSet的.spec.selector字段,使之匹配其在.spec.template.metadata.labels中设置的标签。

在这里插入图片描述

8.2、Pod Identity(pod标识)

  1. StatefulSet Pod 具有唯一的标识,该标识包括顺序标识、稳定的网络标识和稳定的存储。2. 该标识和Pod是绑定的,不管它被调度在哪个节点上。

8.3、有序索引

  1. 对于具有N个副本的StatefulSet,StatefulSet中的每个Pod 将被分配一个整数序号,从 0 到 N-1
  2. 该序号在StatefulSet上是唯一的。

8.4、稳定的网络ID

8.4.1、主机名,网络域,DNS子域

  1. StatefulSet中的每个Pod根据StatefulSet的名称和Pod的序号派生出它的主机名。
    2. 组合主机名格式: ( S t a t e f u l S e t 名称 ) − (StatefulSet名称)- (StatefulSet名称)(序号)。

  2. StatefulSet可以使用headless服务 控制它的Pod的网络域。

    1. 格式为: ( 服务名称 ) . (服务名称). (服务名称).(命名空间).svc.cluster.local
      1. cluster.local:集群域。
  3. 一旦每个Pod创建成功,就会得到一个匹配的DNS子域

    1. 格式为: ( p o d 名称 ) . (pod 名称). (pod名称).(所属服务的 DNS 域名)
      1. 所属服务由 StatefulSet的serviceName域来设定。
  4. 案例:下面给出一些选择集群域、服务名、StatefulSet名、及其怎样影响StatefulSet的Pod上的DNS名称的示例

    1. 在这里插入图片描述

    2. 注意: 集群域会被设置为 cluster.local,除非有其他配置。

8.5、标签

  1. 当StatefulSet控制器创建 Pod 时,它会添加一个标签statefulset.kubernetes.io/pod-name,该标签设置为Pod名称。
  2. 这个标签允许您给 StatefulSet 中的特定 Pod 绑定一个 Service。

9、扩展

9.1、Pod 管理策略

  1. StatefulSet允许您放宽pod的排序保证
  2. 通过.spec.podManagementPolicy,保证pod的唯一性和身份保证。

9.2、OrderedReadyPod 管理

  1. 是 StatefulSet的默认设置。
  2. 实现了9.1的功能。

9.3、ParallelPod 管理

让StatefulSet控制器并行的启动或终止所有的Pod,启动或者终止其他Pod前,无需等待Pod进入Running和ready或者完全停止状态。

9.4、更新策略

通过.spec.updateStrategy让你可以配置和禁用掉自动滚动更新Pod的容器、标签、资源请求或限制、以及注解。

9.5、删除策略

  1. .spec.updateStrategy.type=OnDelete
    1. 它的控制器将不会自动更新 StatefulSet中的Pod。用户必须手动删除Pod以便让控制器创建新的Pod,以此来对StatefulSet的 .spec.template 的变动作出反应。

9.6、滚动更新

  1. 字段:.spec.updateStrategy
  2. 值:RollingUpdate(默认值)
    1. 对 StatefulSet中的Pod 执行自动的滚动更新。
    2. StatefulSet控制器会删除和重建 StatefulSet中的每个Pod
      1. 它将从Pod的最大序号到最小序号进行
      2. 每次更新一个Pod。它会等到被更新的Pod进入Running和Ready 状态,然后再更新其前身。

9.7、分区

  1. 字段:.spec.updateStrategy.rollingUpdate.partition
  2. RollingUpdate 更新策略可以实现分区。
    1. 如果声明了一个分区,当 StatefulSet的 .spec.template 被更新时
      1. 所有序号大于等于该分区序号的Pod 都会被更新
      2. 所有序号小于该分区序号的Pod 都不会被更新
      3. 即使他们被删除也会依据之前的版本进行重建。
  3. 如果.spec.updateStrategy.rollingUpdate.partition 大于.spec.replicas,对它的 .spec.template 的更新将不会传递到它的Pod。
  4. 在大多数情况下,您不需要使用分区,但如果您希望进行阶段更新、执行金丝雀或执行分阶段展开,则这些分区会非常有用。

9.8、强制回滚

  1. Pod 管理策略(OrderedReady)默认使用 滚动更新 ,可能进入需要人工干预才能修复的损坏状态。
  2. 如果更新后Pod 模板配置进入无法运行或就绪的状态(例如,由于错误的二进制文件或应用程序级配置错误),StatefulSet将停止回滚并等待。
    1. 在这种状态下,仅将Pod 模板还原为正确的配置是不够的。由于已知问题,StatefulSet将继续等待损坏状态的Pod 准备就绪(永远不会发生),然后再尝试将其恢复为正常工作配置。
  3. 恢复模板后,还必须删除StatefulSet尝试使用错误的配置来运行的Pod。这样,StatefulSet才会开始使用被还原的模板来重新创建Pod。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

k8s--基础--21--Statefulset 的相关文章

随机推荐

  • 蓝桥杯考生规则

    2017年模拟赛 本科组 考生须知 l 考试开始后 选手首先下载题目 并使用考场现场公布的解压密码解压试题 l 考试时间为4小时 时间截止后 提交答案无效 l 在考试强制结束前 选手可以主动结束考试 需要身份验证 结束考试后将无法继续提交或
  • java计算机毕业设计火车订票系统源码+mysql数据库+系统+lw文档+部署

    java计算机毕业设计火车订票系统源码 mysql数据库 系统 lw文档 部署 java计算机毕业设计火车订票系统源码 mysql数据库 系统 lw文档 部署 本源码技术栈 项目架构 B S架构 开发语言 Java语言 开发软件 idea
  • Tomcat调优

    问题定位 对于Tomcat的处理耗时较长的问题主要有当时的并发量 session数 内存及内存的回收等几个方面造成的 出现问题之后就要进行分析了 1 关于Tomcat的session数目 这个可以直接从Tomcat的web管理界面去查看即可
  • Go语言学习13-类型转换

    类型转换 引言 类型转换 1 概念 2 数值类型之间的转换 3 与string类型相关的转换 4 别名类型值之间的转换 结语 引言 在上一篇博文中 我们介绍了 Go 语言的 数据的使用 本篇博文 我们将介绍 Go 语言的类型转换 类型转换
  • HTTP头的Expires与Cache-control

    1 概念 Cache control用于控制HTTP缓存 在HTTP 1 0中可能部分没实现 仅仅实现了Pragma no cache 数据包中的格式 Cache Control cache directive cache directiv
  • 程序员的十个等级

    转载自 http blog csdn net fx0000001 article details 50397265 如果你还迷茫请看这里 如果你很牛逼请看这里 如果你很自傲请看这里 总有你想学会的 自西方文艺复兴以来 中国在自然科学方面落后
  • 不带头结点的单链表

    建立结构体 和带头结点但单链表一样 按需建立即可 我以建立一个储存学生信息的链表举例 typedef struct node char name 20 int number struct node next Node LinkList 单链
  • 探索全桥电机驱动模块:实现精确控制与高效驱动

    全桥电机驱动模块是一种在现代工程应用中广泛使用的电机驱动方式 对于需要精确控制和高效驱动的场景 如机器人 无人机 电动车等 全桥电机驱动模块提供了理想的解决方案 本文将介绍全桥电机驱动模块的原理和实际应用场景 并对几种常见的全桥驱动芯片进行
  • csdn的Markdown行首缩进的两种方法,非常全

    csdn的行首缩进 鉴于不同编辑器的Markdown语法略微不同 故缩进也略不同 1 特殊占位符 不缩进 行首缩进 nbsp 行首缩进 160 四分之一中文占位符 行首缩进 8197 四分之一中文占位符 行首缩进 ensp 行首缩进 819
  • Spring中Bean的生命周期

    Spring Bean的生命周期是从Bean 实例化之后 即通过反射创建出对象之后 到Bean成为一个完整对象 最终存储到单例池中 这个过程被称为Spring Bean的生命周期 Spring Bean的生命周期大体上分为四个阶段 实例化
  • vue2.0项目调用多个IP接口

    项目中经常遇到跨域问题 最简单的方式就在本地配置代理 可偶尔遇到一个页面里面需要调用来自两个以上不同IP段的接口 多个IP要怎么配置代理呢 请往下看 在项目目录 config index js文件配置代理 module exports de
  • pytest

    一 pytest是单元测试框架 单元测试 对软件开发中 对软件的最小单位 函数 方法 进行正确性检查测试 java框架 jnuit和testing python框架 unittest和pytest 流程 i 测试发现 从多个文件中找到测试用
  • 英俊飘逸气宇轩昂——同人立绘征集大赛凤九天·金奖

    导语 本期介绍的作品是由来自江西科技师范大学的计世平设计的凤九天形象 荣获了本次大赛凤九天组别的金奖 2020年12月22日 由首都版权协会联合全国部分高等院校和链游玩家及部分企业共同举办的 2020同人立绘征集大赛 正式启动 并于2021
  • 详解pop()和push()方法

    pop 是移除堆栈顶部的元素并且返回它的值 push 是把对象压入堆栈的顶部 这里的堆栈不是特指栈 是LinkedList中特有的方法 LinkedHashset和LinkedHashMap ArrayList中没有此方法 下面是个小李子
  • Unity UV 水效果实现

    Unity UV 水效果实现 Unity Water Shader 组件搭载 基本参数调节 所需图片 效果呈现 Unity Water Shader Shader Custom SeaWave Properties WaterTex 水纹理
  • 潘周聃之Python分聃 -----数字雨加入潘周聃运动曲线

    作者 勇敢di牛牛 个人项目地址 englishlearningapp 个人简介 有一年工作经验的大学生 工作 汽车系统应用开发 阿里集团 个人网站 牛牛 小窝 独学而无友 则孤陋而寡闻 前言 相信各位同学最近一定被潘周聃刷屏和洗脑了 互联
  • seaborn可视化——一文搞懂heatmap参数

    文章目录 data cmap linewidths linecolor square ax annot 指定为True 指定为同形状数组 vmax vmin annot kws mask xticklabels yticklabels 设置
  • linux 命令 ls 与 ls -lrt 的区别

    ls lrt 表示按修改时间倒序列出当前工作目录下的文件 ls l 表示按名称顺序正序列出当前工作目录下的文件 1 ls 表示列出当前目录下的文件 后面的 lrt 是这个命令的一些选项补充 lrt 实际上是代表了 l r t 这三个选项集合
  • 对sklearn中transform()和fit_transform()的深入理解

    在用机器学习解决问题时 往往要先对数据进行预处理 其中 z score归一化和Min Max归一化是最常用的两种预处理方式 可以通过sklearn preprocessing模块导入StandardScaler 和 MinMaxScaler
  • k8s--基础--21--Statefulset

    k8s 基础 21 Statefulset 1 概念 StatefulSet是为了解决有状态服务的问题而设计 对应Deployments和ReplicaSets是为无状态服务 1 1 应用场景 稳定的持久化存储 即Pod重新调度后还是能访问