【云原生

2023-11-10

目录

四、通过 k8s 实现滚动更新

4.3 自定义滚动更新策略

取值范围

建议配置

总结

测试:自定义策略 

重建式更新:Recreate 

五、生产环境如何实现蓝绿部署?

5.1 什么是蓝绿部署?

5.2 蓝绿部署的优势和缺点

优点:

缺点:

5.3 通过 k8s 实现线上业务的蓝绿部署 

1.创建绿色部署环境(基于第一版代码做的镜像运行的 pod)

2.创建前端 service(实现在浏览器访问页面) 

3.创建蓝色部署环境(新上线的环境,要替代绿色环境) 

六、通过 k8s 完成线上业务的金丝雀发布 

6.1 金丝雀发布简介

6.2 在 k8s 中实现金丝雀发布 


四、通过 k8s 实现滚动更新

4.3 自定义滚动更新策略

maxSurge 和 maxUnavailable 用来控制滚动更新的更新策略。

取值范围

数值

  • maxUnavailable: [0, 副本数]
  • maxSurge: [0, 副本数]

注意:两者不能同时为 0。

比例

  • maxUnavailable: [0%, 100%] 表示向下取整,比如10个副本,5%的话==0.5个,但计算按照0个;
  • maxSurge: [0%, 100%] 表示向上取整,比如10个副本,5%的话==0.5个,但计算按照1个;

注意:两者不能同时为0。

建议配置

  • maxUnavailable == 0
  • maxSurge == 1

这是我们生产环境提供给用户的默认配置。即“一上一下,先上后下”最平滑原则:

        1个新版本 pod ready(结合readiness)后,才销毁旧版本 pod。此配置适用场景是平滑更新、保证服务平稳,但也有缺点,就是“太慢”了。

总结

  • maxUnavailable:和期望的副本数比,不可用副本数最大比例(或最大值),这个值越小,越能保证服务稳定,更新越平滑;
  • maxSurge:和期望的副本数比,超过期望副本数最大比例(或最大值),这个值调的越大,副本更新速度越快。

测试:自定义策略 

[root@k8s-master01 ~]# kubectl explain deployment.spec
[root@k8s-master01 ~]# kubectl explain deployment.spec.strategy
[root@k8s-master01 ~]# kubectl explain deployment.spec.strategy.rollingUpdate

# 修改更新策略:maxUnavailable=1,maxSurge=1
[root@k8s-master01 ~]# vim deploy-demo.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-v1
spec:
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  replicas: 3

# 因为上一篇咱们回滚了版本,否则需要修改镜像之后才能 pod 创建成功
[root@k8s-master01 ~]# kubectl apply -f deploy-demo.yaml 
deployment.apps/myapp-v1 configured

# 查看 myapp-v1 这个控制器的详细信息
[root@k8s-master01 ~]# kubectl describe deployment myapp-v1 
Name:                   myapp-v1
Namespace:              default
CreationTimestamp:      Sat, 10 Dec 2022 18:09:22 +0800
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 4
Selector:               app=myapp,version=v1
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  1 max unavailable, 1 max surge
Pod Template:
  Labels:  app=myapp
           version=v1

        上面可以看到 RollingUpdateStrategy: 1 max unavailable, 1 max surge。这个 rollingUpdate更新策略变成了刚才设定的,因为我们设定的pod副本数是3,1和1表示最少不能少于2个pod,最多不能超过4个pod。这个就是通过控制 RollingUpdateStrategy 这个字段来设置滚动更新策略的例子。

重建式更新:Recreate 

# 把 pod 更新策略变成 Recreate
[root@k8s-master01 ~]# vim deploy-demo.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-v1
spec:
  strategy:
    type: Recreate
  replicas: 3
······
    spec:
      containers:
      - name: myapp
        image: janakiramm/myapp:v1    # 镜像也要更改为 v1

[root@k8s-master01 ~]# kubectl apply -f deploy-demo.yaml 
deployment.apps/myapp-v1 configured

总结:recreate 这种更新策略,会把之前的所有 pod 都删除,再创建新的pod,风险很大。

五、生产环境如何实现蓝绿部署?

5.1 什么是蓝绿部署?

        蓝绿部署中,一共有两套系统:一套是正在提供服务系统,标记为“绿色”;另一套是准备发布的系统,标记为“蓝色”。两套系统都是功能完善的、正在运行的系统,只是系统版本和对外服务情况不同。

        开发新版本,要用新版本替换线上的旧版本,在线上的系统之外,搭建了一个使用新版本代码的全新系统。 这时候,一共有两套系统在运行,正在对外提供服务的老系统是绿色系统,新部署的系统是蓝色系统。

蓝色系统不对外提供服务,用来做什么呢?

        用来做发布前测试,测试过程中发现任何问题,可以直接在蓝色系统上修改,不干扰用户正在使用的系统。(注意,两套系统没有耦合的时候才能百分百保证不干扰)

        蓝色系统经过反复的测试、修改、验证,确定达到上线标准之后,直接将用户切换到蓝色系统: 

        切换后的一段时间内,依旧是蓝绿两套系统并存,但是用户访问的已经是蓝色系统。这段时间内观察蓝色系统(新系统)工作状态,如果出现问题,直接切换回绿色系统。

        当确信对外提供服务的蓝色系统工作正常,不对外提供服务的绿色系统已经不再需要的时候,蓝色系统正式成为对外提供服务系统,成为新的绿色系统。 原先的绿色系统可以销毁,将资源释放出来,用于部署下一个蓝色系统。

5.2 蓝绿部署的优势和缺点

优点:

  1. 更新过程无需停机,风险较少
  2. 回滚方便,只需要更改路由或者切换DNS服务器,效率较高

缺点:

  1. 成本较高,需要部署两套环境。如果基础服务出现问题,会瞬间影响全网用户;如果新版本有问题也会影响全网用户。
  2. 需要部署两套机器,费用开销大
  3. 在非隔离的机器(Docker、VM)上操作时,可能会导致蓝绿环境被摧毁风险
  4. 负载均衡器/反向代理/路由/DNS处理不当,将导致流量没有切换过来情况出现

5.3 通过 k8s 实现线上业务的蓝绿部署 

下面实验需要的镜像包上传到 k8s 的各个工作节点,ctr -n=k8s.io images import 解压: 

[root@k8s-node1 ~]# ctr -n=k8s.io images import myapp-lan.tar.gz
[root@k8s-node1 ~]# ctr -n=k8s.io images import myapp-lv.tar.gz

[root@k8s-node2 ~]# ctr -n=k8s.io images import myapp-lan.tar.gz
[root@k8s-node2 ~]# ctr -n=k8s.io images import myapp-lv.tar.gz

        Kubernetes 不支持内置的蓝绿部署。目前最好的方式是创建新的 deployment,然后更新应用程序的 service 以指向新的 deployment 部署的应用。

1.创建绿色部署环境(基于第一版代码做的镜像运行的 pod)

[root@k8s-master01 ~]# vim lv.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-v1
  namespace: blue-green
spec:
  replicas: 3
  selector:
   matchLabels:
    app: myapp
    version: v2
  template:
   metadata:
    labels:
     app: myapp
     version: v2
   spec:
    containers:
    - name: myapp
      image: janakiramm/myapp:v2
      imagePullPolicy: IfNotPresent
      ports:
      - containerPort: 80

# 创建名称空间
[root@k8s-master01 ~]# kubectl create ns blue-green
namespace/blue-green created

# 创建资源
[root@k8s-master01 ~]# kubectl apply -f lv.yaml
deployment.apps/myapp-v1 created

# 查看指定名称空间下的 pod 详细信息:
[root@k8s-master01 ~]# kubectl get pods -n blue-green --show-labels -o wide 
NAME                        READY   STATUS    RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES   LABELS
myapp-v1-75d7db5cf7-4tglq   1/1     Running   0          26s   10.244.169.133   k8s-node2   <none>           <none>            app=myapp,pod-template-hash=75d7db5cf7,version=v2
myapp-v1-75d7db5cf7-w6ln2   1/1     Running   0          26s   10.244.169.134   k8s-node2   <none>           <none>            app=myapp,pod-template-hash=75d7db5cf7,version=v2
myapp-v1-75d7db5cf7-zkj5b   1/1     Running   0          26s   10.244.36.114    k8s-node1   <none>           <none>            app=myapp,pod-template-hash=75d7db5cf7,version=v2

2.创建前端 service(实现在浏览器访问页面) 

[root@k8s-master01 ~]# vim service_lanlv.yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-lan-lv
  namespace: blue-green
  labels:
    app: myapp
spec:
  type: NodePort
  ports:
  - port: 80
    nodePort: 30062
    name: http
  selector:
    app: myapp
    version: v2

[root@k8s-master01 ~]# kubectl apply -f service_lanlv.yaml
service/myapp-lan-lv created

[root@k8s-master01 ~]# kubectl get service -n blue-green
NAME           TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
myapp-lan-lv   NodePort   10.97.110.87   <none>        80:30062/TCP   29s

在浏览器访问 http://k8s-master节点ip:30062 (http://192.168.78.133:30062/)显示如下:

3.创建蓝色部署环境(新上线的环境,要替代绿色环境) 

[root@k8s-master01 ~]# vim lan.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-v2
  namespace: blue-green
spec:
  replicas: 3
  selector:
   matchLabels:
    app: myapp
    version: v1
  template:
   metadata:
    labels:
     app: myapp
     version: v1
   spec:
    containers:
    - name: myapp
      image: janakiramm/myapp:v1
      imagePullPolicy: IfNotPresent
      ports:
      - containerPort: 80

[root@k8s-master01 ~]# kubectl apply -f lan.yaml 
deployment.apps/myapp-v2 created

# 可以看到一共有六个pods,上面三个是绿色系统,下面三个是蓝色系统:
[root@k8s-master01 ~]# kubectl get pods -n blue-green --show-labels -o wide 
NAME                        READY   STATUS    RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES   LABELS
myapp-v1-75d7db5cf7-4tglq   1/1     Running   0          15m   10.244.169.133   k8s-node2   <none>           <none>            app=myapp,pod-template-hash=75d7db5cf7,version=v2
myapp-v1-75d7db5cf7-w6ln2   1/1     Running   0          15m   10.244.169.134   k8s-node2   <none>           <none>            app=myapp,pod-template-hash=75d7db5cf7,version=v2
myapp-v1-75d7db5cf7-zkj5b   1/1     Running   0          15m   10.244.36.114    k8s-node1   <none>           <none>            app=myapp,pod-template-hash=75d7db5cf7,version=v2
myapp-v2-85cc897d89-9rqlc   1/1     Running   0          29s   10.244.36.115    k8s-node1   <none>           <none>            app=myapp,pod-template-hash=85cc897d89,version=v1
myapp-v2-85cc897d89-gqv77   1/1     Running   0          29s   10.244.169.137   k8s-node2   <none>           <none>            app=myapp,pod-template-hash=85cc897d89,version=v1
myapp-v2-85cc897d89-x2c42   1/1     Running   0          29s   10.244.169.135   k8s-node2   <none>           <none>            app=myapp,pod-template-hash=85cc897d89,version=v1

# 修改 service_lanlv.yaml 配置文件,修改标签,让其匹配到蓝系统服务(升级之后的系统)
  selector:
    app: myapp
    version: v1
# 由 v2 变为 v1 即可

# 更新资源清单文件:
[root@k8s-master01 ~]# kubectl apply -f service_lanlv.yaml
service/myapp-lan-lv configured

[root@k8s-master01 ~]# kubectl get service -n blue-green
NAME           TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
myapp-lan-lv   NodePort   10.97.110.87   <none>        80:30062/TCP   13m

# 查看 service 资源详细信息
[root@k8s-master01 ~]# kubectl describe service myapp-lan-lv -n blue-green

在浏览器访问 http://k8s-master节点ip:30062 显示如下: 

实验完成之后,把资源先删除,以免影响后面实验:

[root@k8s-master01 ~]# kubectl delete -f lan.yaml
deployment.apps "myapp-v2" deleted
[root@k8s-master01 ~]# kubectl delete -f lv.yaml
deployment.apps "myapp-v1" deleted
[root@k8s-master01 ~]# kubectl delete -f service_lanlv.yaml 
service "myapp-lan-lv" deleted

六、通过 k8s 完成线上业务的金丝雀发布 

6.1 金丝雀发布简介

        金丝雀发布的由来:17 世纪,英国矿井工人发现,金丝雀对瓦斯这种气体十分敏感。空气中哪怕有极其微量的瓦斯,金丝雀也会停止歌唱;当瓦斯含量超过一定限度时,虽然人类毫无察觉,金丝雀却早已毒发身亡。当时在采矿设备相对简陋的条件下,工人们每次下井都会带上一只金丝雀作为瓦斯检测指标,以便在危险状况下紧急撤离。

        金丝雀发布(又称灰度发布、灰度更新):金丝雀发布一般先发1台,或者一个小比例,例如2%的服务器,主要做流量验证用,也称为金丝雀 (Canary) 测试 (国内常称灰度测试)。

假如有100个 pod,更新了一个pod:用的新的代码做的镜像,99个pod:没有更新。

        简单的金丝雀测试一般通过手工测试验证,复杂的金丝雀测试需要比较完善的监控基础设施配合,通过监控指标反馈,观察金丝雀的健康状况,作为后续发布或回退的依据。 如果金丝测试通过,则把剩余的V1版本全部升级为V2版本。如果金丝雀测试失败,则直接回退金丝雀,发布失败。

  • 优点:灵活,策略自定义,可以按照流量或具体的内容进行灰度(比如不同账号,不同参数),出现问题不会影响全网用户。
  • 缺点:没有覆盖到所有的用户导致出现问题不好排查。

6.2 在 k8s 中实现金丝雀发布 

# 打开另一个会话监测更新过程
[root@k8s-master01 ~]# kubectl get pods -n blue-green -o wide -w

[root@k8s-master01 ~]# kubectl apply -f lv.yaml
deployment.apps/myapp-v1 created

# 使用命令行修改镜像,发布新版服务
[root@k8s-master01 ~]# kubectl set image deployment myapp-v1 myapp=nginx:latest -n blue-green && kubectl rollout pause deployment myapp-v1 -n blue-green

        解释说明:把 myapp 这个容器的镜像更新到 nginx:latest ,更新镜像之后,创建一个新的 pod 就立即暂停,这就是我们说的金丝雀发布;如果暂停几个小时之后没有问题,那么取消暂停,就会依次执行后面步骤,把所有 pod 都升级。

我们先访问旧的镜像服务:

绿色背景:

访问新服务 nginx:

金丝雀实验成功,解除暂停,发布更新:

[root@k8s-master01 ~]# kubectl rollout resume deployment myapp-v1 -n blue-green
deployment.apps/myapp-v1 resumed

可以看到如下一些信息,下面过程是把余下的3个 pod 里的容器都更新:

访问下面三个更新后的 pod ip,都是 nginx 访问信息:

 上一篇文章:【云原生 | Kubernetes 实战】10、K8s 控制器 Deployment 入门到企业实战应用(上)_Stars.Sky的博客-CSDN博客

下一篇文章:【云原生 | Kubernetes 实战】12、K8s 四层代理 Service 入门到企业实战应用(上)_Stars.Sky的博客-CSDN博客

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【云原生 的相关文章

随机推荐

  • 【华为OD机试】GPU算力【2023 B卷

    华为OD机试 真题 点这里 华为OD机试 真题考点分类 点这里 题目解析 为了充分发挥GPU算力 需要尽可能多的将任务交给GPU执行 现在有一个任务数组 数组元素表示在这1秒内新增的任务个数且每秒都有新增任务 假设GPU最多一次执行n个任务
  • MySQL8.0忘记密码重置账户

    好久没用MySQL 发现忘记密码 大概试了三种方法 记录下尝试的过程 方法一 失败 参考ERROR 1045 28000 Access denied for user root localhost using password NO 解决办
  • linux 脚本返回值

    linux 脚本返回值 简单版本 1 创建一个脚本a 内容如下 bin sh filename a exit 22 2 创建一个c语言程序1 C 调用该脚本 通过system的返回值来判断是否执行脚本成功 include
  • Unused import statement

    Unused import statement 未使用的导入语句 File菜单 invalidate caches restart选项 点击即可
  • V-REP仿真之Python读取关节当前角度和驱动ur机械臂关节旋转

    V REP仿真之Python读取关节当前角度和驱动ur机械臂关节旋转 在建立与机械臂的通信之后 接着需要读取和驱动ur机械臂的关节角度 代码如下 coding UTF 8 import sim import time import sys
  • 2018看得见的未来:人工智能何去何从?

    2018看得见的未来 系列报道现在继续 本期重磅推出由云报和O Reilly Media共同策划的2018人工智能发展趋势 本系列报道将邀请内业的重量级厂商 专家 大咖 一起畅想2018年IT领域的大事小情 热点焦点 也欢迎有兴趣的厂商都参
  • el-upload自定义上传文件显示进度条

    el upload自定义上传文件时需要显示进度条 但使用http request会覆盖默认的上传行为 on progress也就不生效了 所以可以自定义上传的实现 效果图 功能实现 按钮
  • 微信小程序根据经纬度查看地图

    var longitude 101 234567 var latitude 202 123456 wx openLocation longitude Number longitude 经度或纬度必须是number类型 latitude Nu
  • linux关闭防火墙和打开防火墙

    永久打开或则关闭 chkconfig iptables on chkconfig iptables off 即时生效 重启后还原 service iptables start service iptables stop
  • XXX.axf: Error: L6218E: Undefined symbol xxx (referred from xxxx.o).

    MKD 报错 linking LCD axf Error L6218E Undefined symbol EnZK referred from ht128x64 o LCD axf Error L6218E Undefined symbol
  • 【shell】 =~的使用

    如下 read p need compile OEM installatoin package yes no IS OEM if z IS OEM then IS OEM No fi if Yes IS OEM yes IS OEM the
  • win10配置 tesseract 中文字符识别

    下载win10下的tesseract的安装包 https digi bib uni mannheim de tesseract 下载后双击进行安装 这里因为我们要识别中文字符 所以在安装界面中需要进行额外的语言勾选 展开Additional
  • centos7清理yum源

    1 删除起始的源 cd etc yum repos d rm f echo delete error 2 卸载yum rpm qa grep yum xargs I rpm e nodeps 3 下载最新的yum程序的rpm包 http m
  • 【HTML】不来看看HTML5的WebStorage吗

    HTML 不来看看HTML5的WebStorage吗 面试官 讲讲sessionStorage和localStorage的区别 回答 en 一个有限制 一个无 技术选型 做一个离线数据的缓存 回答 好像都能实现 随便用 引言 内容速递 看了
  • eval(function(p,a,c,k,e,d){e=function(c)加解密

    1 2 3 4 5 6 7 8
  • 初学STM32之看门狗

    初学STM32之看门狗 一 看门狗概述 1 什么是看门狗 单片机在工作中常常会受到来自外界电磁场的干扰 造成程序跑飞 而陷入死循环 程序的正常运行被打断 使得系统无法正常工作 造成整个系统陷入停滞状态 所以为了对单片运行状态进行实时监测 便
  • HTML <section> 标签

    实例 文档中的区段 解释了 PRC section h1 PRC h1 p The People s Republic of China was born in 1949 p section 定义和用法 section 标签定义文档中的节
  • Difference Between LiDAR and RADAR——LiDAR和RADAR的不同

    Difference Between LiDAR and RADAR 原文连接 https www differencebetween com difference between lidar and vs radar 翻译 RADAR和L
  • ifconfig命令不存在command not found

    ifconfig命令不存在command not found场景 刚刚装linux centos mini 想用远程工具链接 首先得查看一下ip吧 结果发现 ifconfig命令不存在 一个命令不存在 无非两种情况 情况一 不在环境变量中
  • 【云原生

    目录 四 通过 k8s 实现滚动更新 4 3 自定义滚动更新策略 取值范围 建议配置 总结 测试 自定义策略 重建式更新 Recreate 五 生产环境如何实现蓝绿部署 5 1 什么是蓝绿部署 5 2 蓝绿部署的优势和缺点 优点 缺点 5