Deployment Controller详解(上)

上一篇在《Kubectl 部署无状态应用》中介绍了如何使用 Deployment 部署五个 hello world 实例时,我们并没有详细探讨 Deployment Controller 的各项功能。因此,本文将深入介绍 Deployment Controller 的作用以及它能够完成的任务。

本文来自官方文档梳理:https://kubernetes.io/docs/concepts/workloads/controllers/deployment/

1. 什么是 Deployment?

Deployment 为 Pod 和 Replica Set(下一代 Replication Controller)提供声明式更新。

只需要在 Deployment 中描述您想要的目标状态是什么,Deployment controller 就会帮您将 Pod 和 ReplicaSet 的实际状态改变到您的目标状态。您可以定义一个全新的 Deployment 来创建 ReplicaSet 或者删除已有的 Deployment 并创建一个新的来替换。

  • 定义 Deployment 来创建 Pod 和 ReplicaSet
  • 滚动升级和回滚应用
  • 扩容和缩容
  • 暂停和继续 Deployment

写到这,想起当年在某节打工时的一个场景:研发上线时,可以选择是否对当前服务进行扩缩容、按照比例对服务进行灰度、回滚服务等等。

是的,这一系列的功能,背后就是Deployment Controller在起作用。

创建Deployment

上一篇中使用了官方提供的node example例子。在本文中,此次将使用nginx镜像进行演示。

以下是部署的示例。它创建一个 ReplicaSet 来启动三个nginxPod:

vim nginx-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
  1. 执行:
kubectl apply -f nginx-deployment.yaml
  1. 查看Deployment 是否已创建:
kubectl get deployments
------
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment      3/3     3            3           2m2s
  1. 要查看Deployment 创建的ReplicaSet,可以运行:
kubectl get rs
------
NAME                            DESIRED   CURRENT   READY   AGE
nginx-deployment-86dcfdf4c6     3         3         3       4m10s
  1. 要查看为每个 Pod 自动生成的标签,可以运行:
kubectl get pods --show-labels
------
NAME                                  READY   STATUS    RESTARTS   AGE     LABELS
nginx-deployment-86dcfdf4c6-2tdlj     1/1     Running   0          6m19s   app=nginx,pod-template-hash=86dcfdf4c6
nginx-deployment-86dcfdf4c6-jqs52     1/1     Running   0          6m19s   app=nginx,pod-template-hash=86dcfdf4c6
nginx-deployment-86dcfdf4c6-vhpsv     1/1     Running   0          6m19s   app=nginx,pod-template-hash=86dcfdf4c6

2. 更新部署

注意:当且仅当 Deployment 的 Pod 模板(即.spec.template)发生更改(例如,模板的标签或容器映像更新)时,才会触发 Deployment 的推出。其他更新(例如扩展部署)不会触发部署。

  1. 将nginx Pod 从nginx:1.14.2更新成nginx:1.16.1
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1

或者使用kubectl edit deployment/nginx-deployment来对文件手动进行更改。

  1. 查看部署状态

运行kubectl get rs可以看到 Deployment 通过创建新的 ReplicaSet 并将其扩展到 3 个副本,以及将旧的 ReplicaSet 缩减到 0 个副本来更新 Pod。

输出类似于:

NAME                            DESIRED   CURRENT   READY   AGE
nginx-deployment-848dd6cfb5     3         3         3       3m10s
nginx-deployment-86dcfdf4c6     0         0         0       12m
  • 下次想要更新这些Pod时,只需再次更新Deployment的Pod模板即可。
  • 部署可确保更新时只有一定数量的 Pod 处于关闭状态。默认情况下,它确保至少有 75% 的所需 Pod 数量处于运行状态(最多 25% 不可用)。
  • 部署还确保仅创建高于所需 Pod 数量的一定数量的 Pod。默认情况下,它确保最多 125% 的所需 Pod 数量处于启动状态(最大激增 25%)。
  • 例如,如果你仔细观察上面的 Deployment,你会发现它首先创建了一个新的 Pod,然后删除了一个旧的 Pod,并创建了另一个新的 Pod。在出现足够数量的新 Pod 之前,它不会杀死旧 Pod;并且在杀死足够数量的旧 Pod 之前,它不会创建新 Pod。它确保至少有 3 个 Pod 可用,并且总共最多有 4 个 Pod 可用。如果部署有 4 个副本,Pod 的数量将在 3 到 5 之间。
  1. 查看部署详细信息

kubectl describe deployments


这里可以看到,当第一次创建Deployment时,它创建了一个ReplicaSet(nginx-deployment-86dcfdf4c6),并直接将其扩展到3个副本。当更新 Deployment 时,它创建了一个新的 ReplicaSet (nginx-deployment-848dd6cfb5) 并将其扩展到 1 并等待它出现。然后将旧的 ReplicaSet 缩小到 2 个,将新的 ReplicaSet 扩大到 2 个,这样每次都至少有 3 个 Pod 可用,最多创建 4 个 Pod。然后,它使用相同的滚动更新策略继续扩展和缩小新旧 ReplicaSet。最后,新的 ReplicaSet 中将有 3 个可用副本,而旧的 ReplicaSet 会缩小到 0。

3. 回滚部署

假设在更新部署时犯了拼写错误,将nginx:1.16.1写成了nginx:1.161

kubectl set image deployment/nginx-deployment nginx=nginx:1.161

执行kubectl rollout status deployment/nginx-deployment来验证执行过程。

此时,可以 Ctrl-C 停止掉,执行kubectl get rs

查看创建的 Pod,您会发现新 ReplicaSet 创建的 1 个 Pod 陷入了镜像拉取循环。

kubectl get pods

注意:部署控制器会自动停止错误的部署,并停止扩展新的副本集。这取决于maxUnavailable指定的rollingUpdate 参数。Kubernetes 默认将该值设置为 25%。

要解决此问题,您需要回滚到之前稳定的 Deployment 版本。

1. 首先,检查此 Deployment 的历史修订
kubectl rollout history deployment/nginx-deployment


CHANGE-CAUSE在创建时,从部署注释复制kubernetes.io/change-cause到其修订版本。此处,本文并没有进行注释,因此CHANGE-CAUSE显示none。

CHANGE-CAUSE可以通过使用注释部署方式指定消息:

kubectl annotate deployment/nginx-deployment kubernetes.io/change-cause="image updated to 1.16.1"
2. 查看每个修订的详细信息
kubectl rollout history deployment/nginx-deployment --revision=2
3. 回滚到以前的修订

撤消当前的修改并回滚到以前的修订版

kubectl rollout undo deployment/nginx-deployment

或者

kubectl rollout undo deployment/nginx-deployment --to-revision=2

再次执行kubectl get deployment nginx-deployment查看是否回滚。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/264117.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Springboot是什么?Springboot详解!入门介绍

📫作者简介:小明java问道之路,2022年度博客之星全国TOP3,专注于后端、中间件、计算机底层、架构设计演进与稳定性建设优化,文章内容兼具广度、深度、大厂技术方案,对待技术喜欢推理加验证,就职于…

数据库编程大赛:一条SQL计算扑克牌24点

你是否在寻找一个平台,能让你展示你的SQL技能,与同行们一较高下?你是否渴望在实战中提升你的SQL水平,开阔你的技术视野?如果你对这些都感兴趣,那么本次由NineData主办的《数据库编程大赛》,将是…

pg自定义函数动态生成表名

目录 一、需求 二、踩坑记录 三、解决方案 一、需求 想在postgres数据库中动态查询【table_2023、table_2024...】这种格式表的数据。 例如: 今天是2023-12-22号,查询语句为select * from table_2023; 今天是2024-12-22号,查询语句为sele…

Navicat里MySQL表的创建(详细)

我以Navicat连接MySQL为例,演示表的创建方法。 前提 创建表的语法: create table 表名 ( 字段名1,字段类型, 字段名2,字段类型, ...... 字段名n,字段类型 ); 我计划在test库存放一…

【c】无限制输入字符

我们做题有时候会碰上这种的输入,一直输入字符, 下面附上两种解决办法 方法1: char s[10000]; int i0; int arr[1000]{0}; while(scanf("%c",&s[i])!EOF) { i; } 这样你就可以一直输入&#xff0…

深信服AF防火墙升级步骤(简单粗暴)

设备当前版本:AF8.0.75 升级升级后版本:AF8.0.85 官方发行:内容比较多,找设备当前版本在不在支持升级的列表即可 8.0.75是可以直接升到8.0.85的 升级前注意事项: 升级是需要重启设备的,会断网&#xff…

FreeRTOS之队列集操作(实践)

多个任务在在同一队列中传递的同一种数据类型,而队列集能够在任务之间传递不同的数据类型。 配置流程:(更详细流程参考正点原子的教程) 1、启用队列集将configUSE_QUEUE_SETA置1) 2、创建队列集 3、创建队列或信号…

Java中的Stream流收集器

目录 1、归约和汇总 2、分组 3、分区 4、理解收集器接口 Java 中 Stream 流用来帮助处理集合,类似于数据库中的操作。 在 Stream 接口中,有一个抽象方法 collect,你会发现 collect 是一个归约操作(高级规约)&#…

[NISACTF 2022]easyssrf

[NISACTF 2022]easyssrf wp ssrf 的题目,提示了会使用 curl 连接输入的网站并返回响应包。 测试连接百度 直接在输入框中写 www.baidu.com 是无法连接的,需要在前面加入 http 或者 https ,因为 curl 的使用方式就是: curl htt…

linux系统和网络(二):进程和系统时间

本文主要探讨linux系统进程和系统相关知识,本博客其他博文对该文章的部分内容有详细介绍 main函数 int main(int argc,char *argv[],char *envp[]); 操作系统下main执行前先执行引导代码,编译连接引导代码和程序连接在一起构成可执行程序,加载器将程序加载到内存中…

MyBatis关联查询(三、多对多查询)

MyBatis关联查询(三、多对多查询) 需求:查询角色及角色赋予的用户信息。 分析:一个用户可以拥有多个角色,一个角色也可以赋予多个用户,用户和角色为双向的一对多关系,多对多关系其实我们看成是…

代码随想录第三十八天(一刷C语言)|零钱兑换II组合总数和 IV

创作目的:为了方便自己后续复习重点,以及养成写博客的习惯。 一、零钱兑换II 思路:参考carl文档 1、确定dp数组以及下标的含义:凑成总金额j的货币组合数为dp[j]。 2、确定递推公式:dp[j] 就是所有的dp[j - coins[i…

lpg期货指数(LPG期货指数盘整整理)

什么是LPG期货指数? LPG期货指数是以液化石油气(Liquefied Petroleum Gas)作为标的物的期货指数,涵盖了LPG国内期货市场的价格变化。LPG是一种广泛用于家庭、工业和交通等领域的燃料。在中国,LPG期货主要交易于上海国…

面试遇到了接口分析和测试用例分析题,该如何下手?

只要有软件产品的公司百分之九十以上都会做接口测试,要做接口测试的公司那是少不了接口测试工程师的,接口测试工程师相对于其他的职位又比较轻松并且容易胜任。如果你想从事接口测试的工作那就少不了对接口进行分析,同时也会对测试用例进行研…

使用Docker-镜像命令

镜像名称一般分两部分组成:[repository]:[tag] 在没有指定tag时,默认是latest,代表最新版本的镜像 目录 案例一:从DockerHub中拉取一个nginx镜像并查看 1.1. 首先去镜像仓库搜索nginx镜像,比如DockerHub ​编辑 1.2.操作拉取n…

【算法刷题】Day23

文章目录 1. 打家劫舍 II题干:算法原理:(dp)1. 状态表示:2. 状态转移方程3. 初始化4. 填表顺序5. 返回值 代码: 2. 和为 K 的子数组题干:算法原理:1. 暴力枚举2. 前缀和 哈希表 代码…

(十七)Flask之大型项目目录结构示例【二扣蓝图】

大型项目目录结构: 问题引入: 在上篇文章讲蓝图的时候我给了一个demo项目,其中templates和static都各自只有一个,这就意味着所有app的模板和静态文件都放在了一起,如果项目比较大的话,这就非常乱&#xf…

macOS 开发 - MASShortcut

文章目录 关于 MASShortcut项目结构 快速使用源码学习检测是否有热键冲突处理 Event macOS 开发交流 秋秋群:644096295,V : ez-code 关于 MASShortcut MASShortcut 是一款快捷键管理工具,替代和兼容 ShortcutRecorder github : https://git…

解决找不到vcruntime140.dll无法继续执行的多种方法分享

最近,我在使用电脑时遇到了一个问题,即“由于找不到vcruntime140.dll无法继续执行”。vcruntime140.dll是Visual C Redistributable Packages中的一个组件,它是Visual Studio 2015中运行C程序所必需的。如果找不到vcruntime140.dll文件&#…

java-sec-code中rmi

java-sec-code中rmi 暂时没有搞懂原理,这里只说明利用方法 java-sec-code 作者给出的是使用ysoserial进行利用 测试环境搭建 docker环境下,1099端口默认不开启,这里使用idea运行org.joychou.RMI.Server即可 个人电脑java环境分为1.8.381 1.8.…