当前位置: 首页 > news >正文

Kubernetes技术与架构-10

1     前言

2     Kubernetes定义

3     Kubernetes架构

4     Kubernetes技术

4.1   容器化技术

4.1.1 cgroups技术

4.1.2 Docker容器运行环境

4.1.3 containerd容器运行环境

4.1.4 Pod的基本概念

4.1.5 Pod的调度策略

4.1.6 Pod的资源编排

4.1.6.1Deployments

4.1.6.2ReplicaSet

4.1.6.3StatefulSets

StatefulSet是指带有状态的Pod集合,用于运行带有状态的应用集合,其使用与Deployment相同的方式扩展Pod的集群规模,运行在StatefulSet中的Pod具有固定的顺序以及固定的身份标识器,这些Pod的属性不会因为Pod资源的重新调度而发生变化。

StatefulSet简要描述

与Deployment相同的是StatefulSet使用相同的容器规范管理Pod,与Deployment不同的是StatefulSet对每个Pod维护一个严格的、唯一的身份标识(ID),也就是,它们创建Pod的规范或者方式相同,但是它们管理Pod的方式有区别。StatefulSet创建的Pod是不可变的,每个Pod都具备一个持久化的身份标识器,在任何情况下,控制器重新调度Pod资源的时候,该身份标识(ID)都不会发生变化。

在实际的应用场景中,如果用户的应用需求是依赖数据持久化存储空间,则可以使用StatefulSet编排资源。当集群系统发生异常,需要重新调度StatefulSet中Pod资源的时候,控制器会根据旧Pod的属性自动绑定旧Pod的存储空间到新创建的Pod中。

StatefulSet适用场景

StatefulSet适用于具有以下性质的应用:

  • 固定的,唯一的网络标识器

  • 固定的,持久化的存储空间

  • 有序的,平滑地部署与扩展

  • 有序的,自动化地滚动更新

即使控制器因为重新调度,而重新创建新的Pod,持久化层的存储空间或者网络空间也是固定不变的,新创建的Pod会自动绑定旧Pod的持久化层的资源。如果用户的应用不需要依赖于持久化层的资源以及有序的部署、删除、扩展,则可以使用无状态的Pod,无状态的Pod可以使用Deployment或者ReplicaSet实现。

StatefulSet使用限制

  • Pod的存储空间由持久化存储空间提供商提供、由kubernetes集群管理员预先配置

  • 删除一个StatefulSet或者收缩其集群规模的时候,不会删除这些Pod依赖的持久化层的存储空间,这种机制可以保证用户数据或者系统数据的安全

  • 需要用户自行创建Headless类型的service,用于绑定StatefulSet中Pod作为网络标识

  • 当StatefulSet被删除,需要用户自行终止其中的Pod,建议用户先收缩集群规模数量等于0再删除对应的Pod

  • 在滚动更新集群副本时,可以手工修复Pod的状态

StatefulSet相关组件

如上图所示定义一个StatefulSet类型的Pod描述文件:

  • nginx是用户自行定义的Headless类型service,用于指定nginx的网络标识

  • 定义一个命名为web的StatefulSet,包括3个nginx容器镜像的副本,每个Pod对应一个持久化的唯一性ID

  • 定义一个命名为www的volumeClaimTemplates存储空间

Pod选择器

域.spec.selector配置的标签,必须符合域.spec.template.metadata.labels配置的标签,例如,nginx。

定义存储空间模板

使用.spec.volumeClaimTemplates配置指定持久化存储空间提供商的存储空间类型。

最小化准备时间

配置域.spec.minReadySeconds用于创建完成一个新Pod时,还需要多长时间才认为Pod是可用的,单位:秒。当用户使用滚动更新策略时,控制器使用该配置值检查更新的进度,默认值是0,也就是,一旦Pod创建完,即被认为是可用的。

Pod的身份标识(ID)

StatefulSet中的Pod具备一个唯一性的身份标识,是由一个序数、固定的网络标识(ID)、固定的存储空间标识组成,该标识与Pod绑定,保持固定不变,在任何节点上调度都不会发生变化。

序数索引

对于一个给定的StatefulSet,其中包括N个副本,则序数从0到N-1赋予每个Pod,因此该序数在相同的StatefulSet内是唯一的。

固定的网络标识(ID)

在kubernetes集群中,每个Pod对应一个主机名称(hostname),同样,StatefulSet中每个Pod对应的主机名称是根据StatefulSet的名称而定,其命名规则是$(statefulset name)-$(ordinal),例如,上图定义Pod的名称分别是web-0、web-1、web-2。因为每个StatefulSet绑定headless服务,其服务域名的命名规则是$(service name).$(namespace).svc.cluster.local,其中,cluster.local是kubernetes集群的域名,每个Pod对应的子域名的命名规则是$(pondage).$(governing service domain):

在kubernetes集群中Pod提供的服务是以DNS的方式访问,而由于DNS的缓存问题以及DNS的生效时间延迟问题,刚创建的Pod需要等待一段时间(几十秒)才能使用域名正常访问到。用户可以使用如下的方式实现快速访问刚创建的Pod:

  • 使用kubernetes的API直接访问,而不是使用域名

  • 降低DNS缓存的持续时间,例如,CoreDNS的默认缓存时间是30秒

固定的存储空间标识

在StatefulSet的域VolumeClaimTemplate中定义存储空间,用户可以定义指定的存储空间类型。例如,在前面的例子中,定义存储空间类型是my-storage-class以及存储空间的容量大小是1Gib,如果用户没有指定存储空间类型,则系统默认的类型。在一个新的Pod在新的节点中创建,新创建的Pod会挂载旧的存储空间,当StatefulSet或者其中的Pod被删除,其绑定的存储空间不会被删除,需要用户手动删除。

Pod的名称标签

每个新创建Pod的名称标签的形式如:statefulset.kubernetes.io/pod-name,该标签可以用于为StatefulSet中的Pod绑定一个服务。

部署与扩缩容

StatefulSet控制器提供以下有关集群副本的部署与扩缩容的保证:

  • 假设StatefulSet包括N个集群副本,则这些Pod副本的部署顺序是从0到N-1

  • 如果以上这些Pod副本被删除,则删除的顺序刚好与创建的顺序相反,是从N-1到0

  • 对于Pod创建的操作顺序,每一次操作都必须在前一次Pod操作已经准备就绪,才能继续执行

  • 对于Pod终止的操作顺序,每次操作都必须在前面所有Pod都已经被成功终止,才能继续执行

根据以上规则,Pod的启动顺序是web-0、web-1、web-2,web-1在web-0完成后启动,web-2在web-1完成后启动,如果web-1完成启动后,web-0发生故障,则web-2在web-0恢复之前不会启动。假如,用户修改集群副本数由3变化为1,web-2先被终止,web-1在web-2完成终止后终止,web-0在web-1完成终止后终止,如果web-2完成终止后,web-0先于web-1完成终止前发生故障,则web-1在web-0恢复之前不会终止。

Pod的管理策略

用户可以使用.spec.podManagementPolicy域设置更加宽松的扩缩容策略,如下所示:

OrderedReady

该配置值是严格按照指定顺序的扩缩容策略(如前面所述) 

Parallel

该配置值使用并行的、不按照指定顺序的扩缩容策略(不需要依赖于其他Pod的启动状态),该设置只对扩缩容的策略有效,而对更新策略无效 

更新策略

用户可以使用.spec.updateStrategy域设置部署发布时的更新策略(Pod的更新内容包括容器镜像版本、标签属性、资源需求或者限制、注解),如下所示:

OnDelete

该设置值指定StatefulSet控制器不使用自动部署发布的更新方式,也就是,需要用户先手工删除旧的在运行的Pod实例,从而触发Pod新版本(模板更新)的创建与更新

RollingUpdate

该设置值指定StatefulSet控制器使用自动部署发布的更新方式,以滚动发布的方式更新Pod新版本

滚动更新

用户如果设置.spec.updateStrategy.type等于RollingUpdate,则StatefulSet控制器先删除已经存在的旧Pod,再重新创建新Pod替代旧Pod。其终止与更新的顺序是使用前面所述的序数索引的顺序,也就是,从序数索引大的Pod向序数索引小的Pod的方向操作,一次只更新一个Pod,控制器会等待当前的Pod更新完成后再更新下一个Pod,配置域.spec.minReadySeconds设置值是用于当前的Pod更新完成后再等待的持续时间才执行下一次的更新操作。

分区滚动更新

在RollingUpdate滚动更新的策略下,如果用户使用如下所示的设置域,指定序数索引的最小值,StatefulSet控制器只更新大于等于该序数索引的Pod:

.spec.updateStrategy.rollingUpdate.partition

小于该序数索引的Pod不会被更新,小于该序数索引的Pod即使被删除,控制器重新创建新Pod时也只使用旧版本的Pod。假如设置域的值大于副本数,则控制器不会执行任何更新的操作。该更新策略可以指定更新发布一部分的Pod,因此,适用于灰度发布、以及引流测试发布的使用场景。

最大不可用Pod数

在更新发布的过程中,用户可以使用如下所示的设置域,指定最大不可用的Pod数,该值支持整数值或者百分比,也就是,StatefulSet控制器在更新发布时,需要先终止已经运行的Pod,再创建新的Pod,这个数值对应的是最大终止Pod的数量,默认值是1:

.spec.updateStrategy.rollingUpdate.maxUnavailable

假设集群副本数是N,则该值的有效范围是从0到N-1,在StatefulSet中任何不可用的Pod都包括在该值中。

强制性回滚

在部署更新发布的过程中,如果出现异常的情况,则更新过程被终止,需要人工修复或者恢复对应的配置文件、配置域,其他已经涉及到不正确配置域的Pod也需要人工终止,人工修复完成,StatefulSet控制器继续执行更新发布的过程。

存储空间保持策略

PersistentVolumeClaim(PVC)配置域对应的规则如下所示:

.spec.persistentVolumeClaimRetentionPolicy

该配置域是可选项,用于设置在StatefulSet的生命周期内对应的存储空间(PVCs)的删除策略,在配置域StatefulSetAutoDeletePVC开启之后生效,该配置域一旦被开启,则用户可以同时指定如下两种删除规则

whenDeleted

当StatefulSet被删除,配置存储空间的处理规则

whenScaled

当StatefulSet中的Pod副本数降低,配置存储空间的处理规则

当以上设置生效,则设置如下存储空间的处理规则

Delete

当whenDeleted生效,则删除所有Pod对应的存储空间,当whenScaled生效,则删除被删除Pod副本的存储空间

Retain

这是默认值,当StatefulSet被删除或者Pod副本被删除,对应的存储空间不受影响,也就是,对应的存储空间不会被删除

以上的规则只对部署更新发布时,StatefulSet被删除或者StatefulSet中的集群副本规模收缩的时候才生效。如果因为集群节点发生异常,而引起Pod部署失败,则控制器不会删除Pod对应的存储空间,此时,控制器会在新的节点中挂载对应的存储空间,并且绑定到新建的Pod。

在whenDeleted设置域等于Delete值时,StatefulSet控制器创建Pod成功后,为Pod对应的存储空间设置属主的引用关系,当Pod被终止,则这些属主的引用关系也被删除,在存储空间被删除之前,控制器会卸载Pod中的存储空间。

在whenScaled设置域等于Delete值时,控制器只删除集群副本数收缩情况下被终止的Pod的存储空间,而不会删除其他异常情况下被终止的Pod的存储空间。在异常情况被修复之后,控制器会检测配置域中的集群副本数与实际环境kubernetes集群中的Pod实例数,任何Pod的ID大于集群副本数的都将被终止、与之对应的存储空间也最终被删除。

假如在以上属主关系设置成功之前,控制器发生异常而重启,则控制器不会处理这些Pod,在这种使用场景下,建议用户等待控制器的自动恢复处理或者手工检查Pod与存储空间的引用关系再手工恢复。

集群副本数

配置域.spec.replicas是可选项,指定集群副本数,默认值是1。用户可以使用命令行控制台执行以下命令行动态设置集群副本数:

kubectl scale statefulset

statefulset

--replicas=X

用户也可以使用配置文件执行如下命令行,覆盖旧的配置文件:

kubectl apply -f

statefulset.yaml

如果用户使用HorizontalPodAutoscaler水平扩展器,则不需要设置该值,由控制器自动化地管理集群副本数。

(未完待续)

相关文章:

  • 基于微信小程序云开(统计学生信息并导出excel)3.0版
  • 【JAVAEE框架】浅谈 AOP 及代码实现
  • React获取DOM和获取组件实例的方式
  • [Spark、hadoop]spark Streaming的核心DStream
  • 【Vue】父子组件通信
  • API接口开发其实特简单,Python Flask Web 框架教程来了
  • SpringMVC03之拦截器和JSR303
  • 索引失效案例
  • 机器学习笔记 - Albumentations库实现的图像增强功能一览
  • 软考-存储系统
  • 大学生网页设计制作作业实例代码 (全网最全,建议收藏) HTML+CSS+JS
  • GAN Step By Step -- Step4 CGAN
  • HackerRank 算法刷题笔记(一),基于Go语言
  • 【Linux篇】第十三篇——信号(概念+信号的产生+阻塞信号+捕捉信号)
  • Android Jetpack系列之MVI架构
  • JAVA_NIO系列——Channel和Buffer详解
  • JavaScript实现分页效果
  • Java知识点总结(JavaIO-打印流)
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • Phpstorm怎样批量删除空行?
  • Spring技术内幕笔记(2):Spring MVC 与 Web
  • 对超线程几个不同角度的解释
  • 给Prometheus造假数据的方法
  • 猴子数据域名防封接口降低小说被封的风险
  • 解决iview多表头动态更改列元素发生的错误
  • 快速构建spring-cloud+sleuth+rabbit+ zipkin+es+kibana+grafana日志跟踪平台
  • 一个JAVA程序员成长之路分享
  • 译有关态射的一切
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • 大数据全解:定义、价值及挑战
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • (03)光刻——半导体电路的绘制
  • (C++20) consteval立即函数
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (论文阅读30/100)Convolutional Pose Machines
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (学习日记)2024.02.29:UCOSIII第二节
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • ******之网络***——物理***
  • .Net 8.0 新的变化
  • .NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式
  • .NET(C#、VB)APP开发——Smobiler平台控件介绍:Bluetooth组件
  • .NET/C# 获取一个正在运行的进程的命令行参数
  • .NET6使用MiniExcel根据数据源横向导出头部标题及数据
  • .Net7 环境安装配置
  • .NET中GET与SET的用法
  • /bin/bash^M: bad interpreter: No such file or directory
  • @Resource和@Autowired的区别
  • [ACM] hdu 1201 18岁生日
  • [AutoSar]工程中的cpuload陷阱(三)测试
  • [BZOJ 1040] 骑士
  • [caffe(二)]Python加载训练caffe模型并进行测试1
  • [C和指针].(美)Kenneth.A.Reek(ED2000.COM)pdf
  • [FROM COM张]如何解决Nios II SBTE中出现的undefined reference to `xxx'警告
  • [Hadoop in China 2011] Hadoop之上 中国移动“大云”系统解析