一、概述
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工具。