在现代化应用技术领域中,容器编排平台简化了针对基于微服务应用的基础架构配置,并通过模块化实现了高效的工作负载的管理。而作为一个被广泛采用的、能够支持多种部署资源的平台,Kubernetes更是方便了企业大规模地以CI/CD管道的方式,部署和管理各类应用程序。虽然Kubernetes提供了滚动更新(rolling updates)作为默认的部署策略,但是某些用例则需要使用非常规的方法,来部署或更新集群中的各项服务。下面,我们将在回顾Kubernetes基本部署概念的基础上,深入探讨各种高级的Kubernetes部署策略、它们的优缺点、及其用例。
Kubernetes的部署概念
在部署过程中,集群管理员可以自定义应用程序的生命周期,以及执行更新的方式。而Kubernetes通常会使用部署资源,并以声明的方式去更新各类应用程序。它的这种自动化部署方式,实现并维护了各个集群对象及应用程序的所需状态。而且,其后端无需人工干预,即可以一种安全且可重复的方式,来执行应用程序的更新。也就是说,Kubernetes的部署可以协助集群管理员实现:
部署单个pod或副本集更新一组pod或副本集回滚到早期的版本暂停或继续部署扩展各种部署
下面,我们将探讨Kubernetes是如何简化容器化应用的更新过程,以及它将如何应对持续交付的挑战。
Kubernetes对象
虽然Kubernetes可以利用许多种工作负载资源对象,作为持久实体,去管理集群的状态,但Kubernetes API通常会使用Deployment(部署)、ReplicaSet(副本集)、StatefulSet(有状态集)和DaemonSet(守护程序集)四种资源,对应用程序进行声明式更新。下面我们来具体看看这四种资源的特点:
Deployment
作为一种Kubernetes资源,Deployment可用于定义和识别应用程序所需的状态。集群管理员在Deployment的YAML文件中通过描述预期的状态,以便部署控制器,并据此将实际状态逐渐更改为预期的状态。而为了确保高可用性,部署控制器还会通过持续监控,按需将健康的集群节点和pod,去替换那些失败的集群节点和pod。
ReplicaSet
ReplicaSet可用于维护特定数量的pod,以确保其高可用性。ReplicaSet的清单文件会包括如下字段:
用于识别隶属于某个集合的pod选择器通过副本数,来表示集合中应该有多少个pod通过一个pod模板,来显示新的pod应创建哪些数据,以满足副本集的标准StatefulSet
StatefulSet对象可以管理某个有状态的应用程序中的pod部署与扩展。该资源会基于相同的容器规范,去管理pod,并确保整组pod的唯一性、以及排列有序。StatefulSet的持久性pod标识符,能够方便集群管理员将其工作负载连接到具有高可用性的持久性存储卷上。
DaemonSet
DaemonSet通过确保一组节点运行在某个pod的副本上,来协助维护应用程序的部署。DaemonSet资源主要被用于管理各种代理的部署和生命周期中,例如:
每个节点上的各个集群存储代理日志收集的守护进程节点监控的守护进程
您也可以通过链接--https://kubernetes.io/docs/concepts/workloads/controllers/,查看更多有关各种Kubernetes工作负载资源的列表,及其详细信息。
使用部署更新
Kubernetes的部署提供了一种可预测的方法,来启动和停止pod。有了这些资源,我们可以轻松地实施部署、回滚更改、以及以自主迭代式管理软件的发布周期。目前,Kubernetes通过提供各种部署策略,来实现更小、更频繁的更新,并为应用提供如下优势:
通过更快的客户反馈,以获得更好的功能性优化缩短面市时间提高DevOps团队的生产力
默认情况下,由Kubernetes提供的滚动式更新,可作为其标准的部署策略,实现一次性将新的版本去替换某个旧的pod,以避免集群的停机。此外,根据功能性的目标和类型的不同,Kubernetes还支持包括蓝绿、金丝雀和A/B部署在内,各种高级部署策略。下面,让我们来详细讨论这些策略的特点,及其优缺点。
Kubernetes部署的高级策略
部署配置与路由功能的结合使用,能够方便发布团队在提交完整版本之前,在实时的生产环境中,测试新功能的有效性。为此,开发人员可以利用Kubernetes所支持的高级部署策略,来精确地控制特定版本的质量。当然,具体应当采取何种Kubernetes的部署方式,去发布应用程序的更新和新功能,则取决于实际用例和工作负载。
蓝绿部署
在蓝绿策略中,应用程序的新旧实例会被同时部署。在用户可以持续访问现有版本(蓝色)的同时,具有相同数量的新版本(绿色)实例可供站点可靠性工程师(site reliability engineering,SRE)和QA团队使用。一旦QA团队确认了绿色版本已通过所有测试要求,用户就会被重定向到新的版本上。这往往是通过更新负载均衡服务上selector字段中的version标签来实现的。通常,当开发人员想要避免出现版本控制问题时,蓝绿部署就非常适用。
使用蓝绿部署策略
让我们假设某个应用程序的第一个版为v1.0.0,而可用的第二个版是v2.0.0。那么如下代码段便是指向第一个版本的服务:
apiVersion: v1
kind: Service
metadata:
name: darwin-service-a
spec:
type: LoadBalancer
selector:
app: nginx
version: v1.0.0
ports:
- name: http
port: 80
targetPort: 80
而下面是指向第二个版本的服务:
apiVersion: v1
kind: Service
metadata:
name: darwin-service-b
spec:
type: LoadBalancer
selector:
app: nginx
version: v2.0.0
ports:
- name: http
port: 80
targetPort: http
一旦我们完成了必要的测试,并批准了第二个版本,那么指向第一个服务的selector就需要更改为v2.0.0:
apiVersion: v1
kind: Service
metadata:
name: darwin-service-a
spec:
type: LoadBalancer
selector:
app: nginx
version: v2.0.0
ports:
- name: http
port: 80
targetPort: http
如果新版本的应用程序能够按预期运行,那么v1.0.0版就可以“下线”了。
金丝雀部署
在金丝雀策略中,一部分用户会被路由到承载了新版本的pod上。该用户群会逐渐增加,而连接到旧版本的群体则会相应减少。该策略可用于比较使用着两个版本的用户集合的体验。如果未检测到错误,我们则可以将新版本推送给遗留在旧版本上的用户。
使用金丝雀部署策略
原生的Kubernetes金丝雀部署的过程包含如下步骤:
1. 通过以下方式部署运行版本1所需的副本:
部署第一个应用程序:
$ kubectl apply -f darwin-v1.yaml
将其扩展至所需的副本数量:
$ kubectl scale --replicas=9 deploy darwin-v1
2.部署版本2的实例:
$ kubectl apply -f darwin-v2.yaml
3.测试版本2是否已部署成功:
$ service=$(minikube service darwin --url)
$ while sleep 0.1; do curl "$service"; done
4.如果部署成功,则扩展版本2的实例数量:
$ kubectl scale --replicas=10 deploy darwin-v2
5.一旦所有副本都上线,您就可以“优雅地”删除版本1了:
$ kubectl delete deploy darwin-v1A/B部署
通过A/B部署,管理员可以将特定的用户子集,路由到具有某些限制和/或条件的新版本上。此类部署主要被用于评估用户群对某些新功能的反响。由于用户在测试期间并不知晓自己已被呈现了新的功能,因此A/B部署有时也被称为“暗启动”。
使用A/B部署策略
以下是对Istio服务网格执行A/B测试的方法示例。它将有助于使用流量权重(traffic weight)来推出不同的版本:
1.假设集群上已经安装了Istio,那么我们首先需要部署两个版本的应用:
$ kubectl apply -f darwin-v1.yaml -f darwin-v2.yaml
2. 然后,我们可以通过Istio网关去发布两个版本,并使用如下命令,将请求匹配到第一个服务上:
$ kubectl apply -f ./gateway.yaml -f ./virtualservice.yaml
3.接着,我们可以使用如下命令,根据权重来应用Istio的VirtualService规则:
$ kubectl apply -f ./virtualservice-weight.yaml
它会以1:10的比例,在版本之间分配流量的权重。为了转移流量的权重,我们可以编辑每个服务的权重,然后通过Kubernetes CLI去更新VirtualService规则。
每种高级部署策略的适用场景
由于Kubernetes用例会因可用性要求、预算限制、可用资源和其他考虑因素而异,因此目前并不存在一种万能的部署策略。您在选择部署策略时,需要考虑以下表格:
Kubernetes部署策略比较
小结
借助各种部署资源,Kubernetes管理员可以通过建立高效的版本控制系统,来更新pod,回滚到早期版本、或扩展基础架构,以满足不断增长的工作负载,并通过管理应用的不同版本,来最小化停机时间。
上文介绍的各种Kubernetes高级部署策略,能够在一定程度上方便管理员将流量和请求路由到特定的版本上,从而在真实的测试环境中处理各种错误。同时,这些策略也常被用于,在管理员和开发人员完全提交更改之前,检验新的功能是否能够按照原定计划运行,以及通过充分的回滚选项,实现多种松散的耦合服务,进而实现应用更新和功能上的快速交付。当然,具体该如何选择,还需要您根据实际的应用环境,参照上述比较表,做出选择。
其他可参考资源使用kubectl创建部署Kubernetes的各种部署用例Kubernetes部署生命周期的不同状态译者介绍
陈峻 (Julian Chen),51CTO社区编辑,具有十多年的IT项目实施经验,善于对内外部资源与风险实施管控,专注传播网络与信息安全知识与经验;持续以博文、专题和译文等形式,分享前沿技术与新知;经常以线上、线下等方式,开展信息安全类培训与授课。
原文标题:Advanced Kubernetes Deployment Strategies,作者:Sudip Sengupta