k8s灰度发布(灰度发布的实现)

一、概述

k8s(Kubernetes)是现代化的分布式系统,用于容器化应用程序的自动部署,管理和扩展,它提供了一种容器编排平台。灰度发布是指在生产环境中,逐步将新版本应用程序的流量从旧版本中划分出来,以便更好地测试和评估,并将生产环境的中断率最小化。k8s提供了许多工具来帮助您进行灰度发布。

二、k8s中的灰度发布实现方式

k8s中有多种实现灰度发布的方式。下面介绍两种常见的方式。

1、基于标签的灰度发布

基于标签的灰度发布是最广泛使用的一种方式。您可以使用Pod模板和服务机制在k8s上对应用程序进行灰度发布。

先创建一个Deployment,如下所示:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-world
      release: canary # 上传canary版本镜像并创建标签
  template:
    metadata:
      labels:
        app: hello-world
        release: canary # 上传canary版本镜像并创建标签
    spec:
      containers:
        - name: hello-world
          image: hello-world:canary # 使用canary版本
          ports:
            - containerPort: 80
              name: http

这个Deployment创建了一个hello-world服务的canary版本。然后,您可以通过创建一个标签选择器,将流量转移到这个版本。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: hello-world-ingress
spec:
  rules:
    - host: hello-world.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: hello-world
                port:
                  name: http
                annotations:
                  nginx.ingress.kubernetes.io/canary: "true"  # 标记此为canary版本,引导流量

这个Ingress创建了一个名为hello-world的服务,并标记为canary版本,以便使用nginx-ingress-controller的canary功能将20%的流量发送到canary版本的hello-world服务上。

然后,您可以滚动更新这个Deployment。

kubectl set image deployment/hello-world hello-world=hello-world:v1.1 --selector=release=canary

这个命令使用hello-world:v1.1替换所有标签中的hello-world映像。默认情况下,k8s使用滚动更新来确保在流量转移期间不会发生中断。

2、蓝绿部署

蓝绿部署是另一种流行的方法。蓝绿部署是指在生产环境中创建一个完全相同的集群,其中新版本可以得到验证和测试,然后可以迅速地将流量切换到新版本,以便扩展和可靠性测试。

下面是一个示例,使用HPA区分生产和测试环境:

首先,在k8s中创建一个新的Deployment来托管应用程序,如下所示:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world-test
  labels:
    app: hello-world-test
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-world-test
  template:
    metadata:
      labels:
        app: hello-world-test
    spec:
      containers:
        - name: hello-world-test
          image: hello-world
          ports:
            - containerPort: 80
              name: http

这个Deployment当前没有标签。然后我们创建另一个Deployment,来承载生产环境:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world-prod
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-world-prod
  template:
    metadata:
      labels:
        app: hello-world-prod
    spec:
      containers:
        - name: hello-world-prod
          image: hello-world:v1.0
          ports:
            - containerPort: 80
              name: http
              protocol: TCP
          resources:
            requests:
              cpu: 50m
              memory: 64Mi # 每个实例最小的内存要求

这个Deployment托管生产环境的hello-world应用程序,并标记为”app=hello-world-prod”。

现在,我们要将蓝色环境转换为绿色环境,并通过部署绿色环境来覆盖所有的蓝色环境。我们要使用HPA HPA做到这一点,HPA根据负载调整Pod数量。我们使用下面的命令为生产环境创建一个HPA:

kubectl autoscale deployment hello-world-prod --cpu-percent=50 --min=3 --max=10

这个命令使用cpu-percent来为hello-world-prod服务创建一个水平自动缩放器。它会监视hello-world-prod服务中Pod的CPU使用率,如果CPU使用率超过50%,它就会自动调整Pod数量,使其最少为3个,最多为10个。

现在,我们可以将两个Deployment中的Pod数量配置成相同的:

kubectl scale deployment hello-world-prod --replicas=3
kubectl scale deployment hello-world-test --replicas=3

然后,我们将Ingress路由到hello-world-prod服务:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: blue-green-ingress
spec:
  rules:
    - host: hello-world.example.com
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: hello-world-prod
              port:
                name: http

我们现在已经有了两个完全相同的环境,每个环境都处理了50%的流量。我们将下一个版本的应用程序部署到另一个Deployment中:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world-new
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-world-new
  template:
    metadata:
      labels:
        app: hello-world-new
    spec:
      containers:
        - name: hello-world-new
          image: hello-world:v1.1
          ports:
            - containerPort: 80
              name: http

一旦新环境准备好,我们可以将Ingress路由到新服务,然后使用HPA逐渐升级新服务的流量百分比:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: blue-green-ingress
spec:
  rules:
    - host: hello-world.example.com
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: hello-world-new
              port:
                name: http
kubectl autoscale deployment hello-world-new --cpu-percent=50 --min=1 --max=10

现在,我们可以使用下面的命令逐步增加hello-world-new服务的流量百分比:

kubectl patch ingress blue-green-ingress -p '{"metadata":{"annotations":{"nginx.ingress.kubernetes.io/canary":"true","nginx.ingress.kubernetes.io/canary-by":"header"}},"spec":{"rules":[{"host":"hello-world.example.com","http":{"paths":[{"backend":{"service":{"name":"hello-world-prod","port":{"name":"http"}}},"path":"/","pathType":"Prefix"}]}}]},"status":{}}'

这个命令使用nginx-ingress-controller的canary功能以10%的流量将流量发送到hello-world-new服务上。如果您需要使用其他百分比,请相应地调整canary配置。最终将流量100%转移到新环境,然后将旧应用程序的Pod数量缩小到零。

三、灰度发布的优缺点

1、优点

灰度发布的主要优点是,它可以极大地减少生产环境的中断率。当您在生产环境中进行部署时,您可能会遇到许多与性能或错误有关的问题。灰度发布使您可以测试新版本的应用程序,以便您可以检测到和解决这些问题,在完全部署之前,只有一部分的流量会发送到新应用程序。

此外,灰度发布还可以允许您大规模滚动回滚策略。如果在完全部署期间遇到问题,则可以快速回滚到旧版本,而不会对客户产生任何影响。

2、缺点

灰度发布的主要缺点是它需要更多的工作量。您需要编写额外的脚本和配置,以确保正确地设置灰度发布流程。此外,灰度发布需要您具备更高的技术水平,以便更好地理解和使用k8s和相关工具。最后,灰度发布可能会增加部署的时间,因为您需要先部署并测试新应用程序,然后才能将其广泛部署到生产环境中。

四、总结

本文详细介绍了k8s中两种灰度发布方式:基于标签的灰度发布和蓝绿部署。灰度发布可以在保证生产环境安全的前提下,将新应用程序逐步发送到生产环境中,以减少中断率和测试新版本应用程序的性能,同时也存在一些缺点。在灰度发布过程中,您需要花费更多的精力和技术水平,以更好地理解和使用相关的k8s工具。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注