Kubernetes容器化技术之蓝绿发布

举报
人工智能-张晨光 发表于 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个月内不可修改。