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

K8S - 实现statefulset 有状态service的灰度发布

什么是灰度发布 Canary Release

在这里插入图片描述

参考
理解 什么是 滚动更新,蓝绿部署,灰度发布 以及它们的区别




配置partition in updateStrategy/rollingUpdate

这次我为修改了 statefulset 的1个yaml file
statefulsets/stateful-nginx-without-pvc.yaml:

---
apiVersion: v1 # api version
kind: Service # type of this resource e.g. Pod/Deployment ..
metadata:name: nginx-stateful-service # name of the servicelabels:app: nginx-stateful-service
spec:ports: - port: 80 # port of the service, used to access the servicename: web-portclusterIP: None # the service is not exposed outside the clusterselector: # label of the Pod that the Service is selectingapp: nginx-stateful # only service selector could skip the matchLabels:
---apiVersion: apps/v1
kind: StatefulSet # it's for a stateful application, it's a controller
metadata:name: nginx-statefulset # name of the statefulsetlabels:app: nginx-stateful
spec: # detail descriptionserviceName: "nginx-stateful-service" # name of the service that used to manange the dns,  # must be the same as the service name defined abovereplicas: 3 # desired replica countselector: # label of the Pod that the StatefulSet is managingmatchLabels:app: nginx-statefultemplate: # Pod templatemetadata:labels:app: nginx-statefulspec:containers:- name: nginx-containeimage: nginx:1.25.4 # image of the containerports: # the ports of the container and they will be exposed- containerPort: 80 # the port used by the container servicename: web-portupdateStrategy:rollingUpdate:partition: 2type: RollingUpdate

关键是最后1个block

  updateStrategy:rollingUpdate:partition: 2type: RollingUpdate

rollingUpdate 很容易理解, 关键是partition 的值

这个值表示在image 版本更新后, 只会更新 pod-index 中index >= partition 的POD, 其他POD保持先版本, 这就能同时让两个版本存在一段时间, 实现灰度发布




一个例子

首先我们先apply 上面的yaml
[gateman@manjaro-x13 statefulsets]$ kubectl apply -f stateful-nginx-without-pvc.yaml 
service/nginx-stateful-service unchanged
statefulset.apps/nginx-statefulset created
检查pods , 3个pod 起来了分别是0, 1, 2
[gateman@manjaro-x13 statefulsets]$ kubectl get pods -o wide
NAME                  READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
nginx-statefulset-0   1/1     Running   0          12m   10.244.2.120   k8s-node0   <none>           <none>
nginx-statefulset-1   1/1     Running   0          12m   10.244.1.59    k8s-node1   <none>           <none>
nginx-statefulset-2   1/1     Running   0          12m   10.244.3.69    k8s-node3   <none>           <none>
为了更好的present, 我们把pods数量scale 到5个
[gateman@manjaro-x13 statefulsets]$ kubectl scale statefulset nginx-statefulset --replicas=5
statefulset.apps/nginx-statefulset scaled
[gateman@manjaro-x13 statefulsets]$ kubectl get pods -o wide
NAME                  READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
nginx-statefulset-0   1/1     Running   0          13m   10.244.2.120   k8s-node0   <none>           <none>
nginx-statefulset-1   1/1     Running   0          13m   10.244.1.59    k8s-node1   <none>           <none>
nginx-statefulset-2   1/1     Running   0          13m   10.244.3.69    k8s-node3   <none>           <none>
nginx-statefulset-3   1/1     Running   0          13s   10.244.2.121   k8s-node0   <none>           <none>
nginx-statefulset-4   1/1     Running   0          12s   10.244.3.70    k8s-node3   <none>           <none>

这时5个pod 起来了

查看每个pod的image 版本
[gateman@manjaro-x13 statefulsets]$ kubectl get pods -o=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}'
nginx-statefulset-0	nginx:1.25.4
nginx-statefulset-1	nginx:1.25.4
nginx-statefulset-2	nginx:1.25.4
nginx-statefulset-3	nginx:1.25.4
nginx-statefulset-4	nginx:1.25.4
这时我们更新image 版本从 1.25.4 更新到1.26.1
[gateman@manjaro-x13 statefulsets]$ kubectl set image statefulset/nginx-statefulset nginx-container=nginx:1.26.1
statefulset.apps/nginx-statefulset image updated
再次检查 每个pod 的image version
nginx-statefulset-0	nginx:1.25.4
nginx-statefulset-1	nginx:1.25.4
nginx-statefulset-2	nginx:1.26.1
nginx-statefulset-3	nginx:1.26.1
nginx-statefulset-4	nginx:1.26.1

可以见到只有pod 2 3 和4 更新了, 0, 1 还是旧版本

下一步, 把新版本应到pod 1 和 pod 0

也很简单, 只需要更改partition 的值就行

---
apiVersion: v1 # api version
kind: Service # type of this resource e.g. Pod/Deployment ..
metadata:name: nginx-stateful-service # name of the servicelabels:app: nginx-stateful-service
spec:ports: - port: 80 # port of the service, used to access the servicename: web-portclusterIP: None # the service is not exposed outside the clusterselector: # label of the Pod that the Service is selectingapp: nginx-stateful # only service selector could skip the matchLabels:
---apiVersion: apps/v1
kind: StatefulSet # it's for a stateful application, it's a controller
metadata:name: nginx-statefulset # name of the statefulsetlabels:app: nginx-stateful
spec: # detail descriptionserviceName: "nginx-stateful-service" # name of the service that used to manange the dns,  # must be the same as the service name defined abovereplicas: 5 # desired replica countselector: # label of the Pod that the StatefulSet is managingmatchLabels:app: nginx-statefultemplate: # Pod templatemetadata:labels:app: nginx-statefulspec:containers:- name: nginx-containerimage: nginx:1.26.1 # image of the containerports: # the ports of the container and they will be exposed- containerPort: 80 # the port used by the container servicename: web-portupdateStrategy:rollingUpdate:partition: 1type: RollingUpdate

记得修改3个地方, 1是
replicas: 5 改成当前的数量
image: nginx:1.26.1 要改成新的版本
partition: 1 改成1 就是意思把pod 1 也部署新版本

[gateman@manjaro-x13 statefulsets]$ kubectl replace -f stateful-nginx-without-pvc.yaml 
service/nginx-stateful-service replaced
statefulset.apps/nginx-statefulset replaced
[gateman@manjaro-x13 statefulsets]$ kubectl get pods -o=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}'
nginx-statefulset-0	nginx:1.25.4
nginx-statefulset-1	nginx:1.26.1
nginx-statefulset-2	nginx:1.26.1
nginx-statefulset-3	nginx:1.26.1
nginx-statefulset-4	nginx:1.26.1

这时只有pod0 还是旧版本

如何 把pod0 也同步?
方法1是用上面的方法重新更新partition 的值为0

方法2使用 kubectl patch 修改
kubectl patch statefulset nginx-statefulset --type=‘json’ -p=‘[{“op”: “replace”, “path”: “/spec/updateStrategy/rollingUpdate/partition”, “value”: 0}]’

[gateman@manjaro-x13 statefulsets]$ kubectl get pods -o=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}'
nginx-statefulset-0	nginx:1.26.1
nginx-statefulset-1	nginx:1.26.1
nginx-statefulset-2	nginx:1.26.1
nginx-statefulset-3	nginx:1.26.1
nginx-statefulset-4	nginx:1.26.1




Deployment 的灰度发布

如果是无状态service 的deployment , 可以用这种方法灰度发布吗?
不行
因为 deployment 的pods 的后续不是1个index 数字, 无序的, 所以无法去比较 pod 的index 和 partition的值

强行写上yaml 就会有如下错误:

[gateman@manjaro-x13 bq-api-service]$ kubectl apply -f bq-api-service-test.yaml 
error: error validating "bq-api-service-test.yaml": error validating data: ValidationError(Deployment.spec.strategy.rollingUpdate): unknown field "partition" in io.k8s.api.apps.v1.RollingUpdateDeployment; if you choose to ignore these errors, turn validation off with --validate=false

但是灰度发布只是1个思想, 实现的方法有很多种
deployment的灰度发布在k8s 是可行的, 例如简单粗暴地用多个deployment 去cover 不同的instance. 具体方法不在此讨论

相关文章:

K8S - 实现statefulset 有状态service的灰度发布

什么是灰度发布 Canary Release 参考 理解 什么是 滚动更新&#xff0c;蓝绿部署&#xff0c;灰度发布 以及它们的区别 配置partition in updateStrategy/rollingUpdate 这次我为修改了 statefulset 的1个yaml file statefulsets/stateful-nginx-without-pvc.yaml: --- apiVe…...

Qt 技术博客:深入理解 Qt 中的 delete 和 deleteLater 与信号槽机制

在 Qt 开发中&#xff0c;内存管理和对象生命周期的处理是至关重要的一环。特别是在涉及信号和槽机制时&#xff0c;如何正确删除对象会直接影响应用程序的稳定性。本文将详细讨论在使用 Qt 的信号和槽机制时&#xff0c;delete 和 deleteLater 的工作原理&#xff0c;并给出最…...

自学鸿蒙HarmonyOS的ArkTS语言<一>基本语法

一、一个ArkTs的目录结构 二、一个页面的结构 A、装饰器 Entry 装饰器 : 标记组件为入口组件&#xff0c;一个页面由多个自定义组件组成&#xff0c;但是只能有一个组件被标记 Component : 自定义组件, 仅能装饰struct关键字声明的数据结构 State&#xff1a;组件中的状态变量…...

【OpenGauss源码学习 —— (ALTER TABLE(列存修改列类型))】

ALTER TABLE&#xff08;列存修改列类型&#xff09; ATExecAlterColumnType 函数1. 检查和处理列存储表的字符集&#xff1a;2. 处理自动递增列的数据类型检查&#xff1a;3. 处理生成列的类型转换检查&#xff1a;4. 处理生成列的数据类型转换&#xff1a; build_column_defa…...

【大数据 复习】第7章 MapReduce(重中之重)

一、概念 1.MapReduce 设计就是“计算向数据靠拢”&#xff0c;而不是“数据向计算靠拢”&#xff0c;因为移动&#xff0c;数据需要大量的网络传输开销。 2.Hadoop MapReduce是分布式并行编程模型MapReduce的开源实现。 3.特点 &#xff08;1&#xff09;非共享式&#xff0c;…...

Zookeeper:节点

文章目录 一、节点类型二、监听器及节点删除三、创建节点四、监听节点变化五、判断节点是否存在 一、节点类型 持久&#xff08;Persistent&#xff09;&#xff1a;客户端和服务器端断开连接后&#xff0c;创建的节点不删除。 持久化目录节点&#xff1a;客户端与Zookeeper断…...

生产级别的 vue

生产级别的 vue 拆分组件的标识更好的组织你的目录如何解决 props-base 设计的问题transparent component &#xff08;透明组件&#xff09;可减缓上述问题provide 和 inject vue-meta 在路由中的使用如何确保用户导航到某个路由自己都重新渲染&#xff1f;测试最佳实践如何制…...

kafka(五)spring-kafka(1)集成方法

一、集成 1、pom依赖 <!--kafka--><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId></dependency><dependency><groupId>org.springframework.kafka</groupId><artif…...

Java中的设计模式深度解析

Java中的设计模式深度解析 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在软件开发领域&#xff0c;设计模式是一种被广泛应用的经验总结和解决方案&#x…...

鸿蒙 HarmonyOS NEXT星河版APP应用开发—上篇

一、鸿蒙开发环境搭建 DevEco Studio安装 下载 访问官网&#xff1a;https://developer.huawei.com/consumer/cn/deveco-studio/选择操作系统版本后并注册登录华为账号既可下载安装包 安装 建议&#xff1a;软件和依赖安装目录不要使用中文字符软件安装包下载完成后&#xff0…...

[FreeRTOS 基础知识] 互斥访问与回环队列 概念

文章目录 为什么需要互斥访问&#xff1f;使用队列实现互斥访问休眠和唤醒机制环形缓冲区 为什么需要互斥访问&#xff1f; 在裸机中&#xff0c;假设有两个函数&#xff08;func_A, func_B&#xff09;都要修改a的值&#xff08;a&#xff09;&#xff0c;那么将a定义为全局变…...

音视频的Buffer处理

最近在做安卓下UVC的一个案子。正好之前搞过ST方案的开机广告&#xff0c;这个也是我少数最后没搞成功的项目。当时也有点客观原因&#xff0c;当时ST要退出机顶盒市场&#xff0c;所以一切的支持都停了&#xff0c;当时啃他家播放器几十万行的代码&#xff0c;而且几乎没有文档…...

【总结】攻击 AI 模型的方法

数据投毒 污染训练数据 后门攻击 通过设计隐蔽的触发器&#xff0c;使得模型在正常测试时无异常&#xff0c;而面对触发器样本时被操纵输出。后门攻击可以看作是特殊的数据投毒&#xff0c;但是也可以通过修改模型参数来实现 对抗样本 只对输入做微小的改动&#xff0c;使模型…...

Linux配置中文环境

文章目录 前言中文语言包中文输入法中文字体 前言 在Linux系统中修改为中文环境&#xff0c;通常涉及以下几个步骤&#xff1a; 中文语言包 更新源列表&#xff1a; 更新系统的软件源列表和语言环境设置&#xff0c;确保可以安装所需的语言包。 sudo apt update sudo apt ins…...

深入解析 iOS 应用启动过程:main() 函数前的四大步骤

深入解析 iOS 应用启动过程&#xff1a;main() 函数前的四大步骤 背景描述&#xff1a;使用 Objective-C 开发的 iOS 或者 MacOS 应用 在开发 iOS 应用时&#xff0c;我们通常会关注 main() 函数及其之后的执行逻辑&#xff0c;但在 main() 函数之前&#xff0c;系统已经为我们…...

textarea标签改写为富文本框编辑器KindEditor

下载 - KindEditor - 在线HTML编辑器 KindEditor的简单使用-CSDN博客 一、 Maven需要的依赖&#xff1a; 如果依赖无法下载&#xff0c;可以多添加几个私服地址&#xff1a; 在Maven框架中加入镜像私服 <mirrors><!-- mirror| Specifies a repository mirror site to…...

高通安卓12-Input子系统

1.Input输入子系统架构 Input Driver(Input设备驱动层)->Input core(输入子系统核心层)->Event handler(事件处理层)->User space(用户空间) 2.getevent获取Input事件的用法 getevent 指令用于获取android系统中 input 输入事件&#xff0c;比如获取按键上报信息、获…...

HTML 事件

HTML 事件 HTML 事件是发生在 HTML 元素上的交互瞬间,它们可以由用户的行为(如点击、按键、鼠标移动等)或浏览器自身的行为(如页面加载完成、图片加载失败等)触发。在 HTML 和 JavaScript 的交互中,事件扮演着核心角色,允许开发者创建动态和响应式的网页。 常见的 HTM…...

Mysql 官方提供的公共测试数据集 Example Databases

数据集&#xff1a;GitHub - datacharmer/test_db: A sample MySQL database with an integrated test suite, used to test your applications and database servers 下载 test_db: https://github.com/datacharmer/test_db/releases/download/v1.0.7/test_db-1.0.7.tar.gz …...

Docker 下载与安装以及配置

安装yum工具 yum install -y yum-ulits配置yum源 阿里云源 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo安装Docker 17.03后为两个版本&#xff1a; 社区版&#xff08;Community Edition&#xff0c;缩写为 CE&#x…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

嵌入式学习笔记DAY33(网络编程——TCP)

一、网络架构 C/S &#xff08;client/server 客户端/服务器&#xff09;&#xff1a;由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序&#xff0c;负责提供用户界面和交互逻辑 &#xff0c;接收用户输入&#xff0c;向服务器发送请求&#xff0c;并展示服务…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...