【云原生】StatefulSet控制器详解
StatefulSet
文章目录
- StatefulSet
- 一、介绍与特点
- 1.1、介绍
- 1.2、特点
- 1.3、组成部分
- 1.4、为什么需要无头服务
- 1.5、为什么需要volumeClaimTemplate
- 二、教程
- 2.1、创建StatefulSet
- 2.2、查看部署资源
- 三、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集群
2.1、创建StatefulSet
- 作为开始,使用如下示例创建了一个StatefulSet(以及它所依赖的Service)。它和StatefulSet概念中的示例相似。它创建了一个Headless Service
nginx用来发布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处于Running并Ready状态后,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
三、StatefulSet中的Pod
- StatefulSet中的每个Pod拥有一个唯一的顺序索引和稳定的网络身份标识。
3.1、检查Pod的顺序索引
- 如果StatefulSet盖尼奥中所提到的,StatefulSet中的每个Pod拥有一个具有黏性的、独一无二的身份标志,这个标志基于StatefulSet控制器分配给每个Pod的唯一顺序索引。Pod名称的格式为
<statefulset 名称>-<序号索引>。WebStatefulSet拥有两个副本,所以它创建了两个Pod:web-0和web-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
- 扩容/缩容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
- 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
相关文章:
【云原生】StatefulSet控制器详解
StatefulSet 文章目录 StatefulSet一、介绍与特点1.1、介绍1.2、特点1.3、组成部分1.4、为什么需要无头服务1.5、为什么需要volumeClaimTemplate 二、教程2.1、创建StatefulSet2.2、查看部署资源 三、StatefulSet中的Pod3.1、检查Pod的顺序索引3.2、使用稳定的网络身份标识3.3、…...
使用 Python 制作一个属于自己的 AI 搜索引擎
1. 使用到技术 OpenAI KEYSerper KEYBing Search 2. 原理解析 使用Google和Bing的搜搜结果交由OpenAI处理并给出回答。 3. 代码实现 import requests from lxml import etree import os from openai import OpenAI# 从环境变量中加载 API 密钥 os.environ["OPENAI_AP…...
rust读取csv文件,匹配搜索字符
1.代码 use std::fs::File; use std::io::{BufRead, BufReader}; use regex::{Regex};fn main() {let f File::open("F:\\0-X-RUST\\1-systematic\\ch2-fileRead\\data\\test.csv").unwrap();let mut reader BufReader::new(f);let re Regex::new("45asd&qu…...
隐藏采购订单类型
文章目录 1 Introduction2 code 1 Introduction The passage is that how to hiden purchase type . 2 code DATA: ls_shlp_selopt TYPE ddshselopt. IF ( sy-tcode ME21N OR sy-tcode ME22N OR sy-tcode ME23N or sy-tcode ME51N OR sy-tcode ME52N OR sy-tcode ME5…...
ESP32人脸识别开发- 基础介绍(一)
一、ESP32人脸识别的方案介绍 目前ESP32和ESP32S3都是支持的,官方推的开发板有两种,一种 ESP-EYE ,没有LCD 另一种是ESP32S3-EYE,有带LCD屏 二、ESP32人脸识别选用ESP32的优势 ESP32S3带AI 加速功能,在人脸识别的速度是比ESP32快了不少 | S…...
编程学习指南:语言选择、资源推荐与高效学习策略
目录 一、编程语言选择 1. Java:广泛应用的基石 2. C/C:深入底层的钥匙 3. Python:AI与大数据的宠儿 4. Web前端技术:构建交互界面的艺术 二、学习资源推荐 1. 国内外在线课程平台 2. 官方文档与教程 3. 书籍与电子书 4…...
AWS开发人工智能:如何基于云进行开发人工智能AI
随着人工智能技术的飞速发展,企业对高效、易用的AI服务需求日益增长。Amazon Bedrock是AWS推出的一项创新服务,旨在为企业提供一个简单、安全的平台,以访问和集成先进的基础模型。本文中九河云将详细介绍Amazon Bedrock的功能特点以及其收费方…...
CentOS 8 的 YUM 源替换为国内的镜像源
CentOS 8 的 YUM 源替换为国内的镜像源 1.修改 DNS 为 114.114.114.1141.编辑 /etc/resolv.conf 文件:2.在文件中添加或修改如下内容:3.保存并退出编辑器。 2.修改 YUM 源为国内镜像1.备份原有的 YUM 源配置:2.下载新的 YUM 源配置3.清理缓存…...
网络安全入门教程(非常详细)从零基础入门到精通_网路安全 教程
前言 1.入行网络安全这是一条坚持的道路,三分钟的热情可以放弃往下看了。2.多练多想,不要离开了教程什么都不会了,最好看完教程自己独立完成技术方面的开发。3.有时多百度,我们往往都遇不到好心的大神,谁会无聊天天给…...
浅学爬虫-爬虫维护与优化
在实际项目中,爬虫的稳定性和效率至关重要。通过错误处理与重试机制、定时任务以及性能优化,可以确保爬虫的高效稳定运行。下面我们详细介绍这些方面的技巧和方法。 错误处理与重试机制 在爬虫运行过程中,网络不稳定、目标网站变化等因素可…...
STM32G070系列芯片擦除、写入Flash错误解决
在用G070KBT6芯片调用HAL_FLASHEx_Erase(&EraseInitStruct, &PageError)时,调试发现该函数返回HAL_ERROR,最后定位到FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE)函数出现错误,pFlash.ErrorCode为0xA0,即FLASH错误标…...
08.02_111期_Linux_NAT技术
NAT(network address translation)技术说明 IP报文在转发的时候需要考虑 源IP地址 和 目的IP地址, IP报文每到达一个节点,就会更改一次IP地址和目的IP地址,其中节点是指主机、服务器、路由器 那么这个更改是如何进行的呢? 除了…...
【2024蓝桥杯/C++/B组/小球反弹】
题目 分析 Sx 2 * k1 * x; Sy 2 * k2 * y; (其中k1, k2为整数) Vx * t Sx; Vy * t Sy; k1 / k2 (15 * y) / (17 * x); 目标1:根据k1与k2的关系,找出一组最小整数组(k1, k2)ÿ…...
PHP中如何实现函数的可变参数列表
在PHP中,实现函数的可变参数列表主要有两种方式:使用func_get_args()函数和使用可变数量的参数(通过...操作符,自PHP 5.6.0起引入)。 1. 使用func_get_args()函数 func_get_args()函数用于获取传递给函数的参数列表&…...
串---链串实现
链串详解 本文档将详细介绍链串的基本概念、实现原理及其在 C 语言中的具体应用。通过本指南,读者将了解如何使用链串进行各种字符串操作。 1. 什么是链串? 链串是一种用于存储字符串的数据结构,它使用一组动态分配的节点来保存字符串中的…...
科技赋能生活——便携气象站
传统气象站往往庞大而复杂,需要专业人员维护,它小巧玲珑,设计精致,可以轻松放入背包或口袋,随身携带,不占空间。无论是城市白领穿梭于高楼大厦间,还是户外爱好者深入山林湖海,都能随…...
Golang——GC原理
1.垃圾回收的目的 将未被引用到的对象销毁,回收其所占的内存空间。 2.根对象是什么 全局变量:在编译器就能确定的存在于程序整个生命周期的变量。 执行栈:每个goroutine都包含自己的执行栈,这些执行栈上包含栈上的变量及指向分配…...
OpenStack概述
一、初识OpenStack OpenStack Docs: 概况 一)OpenStack架构简述 1、理解OpenStack OpenStack既是一个社区,也是一个项目和一个开源软件,提供开放源码软件,建立公共和私有云,它提供了一个部署云的操作平台或工具集&…...
机器学习练手(三):基于决策树的iris 多分类和波士顿房价预测
总结:本文为和鲸python 可视化探索训练营资料整理而来,加入了自己的理解(by GPT4o) 原活动链接 原作者:vgbhfive,多年风控引擎研发及金融模型开发经验,现任某公司风控研发工程师,对…...
PS 2024 百种常用插件下载安装教程【免费使用,先到先得】
文章目录 软件介绍软件下载安装步骤 专栏推荐: 超多精品软件(持续更新中…) 软件推荐: PS 2024 PR 2024 软件介绍 PS常用插件 此软件整合了市面近百款ps处理插件,可实现:一键制作背景,一键抠图…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
结构化文件管理实战:实现目录自动创建与归类
手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题,进而引发后续程序异常。使用工具进行标准化操作,能有效降低出错概率。 需要快速整理大量文件的技术用户而言,这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB,…...
