【云原生】StatefulSet控制器详解

embedded/2024/9/24 8:08:55/

StatefulSet_0">StatefulSet

文章目录

  • StatefulSet
    • 一、介绍与特点
      • 1.1、介绍
      • 1.2、特点
      • 1.3、组成部分
      • 1.4、为什么需要无头服务
      • 1.5、为什么需要volumeClaimTemplate
    • 二、教程
    • 三、StatefulSet中的Pod
      • 3.1、检查Pod的顺序索引
      • 3.2、使用稳定的网络身份标识
      • 3.3、查看主机明内部DNS地址
    • 四、扩容/缩容StatefulSet
      • 4.1、扩容
      • 4.2、缩容
    • 五、更新StatefulSet
      • 5.1、滚动更新

一、介绍与特点

1.1、介绍

  • RC、Deployment、DaemonSet都是面向无状态的服务,它们所管理的Pod的IP、名字、启停顺序等都是随机的,而StatefulSet是什么?顾名思义,有状态的集合,管理所有有状态服务,比如MySQL、MongoDB集群等。
  • StatefulSet本质上是Deployment的一种变体,在v1.9版本中已成为GA版本,它为了解有状态服务的问题,它所管理的Pod拥有固定的Pod名称,启停顺序,在StatefulSet中,Pod名称为网络标识(hostname),还必须要用到共享存储。
  • 在Deployment中,与之对应的服务是service,而在StatefulSet中与之对应的是headless service即无头服务,与service的与别是它没有ClusterIP,解析它的名称时将返回该Headless Service对印的全部Pod的Endpoint(端点)列表。
  • 除此之外,StatefulSet在Headless Service的基础上又为StatefulSet控制的每个Pod副本创建了一个DNS域名,这个域名的格式为$(podname).(headless server name)FQDN: (podname).(headless servername).namespace.svc.cluster.local

1.2、特点

  • Pod的一致性:包含次序(启停、停止次序)、网络一致性。此一致性与Pod相关,与 呗调度到哪个node节点无关。

  • 稳定的次序:对于N个副本的StatefulSet,每个Pod都在[0-N]的范围内分配一个数字序号,且是唯一的。

  • 稳定的网络:Pod的hostname模式为(StatefulSet名称)-(序号)。

  • 稳定的存储:通过VolumeClaimTemplate为每个Pod创建一个PV。删除、减少副本,不会删除相关的卷。

1.3、组成部分

  • Headless Service:用来定义Po的网络标识(DNS domain)

  • volumeClaimTemplates:存储卷申请模板,创建PVC,指定pvc名称大小,将自动创建pvc,且pvc必须由存储类供应

1.4、为什么需要无头服务

  • 在用Deployment时,每一个Pod名称是没有顺序的,是随机字符串,因此Pod名称是无序的,但是在StatefulSet中要求必须是有序的,每个Pod不能随意取代,Pod重建后Pod名称还是一样的。而Pod IP是变化的,所以是以Pod名称来识别,Pod名称是Pod唯一性的标识符,必须持久稳定有效,这时候要用到无头服务,它可以给每个Pod一个唯一的名称。

1.5、为什么需要volumeClaimTemplate

  • 对于有状态的副本集都会用到持久存储,对于分布式系统来讲,它的最大特点是数据的不一样的,所以各个节点不能使用同一存储卷,每个节点有自己的专用存储,但是如果在Deployment中的Pod template里定义存储卷,是所有副本共有一个存储卷,数据是相同的,因为是基于模板来创建的,而StatefulSet中每个Pod都要自己的专有存储卷,所以StatefulSet的存储卷就不能再用Pod模板来创建了,于是StatefulSet使用volumeClaimTemplate,称为卷申请模板,它会为每个Pod生成不同的pvc,并绑定pv,从而实现各pod有专用存储。这就是为什么要用volumeClaminTemplate的原因。

二、教程

  • 开始之前确保你已经正常部署Kubernetes集群

StatefulSet_38">2.1、创建StatefulSet

  • 作为开始,使用如下示例创建了一个StatefulSet(以及它所依赖的Service)。它和StatefulSet概念中的示例相似。它创建了一个Headless Servicenginx用来发布StatefulSetweb中的Pod的IP地址。
[root@master ~]# vim nginx-statefulset.yaml
apiVersion: "v1"
kind: Service
metadata:name: nginxlabels:app: nginx
spec:ports:- port: 80name: webclusterIP: None # Service的类型设置为None将标识这是个Headless Service即无头服务selector: app: nginx  # 表示这个Service关联的Pod,将会选择标签带有app=nginx的Pod---apiVersion: "apps/v1"
kind: StatefulSet
metadata:name: web
spec:serviceName: "nginx"  # 声明它属于哪个Headless Service无头服务replicas: 2selector:matchLabels:app: nginx  # 这个StatefulSet将会管理标签是app=nginx的Podtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:latestimagePullPolicy: IfNotPresent# 定义挂载卷,这只是一个演示,生产环境一定不会这样用的volumeMounts:- name: wwwmountPath: /usr/share/nginx/htmlvolumes:- name: wwwhostPath:# 每个运行Pod的宿主机挂载容器中的目录路径path: /mnt
# 使用此命令加载资源
[root@master ~]# kubectl apply -f nginx-statefulset.yaml

2.2、查看部署资源

  • StatefulSet默认以严格的顺序创建其Pod。
  • 对于一个拥有n个副本的StatefulSet,Pod被部署时是按照{0…n-1}的序号顺序创建的
  • 请注意,直到web-0Pod处于RunningReady状态后,web-1Pod才会被启动。
# 查看Pod
[root@master ~]# kubectl get pod -l app=nginx
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          2m50s
web-1   1/1     Running   0          2m48s
# 查看StatefulSet
[root@master ~]# kubectl get statefulset web
NAME   READY   AGE
web    2/2     2m6s
# 查看Service无头服务
[root@master ~]# kubectl get service nginx
NAME    TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
nginx   ClusterIP   None         <none>        80/TCP    3m29s

StatefulSetPod_123">三、StatefulSet中的Pod

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

3.1、检查Pod的顺序索引

  • 如果StatefulSet盖尼奥中所提到的,StatefulSet中的每个Pod拥有一个具有黏性的、独一无二的身份标志,这个标志基于StatefulSet控制器分配给每个Pod的唯一顺序索引。Pod名称的格式为<statefulset 名称>-<序号索引>WebStatefulSet拥有两个副本,所以它创建了两个Pod:web-0web-1
[root@master ~]# kubectl get pod -l app=nginx
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          10m
web-1   1/1     Running   0          10m

3.2、使用稳定的网络身份标识

  • 每个Pod都拥有一个基于顺序索引的稳定的主机名。使用kubectl exex在每个Pod中执行hostname
[root@master ~]# for i in 0 1; do kubectl exec "web-$i" -- sh -c 'hostname'; done
web-0
web-1

3.3、查看主机明内部DNS地址

  • 使用kubectl run运行一个提供nslookup命令的容器,该命令来自于dnsutils包。通过对Pod的主机名执行nslookup,你可以检查这些主机名在集群内部的DNS地址
# 命令终端中运行一个Pod终端
[root@master ~]# kubectl run -i --tty --image busybox:1.28 dns-test --restart=Never --rm# 使用以下命令解析web-0Pod的内部DNS地址
/ # nslookup web-0.nginx
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.localName:      web-0.nginx
Address 1: 10.244.1.2 web-0.nginx.default.svc.cluster.local

StatefulSet_166">四、扩容/缩容StatefulSet

  • 扩容/缩容StatefulSet指增加或减少它的副本数。这通过更新replicas字段完成(水平缩放)。你也可以使用kubectl sacale或者kubectl pathch来缩容/缩容一个StatefulSet

4.1、扩容

  • 扩容意味着添加更多副本。如果你的应用程序能够在整个StatefulSet范围内分派工作,则新的更大的Pod及可以执行更多的工作。

  • StatefulSet控制器扩展了副本的数量。如同创建StatefulSet所述,StatefulSet按序号索引扩容各个Pod,并且会等待前一个Pod变为Running和Ready才会启动下一个Pod。

# 将Pod容扩容为5个
[root@master ~]# kubectl scale statefulset web --replicas=5
# 可以提前执行效果更加明显
# 可以看出,前一个Pod创建完成并且成功运行之后才会去创建下一个Pod,而且创建Pod顺序也有要求,仔细观察可以看出顺序是由低到高。
[root@master ~]# kubectl get pod -l app=nginx --watch
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          27m
web-1   1/1     Running   0          26m
web-2   0/1     Pending   0          0s
web-2   0/1     Pending   0          0s
web-2   0/1     ContainerCreating   0          0s
web-2   1/1     Running             0          2s
web-3   0/1     Pending             0          0s
web-3   0/1     Pending             0          0s
web-3   0/1     ContainerCreating   0          0s
web-3   1/1     Running             0          1s
web-4   0/1     Pending             0          0s
web-4   0/1     Pending             0          0s
web-4   0/1     ContainerCreating   0          0s
web-4   1/1     Running             0          1s
[root@master ~]# kubectl get pod
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          27m
web-1   1/1     Running   0          27m
web-2   1/1     Running   0          22s
web-3   1/1     Running   0          20s
web-4   1/1     Running   0          19s

4.2、缩容

  • 缩容意味着减少副本数量。例如,你可能因为服务的流量水平已降低并且在当前规模下存在空闲资源的原因执行缩容操作。
# 将Pod缩容为3个
[root@master ~]# kubectl patch sts web -p '{"spec":{"replicas":3}}'
# 缩容的同时可以看出,一共5个Pod,缩容为3个之后,是由从高到底的顺序去缩容的
[root@master ~]# kubectl get pod -l app=nginx --watch
web-4   1/1     Terminating         0          3m43s
web-4   0/1     Terminating         0          3m44s
web-4   0/1     Terminating         0          3m44s
web-4   0/1     Terminating         0          3m44s
web-3   1/1     Terminating         0          3m45s
web-3   0/1     Terminating         0          3m46s
web-3   0/1     Terminating         0          3m46s
web-3   0/1     Terminating         0          3m46s

StatefulSet_234">五、更新StatefulSet

  • StatefulSet控制器支持自动更新。更新策略由StatefulSet API对象的spec.updateStrategy字段决定。这个特性能够用更新一个StatefulSet中Pod的容器镜像、资源请求和限制、标签和注解。
  • 有两个有效的更新策略:RollingUpdate(默认)OnDelete

5.1、滚动更新

  • RollingUpdate更新策略会更新一个StatefulSet中的所有Pod,采用与序号索引相反的顺序并遵循StatefulSet的保证
  • StatefulSet里的Pod采用和序号相反的顺序更新。在更新下一个Pod前,StatefulSet控制器终止每个Pod并等待它们变成Running和Ready。请注意,虽然在顺序后继者变成Running和Ready之前StatefulSet控制器不会更新下一个Pod
# 执行patch操作再次该表容器镜像
[root@master ~]# kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"registry.k8s.io/nginx:1.20"}]'
# 查看滚动更新状态
[root@master ~]# kubectl rollout status statefulset web
partitioned roll out complete: 3 new pods have been updated...
# 查看pod状态
[root@master ~]# kubectl get pod -l app=nginx 
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          64s
web-1   1/1     Running   0          66s
web-2   1/1     Running   0          9m17s
# 查看滚动更新后的Nginx版本
[root@master ~]# for p in 0 1 2; do kubectl get pod "web-$p" --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done
registry.k8s.io/nginx:1.20
registry.k8s.io/nginx:1.20
registry.k8s.io/nginx:1.20

http://www.ppmy.cn/embedded/92705.html

相关文章

QT界面设计开发(Visual Studio 2019)—学习记录一

一、控件升级 简要介绍&#xff1a; 简单来说&#xff0c;控件提升就是将一个基础控件&#xff08;Base Widget&#xff09;转换为一个更特定、更复杂的自定义控件&#xff08;Custom Widget&#xff09;。这样做的目的是为了在设计界面时能够使用更多高级功能&#xff0c;而不…

Python学习(2):在单机机器学习,使用Dask实现鸢尾数据集 Iris 的分类任务

目录 一、源码来源 二、鸢尾花数据集的品种分类 1、数据处理步骤 &#xff08;1&#xff09;数据集加载 &#xff08;2&#xff09;准备特征和标签 &#xff08;3&#xff09;训练集和测试集划分 2、安装必需的软件包 3、运行程序 三、信用卡欺诈数据集检测信用卡交易…

CPU 流水线技术初识

在当今数字化的时代&#xff0c;计算机已经成为我们生活中不可或缺的一部分。而在计算机的核心部位&#xff0c;中央处理器&#xff08;CPU&#xff09;则是其重要的组成部分。CPU 的性能决定了计算机的运行速度和处理能力&#xff0c;而流水线技术则是 CPU 性能提升的关键所在…

FPGA开发——IP核的介绍

一、简介 在我们在使用FPGA进行相关开发&#xff0c;设计涉及到复杂的开发时往往需要编写大量的代码对于想要实现的功能进行一个实现&#xff0c;这不仅增加了我们的工作量&#xff0c;往往还会增加开发难度。今天我们就来引入在FPGA开发中IP核的相关概念。 在FPGA&#xff08…

gdb上手简述

文章目录 1. gdb通用命令1.1 常用命令1.2 查看内存1.3 屏蔽信号 2. gdb跟踪调试2.1 debug版本2.2 gdb多线程调试 3. gdb内存监控3.1 watch3.2 mprotect内存保护3.3 perf_event数据断点API进行内存保护 4. 调试技巧4.1 gdb不阻塞进程运行4.2 查看传参、返回值 1. gdb通用命令 1…

【Android面试八股文】荣耀面试算法题:输出所有的水仙花数

文章目录 一、水仙花数的定义二、算法实现 一、水仙花数的定义 要输出所有的水仙花数&#xff0c;我们需要先了解什么是水仙花数。 水仙花数&#xff08;Narcissistic number&#xff09;&#xff0c;也称为自恋数、自幂数、阿姆斯特朗数&#xff0c;是指一个 n 位的正整数&a…

Qt中SQLite数据库的使用

一、安装SQLite 在Qt6中&#xff0c;不再支持 SQLite2&#xff0c;只支持 SQLite3 。因此&#xff0c;有两种方式使用 SQLite&#xff0c;一种是在 SQLite 官网安装 SQLite3&#xff0c;另外一种是直接安装 SQLite Expert。 SQLite Expert 内置了 SQLite。这意味着用户在安装 S…

未来已来:人工智能如何重塑Facebook的用户体验?

在数字化时代的浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;正成为推动技术进步和用户体验优化的核心力量。Facebook&#xff08;现Meta Platforms&#xff09;作为全球领先的社交媒体平台&#xff0c;正在充分利用人工智能技术&#xff0c;以重塑用户体验&#xff0…