k8s的Init Containers容器实现代码版本升级发布和deployment版本回退:实战操作版

Pod中的初始化容器:Init Containers

initContainers实现理论前提:同一个Pod内的容器共享 网络、volume等资源

Init Containers

在Kubernetes中,init容器是在同一个Pod中的其他容器之前启动和执行的容器。它的目的是为Pod上托管的主应用程序执行初始化逻辑。例如,创建必要的用户帐户、执行数据库迁移、创建数据库模式等等。

Init Containers设计注意事项

• 它们总是比Pod里的其他容器先执行。因此,它们不应该包含需要很长时间才能完成的复杂逻辑。启动脚本通常很小而且简洁。如果我们发现在init容器中添加了太多的逻辑,那就应该考虑将它的一部分移到应用程序容器本身。

• Init容器按顺序启动和执行。除非成功完成其前置容器,否则不会调用init容器。因此,如果启动任务很长,可以考虑将其分成若干步骤,每个步骤都由init容器处理,以便知道哪些步骤失败。

• 如果任何init容器失败,整个Pod将重新启动(除非将restartPolicy设置为Never)。重新启动Pod意味着重新执行所有容器,包括任何init容器。因此,我们可能需要确保启动逻辑能够容忍多次执行而不会导致重复。例如,如果数据库迁移已经完成,那么应该忽略再次执行迁移命令。

• 在一个或多个依赖项可用之前,init容器是延迟应用程序初始化的一个很好的候选者。例如,如果我们的应用程序依赖于一个施加了API请求速率限制的API,可能需要等待一段时间才能从该API接收响应。在应用程序容器中实现此逻辑可能很复杂;因为它需要与运行状况和准备状态探测相结合。一种更简单的方法是创建一个init容器,该容器等待API准备好后才能成功退出。只有在init容器成功完成其工作之后,应用程序容器才会启动。

• Init容器不能像应用程序容器那样使用liveness和readiness探针。原因是它们注定要成功启动后退出,就像Jobs和CronJobs的行为一样。

• 同一个Pod内的所有容器共享相同的卷和网络。我们可以使用此特性在应用程序及其init容器之间共享数据。

Init Containers的“请求”和“限制”行为

正如我们刚刚讨论的,init容器总是在同一个Pod上的其他应用程序容器之前启动。因此,调度程序为init容器的资源和限制提供了更高的优先级。这种行为必须被彻底考虑,因为它可能会导致不期望的结果。例如,如果我们有一个init容器和一个应用程序容器,并且将init容器的资源和限制设置为高于应用程序容器的资源和限制,那么只有在存在满足init容器要求的可用节点时,才会调度整个Pod。换句话说,即使有一个未使用的节点可以运行应用程序容器,如果init容器具有该节点可以处理的更高的资源先决条件,那么Pod也不会部署到该节点。因此,在定义init容器的请求和限制时,应该尽可能严格。作为最佳实践,除非绝对需要,否则不要将这些参数设置为高于应用程序容器的值。

应用场景1: 代码升级发布

以java项目war包 + tomcat为例, 如果我们总是将 代码+tomcat打包为镜像一起发布,那么这个镜像相对就会比较到,而我们项目更新往往时只是代码部分,如果这样频繁更新发布那么每次大镜像传输非常消耗资源和时间。因此可以考虑将 war 单独作为一个镜像 实现为 initContainers,tomcat运行平台单独为一个 container。

使用deployment加InitContainer实现代码的升级发布以及版本回退

k8s的集群我的上个博文有介绍了详细的安装步骤,这里就不提及安装过程了

首先将Tomcat的代码准备好,这里我准备了两个代码,一个是Tomcat的初始页面代码,一个是zrlog项目的代码

然后在代码目录下编辑Dockerfile文件,将两个代码都打包成镜像

这个是初始页面的代码

[root@server151 test]# ls
Dockerfile  ROOT.war
[root@server151 test]# cat Dockerfile 
FROM alpine
WORKDIR /code
COPY  ./ROOT.war   /tmp
[root@server151 test]# docker build -t tomcat:v0 .

这个是zrlog项目的代码

[root@server151 web]# ls
Dockerfile  ROOT.war
[root@server151 web]# cat Dockerfile 
FROM alpine
WORKDIR /code
COPY  ./ROOT.war   /tmp
[root@server151 web]# docker build -t zrlog:v1 .

然后将两个镜像都推送到我们的私有镜像仓库

推送镜像的过程我就不赘述了,我的上一篇博文详细的写了私有镜像仓库的创建和使用,忘记了的可以去看看

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

代码准备好以后,就可以去我们的k8s构建deployment了

先准备一个空目录,然后进入这个空目录

用kubectl创建一个tomcat的deployment模板,这样就不用我们完全手写了,只需要修改部分代码

[root@server153 test]# kubectl create deployment tomcat-deploy --image tomcat --dry-run=server -o yaml > tomcat-deploy.yaml
[root@server153 test]# ls 
tomcat-deploy.yaml

然后将模板文件修改成我们需要的

[root@server153 test]# cat tomcat-deploy.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: tomcat-deployname: tomcat-deploynamespace: default
spec:progressDeadlineSeconds: 600replicas: 1revisionHistoryLimit: 10selector:matchLabels:app: tomcat-deploystrategy:rollingUpdate:maxSurge: 25%maxUnavailable: 25%type: RollingUpdatetemplate:metadata:creationTimestamp: nulllabels:app: tomcat-deployspec:#创建init容器initContainers:#代码镜像- image: www.test.com/mytest/tomcat:v0#init容器名字name: init#将代码复制到匿名数据卷command: ["cp","-R","/tmp/ROOT.war","/www"]#将匿名数据卷挂载到容器中的/www目录下volumeMounts:- mountPath: /wwwname: tomcat-volume#创建tomcat容器containers:- image: oxnme/tomcat#重启策略imagePullPolicy: Alwaysname: tomcatterminationMessagePath: /dev/termination-logterminationMessagePolicy: File#将数据卷挂载到tomcat的代码目录下volumeMounts:- mountPath: /usr/local/tomcat/webapps/name: tomcat-volumednsPolicy: ClusterFirstrestartPolicy: AlwaysschedulerName: default-schedulerterminationGracePeriodSeconds: 10#创建匿名数据卷volumes:- name: tomcat-volumeemptyDir: {}

然后开始构建我们的deployment资源

[root@server153 test]# kubectl apply -f tomcat-deploy.yaml 
deployment.apps/tomcat-deploy created

注意看运行结果后面的结尾的是created

因为我们的还没有配置service,只能在本机访问,外网是不能访问的

所以下个nginx做代理转发查看结果

先看看刚才创建pod的ip

[root@server153 test]# kubectl get pods -o wide
NAME                             READY   STATUS    RESTARTS   AGE     IP          NODE        NOMINATED NODE   READINESS GATES
tomcat-deploy-8457d967b5-ltwd6   1/1     Running   0          5m45s   10.2.1.36   server154   <none>           <none>

然后下载nginx

[root@server153 test]# yum install nginx -y
[root@server153 test]# vim /etc/nginx/nginx.conf

在这里插入图片描述

启动nginx后去浏览器查看情况

[root@server153 test]# systemctl start nginx.service 

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

可以看到是可以正常访问到的

现在我们去模拟代码升级,用另一个代码镜像替换

继续修改我们的模板文件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

修改好以后更新我们的deployment资源

[root@server153 test]# kubectl apply -f tomcat-deploy.yaml 
deployment.apps/tomcat-deploy configured

注意看运行结果的结尾,configured,说明我们是更新了配置文件而已,不像刚才一样是创建

[root@server153 test]# kubectl get pods -o wide 
NAME                             READY   STATUS    RESTARTS   AGE   IP          NODE        NOMINATED NODE   READINESS GATES
tomcat-deploy-555479bdf4-hw29f   1/1     Running   0          14s   10.2.1.37   server154   <none>           <none>

这里看我们pod的名称和ip已经换了,说明已经完成了更新,原来的pod删除了,起了新的pod

ip变了我们也得去nginx修改代理的地址

[root@server153 test]# vim /etc/nginx/nginx.conf

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

重启nginx后去浏览器访问

[root@server153 test]# systemctl restart nginx.service

在这里插入图片描述

可以看到我们的代码已经更新成另一个项目的了

说明我们的代码升级完成了

deployment的强大可不仅仅在代码升级,还能回滚

在新版本代码上线的时候,如何出现问题可以快速回滚到上一个版本

刚才我们不是更新了一次代码,我们看看现在deployment的历史版本情况

[root@server153 test]# kubectl rollout history deployment tomcat-deploy 
deployment.apps/tomcat-deploy 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

可以看到有两个版本,我们查看第一个版本的详细情况

我只截取部分,可以看到第一个版本用的镜像

[root@server153 test]# kubectl rollout history deployment/tomcat-deploy --revision=1
deployment.apps/tomcat-deploy with revision #1
Pod Template:Labels:	app=tomcat-deploypod-template-hash=8457d967b5Init Containers:init:Image:	www.test.com/mytest/tomcat:v0

我们再看看第二个版本

[root@server153 test]# kubectl rollout history deployment/tomcat-deploy --revision=2
deployment.apps/tomcat-deploy with revision #2
Pod Template:Labels:	app=tomcat-deploypod-template-hash=555479bdf4Init Containers:init:Image:	www.test.com/mytest/zrlog:v1

可以看到都是对应得上的

比如现在我们刚更新的版本出了问题,我么要回滚到上一个版本

[root@server153 test]# kubectl rollout undo deployment/tomcat-deploy --to-revision=1
deployment.apps/tomcat-deploy rolled back

然后看看pod的情况,可以看到我们的旧版本的pod正在起来

在旧版本pod没起来之前新版本的pod不会直接停止,这样保证了业务能正常运行

[root@server153 test]# kubectl get pods -o wide 
NAME                             READY   STATUS            RESTARTS   AGE   IP          NODE        NOMINATED NODE   READINESS GATES
tomcat-deploy-555479bdf4-hw29f   1/1     Running           0          21m   10.2.1.37   server154   <none>           <none>
tomcat-deploy-8457d967b5-5gdwt   0/1     PodInitializing   0          21s   10.2.1.38   server154   <none>           <none>
[root@server153 test]# kubectl get pods -o wide 
NAME                             READY   STATUS    RESTARTS   AGE    IP          NODE        NOMINATED NODE   READINESS GATES
tomcat-deploy-8457d967b5-5gdwt   1/1     Running   0          116s   10.2.1.38   server154   <none>           <none>

过一会再看可以看到已经回到我们的旧版本pod了,pod的ip变是正常的

然后我们再修改nginx的代理配置

[root@server153 test]# vim /etc/nginx/nginx.conf

在这里插入图片描述

重启nginx,然后去浏览器访问

[root@server153 test]# systemctl restart nginx.service 

在这里插入图片描述

可以看到又回到原来版本的代码了

证明我们的代码版本升级或者回滚都没有问题

可以看出来deploym的确是非常强大的

希望对大家有帮助

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

洛谷P9388 [THUPC 2023 决赛] 先人类的人类选别(主席树+权值线段树)

题目 思路来源 P9388 [THUPC 2023 决赛] 先人类的人类选别 - 违规用户名FkZyA0!2 的博客 - 洛谷博客 题解 这个题是2023ccpc深圳热身赛的题目&#xff0c;也是thupc2023决赛的题目&#xff0c; 学弟问了一下&#xff0c;于是就乱搞了一下&#xff0c;搞了很久才a&#xff0…

Linux ____03、文件类型、属性、修改文件属性(更改文件权限)(命令)

文件类型、属性、修改文件属性 一、文件类型二、文件属性三、修改文件属性1、chgrp&#xff1a;更改文件属组2、chown&#xff1a;更改文件属主&#xff0c;也可以同时更改文件属组3、chmod&#xff1a;更改文件9个属性————————如觉不错&#xff0c;随手点赞&#xff…

微信小程序真机调试连接状态一直在正常和未链接之间反复横跳?

背景&#xff1a;小程序真机调试的时候&#xff0c;发现真机的network不显示接口调用情况&#xff0c;控制台也没有输出内容。具体如下所示&#xff1b; 解决方法&#xff1a; 1、确保手机端连接的网络和微信开发者工具网络一致&#xff0c;比如用同一个WiFi 2、真机自动调试…

编程知识\_C与汇编深入分析

1. 汇编怎么调用C函数 1.1 直接调用 bl main 1.2 想传参数怎么办&#xff1f; 在arm中有个ATPCS规则(ARM-THUMB procedure call standard&#xff08;ARM-Thumb过程调用标准&#xff09;。 约定r0-r15寄存器的用途&#xff1a; r0-r3 调用者和被调用者之间传参数 r4-r11 函…

Flink SQL自定义标量函数(Scalar Function)

使用场景&#xff1a; 标量函数即 UDF&#xff0c;⽤于进⼀条数据出⼀条数据的场景。 开发流程&#xff1a; 实现 org.apache.flink.table.functions.ScalarFunction 接⼝实现⼀个或者多个⾃定义的 eval 函数&#xff0c;名称必须叫做 eval&#xff0c;eval ⽅法签名必须是 p…

冒泡排序

贵阳这个地方的天气变化好大呀&#xff0c;前两天晒大太阳&#xff0c;今天就冷的脚抖&#xff0c;简直不要太冷&#xff0c;但是不管怎么样&#xff0c;还是要学习的哟&#xff01; 冬天来了&#xff0c;春天确实还有一点远&#xff01; 好了&#xff0c;话不多说&#xff0c;…

springboot rocketmq 延时消息、延迟消息

rocketmq也有延迟消息&#xff0c;经典的应用场景&#xff1a;订单30分钟未支付&#xff0c;则取消的场景 其他博客提到从rocketmq5.0开始&#xff0c;支持自定义延迟时间&#xff0c;4.x只支持预定义延迟时间&#xff0c;安装rocketmq可参考RocketMq简介及安装、docker安装ro…

【C++】模板初阶

目录 一&#xff0c;泛型编程 二&#xff0c;函数模板 1&#xff0c;函数模板概念 2&#xff0c;函数模板格式 3&#xff0c;函数模板的原理 4&#xff0c;函数模板的实例化 5&#xff0c;模板参数的匹配原则 三&#xff0c;类模板 1&#xff0c;类模板的定义格式 2&…

⑤ 【MySQL】DCL语句 —— 用户管理、权限控制

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ MySQL用户与权限 ⑤ 【MySQL】DCL语句 —— 用…

pytorch中对nn.BatchNorm2d()函数的理解

pytorch中对BatchNorm2d函数的理解 简介计算3. Pytorch的nn.BatchNorm2d()函数4 代码示例 简介 机器学习中&#xff0c;进行模型训练之前&#xff0c;需对数据做归一化处理&#xff0c;使其分布一致。在深度神经网络训练过程中&#xff0c;通常一次训练是一个batch&#xff0c…

U-Mail邮件系统安全登录解决方案

企业邮箱是企业对内对外商务往来的主要通信工具&#xff0c;并且企业邮箱里面还包含了大量企业内部隐私信息、商业机密等&#xff0c;很容易成为黑客的攻击目标。其中邮件盗号是企业邮箱遭受攻击的主要形式&#xff0c;一旦企业邮箱密码被黑客盗取&#xff0c;黑客不仅可以利用…

操作系统 | 虚拟机及linux的安装

​ &#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《操作系统实验室》&#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 目录结构 1.操作系统实验之虚拟机及linux的安装 1.1 实验目的 1.2 实验内容 1.3 实验步骤 …

BIO、NIO、AIO之间有什么区别

文章目录 BIO优缺点示例代码 NIO优缺点示例代码 AIO优缺点示例代码 总结 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 BIO、NIO和AIO是Java编程语言中用于处理输入输出&#xff08;IO…

MYSQL字符串函数详解和实战(字符串函数大全,内含示例)

MySQL提供了许多字符串函数&#xff0c;用于处理和操作字符串数据。以下是一些常用的MYSQL字符串函数。 建议收藏以备后续用到查阅参考。 目录 一、CONCAT 拼接字符串 二、CONCAT_WS 拼接字符串 三、SUBSTR 取子字符串 四、SUBSTRING 取子字符串 五、SUBSTRING_INDEX 取子…

《红蓝攻防对抗实战》十二.内网穿透之利用ICMP协议进行隧道穿透

内网穿透之利用ICMP协议进行隧道穿透 一.前言二.前文推荐三.利用ICMP协议进行隧道穿透1.ICMPsh获取反弹shell2.PingTunnel 搭建隧道 四.本篇总结 一.前言 本文介绍了利用ICMP协议进行隧道穿透的方法。ICMP协议不需要开放端口&#xff0c;可以将TCP/UDP数据封装到ICMP的Ping数据…

Mysql数据库 14.SQL语言 视图

一、视图的概念 视图&#xff1a;就是由数据库中一张或多张表根据特定的条件查询出的数据狗造成的虚拟表 二、视图的作用 安全性&#xff0c;简单性 三、视图的语法 语法 create view 视图表 as select_statement; 代码实现 #创建视图 将查询结果创建称为视图&#x…

Flutter开发中的一些Tips(四)

最近接手了一个flutter项目&#xff0c;整体感觉代码质量不高&#xff0c;感觉有些是初学者容易犯的问题。几年前写的前三篇&#xff0c;我是站在我自己开发遇到问题的角度&#xff0c;这篇是站在别人遇到问题的角度&#xff0c;算是一种补充。下面我整理一下遇到的小问题&…

中国专利转让数据集(1985-2021年)

专利转让数据追踪和记录专利从一个实体转移到另一个实体的过程。这些数据不仅包括参与转让的申请人和受让人的身份信息&#xff0c;如名字和地址&#xff0c;还涵盖了转让的具体法律细节&#xff0c;包括转让执行日、转让次数、法律状态变更&#xff0c;以及转让登记的相关信息…

在Spring Boot中使用MyBatis访问数据库

MyBatis&#xff0c;这个对各位使用Java开发的开发者来说还是蛮重要的&#xff0c;我相信诸位在企业开发项目的时候&#xff0c;大多数采用的是Mybatis。使用MyBatis帮助我们解决各种问题&#xff0c;实际上这篇文章&#xff0c;基本上默认为可以跳过的一篇&#xff0c;但是为了…

Linux服务器从零开始训练 RT-DETR 改进项目 (Ultralytics) 教程,改进RTDETR算法(包括使用训练、验证、推理教程)

手把手从零开始训练 RT-DETR 改进项目 (Ultralytics版本) 教程,改进RTDETR算法 本文以Linux服务器为例:从零开始使用Linux训练 RT-DETR 算法项目 《芒果剑指 RT-DETR 目标检测算法 改进》 适用于芒果专栏改进RT-DETR算法 文章目录 百度 RT-DETR 算法介绍改进网络代码汇总第…