Kubernetes容器化技术之蓝绿发布

举报
tea_year 发表于 2024/12/30 21:56:42 2024/12/30
【摘要】 蓝绿发布是一种通过Kubernetes实现的零停机部署策略,旨在提高系统的稳定性和可用性。此策略涉及同时运行两个生产环境版本(即蓝色环境和绿色环境),在蓝色环境运行当前稳定版本的同时,绿色环境部署新版本应用。通过逐步将流量从蓝色环境切换到绿色环境,确保新版本的稳定性。如果新版本表现不佳,可以快速回滚至旧版本,保证业务不中断。这种发布方式在Kubernetes中尤为重要,因为其自动化和灵活性有...

蓝绿发布是一种通过Kubernetes实现的零停机部署策略,旨在提高系统的稳定性和可用性。此策略涉及同时运行两个生产环境版本(即蓝色环境和绿色环境),在蓝色环境运行当前稳定版本的同时,绿色环境部署新版本应用。通过逐步将流量从蓝色环境切换到绿色环境,确保新版本的稳定性。如果新版本表现不佳,可以快速回滚至旧版本,保证业务不中断。这种发布方式在Kubernetes中尤为重要,因为其自动化和灵活性有助于减少人为错误,提高效率。


一、概述

在下面这张架构图中,我们对同一个应用部署了两个版本的环境,称之为蓝绿环境,流量通过 Ingress-Nginx 进入到 Service,然后再由它将流量转发至 Pod。在没有切换流量之前,蓝色环境负责接收外部请求流量。

 

 

Snipaste_2024-12-30_21-38-07.png

 

需要进行流量切换时,只要调整 Ingress 策略就可以让绿色环境接收外部流量,如下图所示。

 

2.png

 

二、实战

接下来,我们通过一个例子来说明如何使用 Kubernetes 原生的Deployment Service 来进行蓝绿发布,实战过程主要包含下面几个步骤。

  1. 创建蓝色环境的 Deployment Service
  2. 创建 Ingress 策略,并指向蓝色环境的 Service
  3. 访问蓝色环境。
  4. 创建绿色环境的 Deployment Service
  5. 更新 Ingress 策略,并指向绿色环境。
  6. 访问绿色环境。

 

实验过程:

  1. 创建蓝色环境的 Deployment Service

YAML
apiVersion: apps/v1
kind: Deployment
metadata:
  name: blue
  labels:
    app: blue
spec:
  replicas: 3
  selector:
    matchLabels:
      app: blue
  template:
    metadata:
      labels:
        app: blue
    spec:
      containers:
      - name: blue-demo
        image: reg.xinxianghf.cloud/library/rollouts-demo:blue
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: blue-svc
  labels:
    app: blue
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
  selector:
    app: blue
  type: ClusterIP

 

2.创建 Ingress 策略,并指向蓝色环境的 Service

YAML
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: app.xinxianghf.cloud
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: blue-svc
            port:
              number: 80

 

3.部署应用 访问蓝色环境。

YAML
[root@master-01 blue-green]# kubectl  apply -f blue-dep.yaml  
deployment.apps/blue created
service/blue-svc created
[root@master-01 blue-green]# kubectl  apply -f app-ingress.yaml
ingress.networking.k8s.io/app-ingress created
[root@master-01 blue-green]#
[root@master-01 blue-green]# kubectl  get pods
NAME                    READY   STATUS    RESTARTS   AGE
blue-59fcd7f57f-dqwjh   1/1     Running   0          14s
blue-59fcd7f57f-ltztl   1/1     Running   0          14s
blue-59fcd7f57f-xrgsr   1/1     Running   0          14s
[root@master-01 blue-green]#
[root@master-01 blue-green]# kubectl  get svc
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
blue-svc       ClusterIP   10.105.137.138   <none>        80/TCP         20s
[root@master-01 blue-green]#
[root@master-01 blue-green]# kubectl  get ingress
NAME           CLASS   HOSTS                  ADDRESS   PORTS   AGE
demo-ingress   nginx   app.xinxianghf.cloud             80      22s

修改 hosts 文件

 访问 ingress 配置的域名地址  app.xinxianghf.cloud:30081

YAML
[root@master-01 nfs-provisioner]# kubectl  get ingress
NAME           CLASS   HOSTS                  ADDRESS   PORTS   AGE
demo-ingress   nginx   app.xinxianghf.cloud             80      3m57s

[root@master-01 nfs-provisioner]# kubectl  -n ingress-nginx  get svc
NAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.110.247.106   <none>        80:30081/TCP,443:30443/TCP   11m

 

3.png

4.创建绿色环境的 Deployment Service

YAML
apiVersion: apps/v1
kind: Deployment
metadata:
  name: green
  labels:
    app: green
spec:
  replicas: 3
  selector:
    matchLabels:
      app: green
  template:
    metadata:
      labels:
        app: green
    spec:
      containers:
      - name: green-demo
        image: reg.xinxianghf.cloud/library/rollouts-demo:green
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: green-svc
  labels:
    app: green
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
  selector:
    app: green
  type: ClusterIP

 

5.更新 Ingress 策略,并指向绿色环境。

YAML
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: app.xinxianghf.cloud
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: green-svc
            port:
              number: 80

 

6.访问绿色环境。

YAML
[root@master-01 blue-green]# kubectl apply -f green-dep.yaml
deployment.apps/green created
service/green-svc created
[root@master-01 blue-green]#
[root@master-01 blue-green]# kubectl apply -f app-ingress-green.yaml
ingress.networking.k8s.io/app-ingress created

 

4.png

三、金丝雀发布/灰度发布

   在下面这张架构图中,我们会对同一个应用部署两套环境,一套是 Prod 生产环境,另一套是Canary 金丝雀环境。这两套环境分别由不同的 Service 通过标签选择器进行关联,最外层通过Ingress-Nginx 网关将流量按不同的比例转发到 Service 当中。比如,图中 20% 的流量将会转发到金丝雀环境,80% 的流量会转发到生产环境,这实际上是一种流量负载均衡的算法。

5.png

实战

接下来,我们会通过一个例子来说明如何使用 Kubernetes 原生的 Deployment Service 来进行金丝雀发布,实战过程主要包含下面几个步骤。

  1. 创建生产环境的 Deployment Service
  2. 创建生产环境 Ingress 策略,并指向生产环境的 Service
  3. 访问生产环境。
  4. 创建金丝雀环境的 Deployment Service
  5. 创建金丝雀环境 Ingress 策略,并实现按比例分发和识别特殊流量分发。
  6. 访问生产环境。

实验过程

  1. 创建生产环境的 Deployment Service

YAML
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prod
  labels:
    app: prod
spec:
  replicas: 3
  selector:
    matchLabels:
      app: prod
  template:
    metadata:
      labels:
        app: prod
    spec:
      containers:
      - name: prod-demo
        image: reg.xinxianghf.cloud/library/rollouts-demo:blue
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: prod-svc
  labels:
    app: prod
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
  selector:
    app: prod
  type: ClusterIP

 

2.创建生产环境 Ingress 策略,并指向生产环境的 Service

YAML
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: prod-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: canary.xinxianghf.cloud
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: prod-svc
            port:
              number: 80

 

 

3.访问生产环境。

YAML
[root@master-01 canary]# kubectl apply -f prod-dep.yaml  -f prod-ingress.yaml
deployment.apps/prod created
service/prod-svc created
ingress.networking.k8s.io/prod-ingress created

[root@master-01 canary]# kubectl  get ingress
NAME           CLASS   HOSTS                     ADDRESS          PORTS   AGE
prod-ingress   nginx   canary.xinxianghf.cloud   10.110.247.106   80      36s
[root@master-01 canary]#
[root@master-01 canary]# kubectl  -n ingress-nginx  get svc
NAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.110.247.106   <none>        80:30081/TCP,443:30443/TCP   62m
ingress-nginx-controller-admission   ClusterIP   10.107.56.194    <none>        443/TCP                      62m

修改 hosts 文件

访问  canary.xinxianghf.cloud:30081

6.png

4.创建金丝雀环境的 Deployment Service

YAML
apiVersion: apps/v1
kind: Deployment
metadata:
  name: canary
  labels:
    app: canary
spec:
  replicas: 3
  selector:
    matchLabels:
      app: canary
  template:
    metadata:
      labels:
        app: canary
    spec:
      containers:
      - name: canary-demo
        image: reg.xinxianghf.cloud/library/rollouts-demo:green
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: canary-svc
  labels:
    app: canary
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
  selector:
    app: canary
  type: ClusterIP

 

5.创建金丝雀环境 Ingress 策略,并实现按比例分发和识别特殊流量分发。

YAML
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: canary-ingress-canary
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "20"
    nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"  
spec:
  ingressClassName: nginx
  rules:
  - host: canary.xinxianghf.cloud
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: canary-svc
            port:
              number: 80

nginx.ingress.kubernetes.io/canary 字段的值为 true,表示启用金丝雀发布策略。

nginx.ingress.kubernetes.io/canary-weight 字段的值为 20,表示将 20% 的流量转发到金丝雀环境当中,这是负载均衡的加权轮询机制。

nginx.ingress.kubernetes.io/canary-by-header 字段的值为 X-Canary,代表当 Header 中包含 X-Canary 时,则无视流量比例规则,将请求直接转发到金丝雀环境中。

上面的 Ingress 策略实际上同时配置了基于请求流量比例以及请求头的金丝雀策略。

 

6.访问生产环境。

YAML
[root@master-01 canary]# kubectl apply -f canary-dep.yaml  -f canary-ingress.yaml
deployment.apps/canary created
service/canary-svc created
ingress.networking.k8s.io/canary-ingress-canary created

  

7.png

调整权重为 50,再做查看。

8.png

 

最终把权重调为100,就完成了一次金丝雀发布过程。

 总结:

1. 高可用性

1.1 蓝绿发布通过同时运行蓝色和绿色两个环境,确保在任何情况下都有一个稳定版本对外提供服务。即使新版本出现问题,也可以立即切换回蓝色环境,保证业务的连续性。 1.2 在流量切换过程中,可以利用少量的流量先期进行A/B测试,通过逐步放量降低风险。一旦新版本表现不稳定,可以快速回滚,避免对用户造成影响。

2. 风险控制

2.1 蓝绿发布的核心优势在于其流量切换过程是逐步进行的,这意味着任何新版本的问题都可以在初期被发现并处理,避免了大量用户受到影响。 2.2 通过在绿色环境中进行充分的测试和验证,确保新版本的稳定性和兼容性。只有当新版本通过一系列严格的检查后,才会将更多的流量导入绿色环境。

3. 部署效率提升

3.1 蓝绿发布策略使得部署过程高度自动化,通过Kubernetes的清单文件管理和流量切换策略,减少了手动操作的需求,提高了工作效率。 3.2 整个部署过程无需停机,避免了传统发布方式中因停机导致业务中断的风险,提升了系统的可用性和用户体验。

4. 灵活的回滚机制

4.1 蓝绿发布提供了一种安全的回滚机制,通过简单的流量切换,可以立即将新版本中的问题版本替换为前一个稳定版本,确保业务不中断。 4.2 在新版本发布过程中,如果发现任何不可预见的问题,蓝绿发布允许快速回滚到上一个稳定版本,提供了极大的部署保障。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。