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

K8S Deployment 实现 蓝绿 发布

一、何为蓝绿发布

蓝绿发布(Blue - Green Deployment)是一种软件部署策略,旨在最大程度减少应用程序停机时间,确保新老版本系统平稳过渡。以下为详细介绍:

1.1、基本概念

  • 存在两个完全相同的生产环境,通常称为 “蓝” 环境和 “绿” 环境 。在任意时刻,只有一个环境对外提供服务,假设当前是蓝色环境服务用户请求,那么绿色环境则处于闲置或预发布状态。
  • 当有新的软件版本需要发布时,先将其部署到非当前运行的环境(如绿色环境)。在绿色环境中完成全面的测试和验证,确保新部署的应用程序功能正常、性能达标。当确认无误后,通过将流量从蓝色环境切换到绿色环境,完成新老版本的更替。
  • 如下图所示,某服务旧版本为v1,对新版本v2进行冗余部署。版本升级时,将现有流量全部切换为新版本v2。

  • 当新版本v2存在问题或者发生故障时,可以快速切回旧版本v1。

1.2、优势

  • 降低风险:通过在切换前对新环境进行充分测试,可在不影响用户体验的前提下,提前发现并解决新部署可能出现的问题,如代码缺陷、配置错误等,从而降低发布失败的风险。
  • 减少停机时间:切换过程只是简单地将流量从一个环境导向另一个环境,如通过修改负载均衡器配置,所以能实现快速切换,显著减少应用程序停机时间,提升用户体验。
  • 回滚便捷:若新环境出现问题,只需将流量重新切回原环境,即可快速恢复到之前稳定的版本,操作相对简单,能有效缩短故障恢复时间。

1.3、局限性

  • 成本较高:需同时维护两个完整的生产环境,包括硬件设施、软件许可等,这无疑增加了企业的基础设施成本和运维管理成本。
  • 配置复杂:两个环境需保持一致的配置,包括服务器设置、网络配置、数据库连接等,配置管理难度大,任何细微差异都可能导致发布问题。

二、镜像准备

 假设有如下三个节点的 K8S 集群:

k8s31master 是控制节点

k8s31node1、k8s31node2 是工作节点

容器运行时是 containerd

使用 springboot 打包两个镜像 hellok8s-1.0.jar.gz 和 hellok8s-2.0.jar.gz。

hellok8s:1.0

@RestController
public class HelloController {

    @GetMapping("/sayHello")
    @ResponseBody
    public String sayHello() {
        # 蓝
        return "Hello,I am Blue";
    }
}

hellok8s:2.0

@RestController
public class HelloController {

    @GetMapping("/sayHello")
    @ResponseBody
    public String sayHello() {
        # 绿
        return "Hello,I am Green";
    }
}

它们的区别仅在输出的问候信息不同,一个 Blue、一个 Green.

  •  导入镜像
# node1 执行
[root@k8s31node1 ~]# ctr -n=k8s.io images import hellok8s-1.0.jar.gz
[root@k8s31node1 ~]# ctr -n=k8s.io images import hellok8s-2.0.jar.gz
# node2 执行
[root@k8s31node2 ~]# ctr -n=k8s.io images import hellok8s-1.0.jar.gz
[root@k8s31node2 ~]# ctr -n=k8s.io images import hellok8s-2.0.jar.gz

三、Deployment 实现

我们用 Service 代替网关,来实现一个 绿 发布。

3.1、部署 1.0 “”环境

假设现在有 1.0 版本的 deploy-blue.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-blue
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hellok8s
      version: "1.0"
  template:
    metadata:
      labels:
        app: hellok8s
        version: "1.0"
    spec:
      containers:
      - name: hellok8s
        image: hellok8s:1.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
        startupProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10

  • selector.matchLabels 要与 template.metadata.labels 相匹配。
  • 镜像版本是 1.0
  • 运行并查看
kubectl apply -f deploy-blue.yaml
kubectl get deploy
kubectl get rs
kubectl get pod -owide

 3.2、部署 2.0 “绿”环境

deploy-green.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-green
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hellok8s
      version: "2.0"
  template:
    metadata:
      labels:
        app: hellok8s
        version: "2.0"
    spec:
      containers:
      - name: hellok8s
        image: hellok8s:2.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
        startupProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
  •  运行并查看
kubectl apply -f deploy-green.yaml
kubectl get deploy
kubectl get rs
kubectl get pod -owide

 3.3、暴露服务

假设当前是“”环境服务用户请求。

  • 编写 service

service-blue-green.yaml

apiVersion: v1
kind: Service
metadata: 
  name: svc-blue-green
spec:
  type: NodePort
  ports:
  - port: 80
    nodePort: 32181
    targetPort: 8080
  selector:
    app: hellok8s
    version: "1.0"
  • NodePort:以节点端口的方式暴露服务。
  • port:service 暴露的服务端口。
  • targetPort:容器端口(1 to 65535)。
  • nodePort:节点端口(default: 30000-32767)。
  • selector:标签选择器。选择想要暴露服务的 pod 的 labels。
  • 运行并查看
kubectl apply -f service-blue-green.yaml
kubectl get svc

  •  以 节点IP:端口 访问接口

可以看到,service 返回的是 Blue 1.0 版本的接口。

部署结构图如下:​

  • 当用户访问 master、node1、node2 的 32181 端口时,流量会被导到 service 的 80 端口。
  • service 的 80 端口,代理的就是 app: hellok8s,version: "1.0" 的三个 pod:deploy-blue-d96bd64f7-btrzv、deploy-blue-d96bd64f7-vc7d2、deploy-blue-d96bd64f7-w64ml

 3.4、切换流量

假设现在运营测试人员已在 “绿”环境验证完 2.0 的应用功能,需要将 2.0 切换给用户使用。

  • 修改 service-blue-green.yaml,将 1.0 修改为 2.0

version: "2.0"

  •  更新 service
kubectl apply -f service-blue-green.yaml
  •  以 节点IP:端口 访问接口

 可以看到,服务版本,已经切换为 Green。

从这边我们也可以看出,这种部署方式,对于用户是无感知的,

用户一直只需要用 nodeIp:nodePort/path 的方式访问,而应用的版本,已经从 1.0 被切换为 2.0。

3.5、版本回退

版本回退的过程跟切换流量是一样的,只不过把 version: "2.0" 改为 version: "1.0",并重新更新 service。这里就不再演示了。


http://www.kler.cn/a/534223.html

相关文章:

  • 【Origin笔记-2】降水量变化趋势单位理解
  • 【算法】动态规划专题④ ——LCS(最长公共子序列)+ LPS(最长回文子序列) python
  • 留学生编程辅导Haskell/OCaml/Prolog/Rust/Python
  • 计算机网络——三种交换技术
  • 【PyQt】pyqt小案例实现简易文本编辑器
  • SQL Server中RANK()函数:处理并列排名与自然跳号
  • 关于19C的审计日志
  • 试试DeepSeek写prompt+stable diffusion生成漫画
  • 【蓝桥杯嵌入式】2_LED
  • 汽车加气站操作工试题及答案​
  • 前端组件标准化专家Prompt指令的最佳实践
  • VulnHub | Prime - 1
  • Ollama AI 开发助手完全指南:从入门到实践
  • C++常用拷贝和替换算法
  • FastAPI与Selenium:打造高效的Web数据抓取服务
  • 【Rancher】简化Kubernetes容器管理与部署的开源平台
  • AlwaysOn 可用性组副本所在服务器以及该副本上数据库的各项状态信息
  • kamailio-osp模块
  • 洛谷P2789 直线交点数
  • 除了 Python,还有哪些语言可以调用淘宝 API?
  • 深度学习系列--02.损失函数
  • k8m 是一款轻量级、跨平台的 Kubernetes 仪表板
  • RabbitMQ:python基础调用
  • DS图(中)(19)
  • 【分布式架构理论2】分布式架构要处理的问题及解决方案
  • 【自然语言处理(NLP)】Bahdanau 注意力(Bahdanau Attention)原理及代码实现