为云栖社区总监课系列准备的课件讲义,面向开发者入门向讲解云原生的一些实践经验和发展方向。
容器技术的发展揭开了云原生计算的序幕:
首先是应用的容器化,Heroku/CloudFoundry 等PaaS平台基于容器技术构建,极大地简化了Web应用的部署运维。Docker提出了容器应用打包规范 Docker Image,并建立Docker Hub进行全球应用分发和协作,极大推动了容器的技术普及,并让容器应用到更多的业务场景中。Open Container Initiative, Containerd等社区进一步推动了容器技术的标准化和规范化。
之后是容器的编排调度,开发者希望通过容器技术对底层资源进行优化组合和高效调度,提升系统利用率、应用SLA和自动化水平。Kubernetes因为其优秀地开放性,可扩展性和活跃的社区,在竞争中脱颖而出。Google把Kubernetes捐赠给CNCF之后,加速了其普及。
随着容器以及容器编排标准化的逐渐建立,Kubernetes/Docker屏蔽了底层基础架构的差异,提供了良好的可移植性可以支撑多云/混合云。社区开始基于此建立上层的业务抽象。首先是服务治理层,2018年是Service Mesh服务网格的元年, Istio是Google/IBM/Lyft推出的服务治理平台。一个类比云原生时代的微服务之间的网络协议栈,我们可以通过Istio实现服务调用的动态路由,限流、降级、全链路追踪、安全传输等工作而无需在应用层进行处理。在此之上,面向领域的云原生框架也在迅速出现,比如面向机器学习的云原生平台Kubeflow,和面向无服务器的Knative等等。通过这样的架构分层,开发者只需关注自身的业务逻辑,而无需关注底层实现的复杂性。
我们可以看到一个云原生操作系统的雏形开始出现。这是开发者最好的时代,云基础设施和云原生计算技术极大地提升了业务创新的速度。
为了解决互联网规模应用的挑战,我们开始采用分布式技术来构建应用。然而在构建分布式系统应用时,我们经常会做出一些假设,但在长期运行过程中这些假设被证明是不准确的甚至是错误的。Peter Deutsch总结了常见的“分布式系统的误区”。主要有以下几个方面:
- 网络是可靠的:任何组件和基础设施都会发生故障,当规模足够大时这将成为必然
- 可忽略的延迟、宽带是无限的:当业务高峰时,网络资源不足会导致系统稳定性下降,今年双十一就有两个朋友电话求助,应对由网络打满导致的系统雪崩。
- 网络是安全的
- 拓扑结构不会发生变化
- 只有一个管理员
- 传输的代价是零
- 网络是同构的
为了解决互联网规模应用的挑战,我们一直在不断地讨论如何从单体应用程序向分布式的微服务架构进行转型。基于Netflix OSS项目的Spring Cloud,阿里集团开源的Apache Dubbo,都是微服务框架的佼佼者。
当前的微服务架构的实现往往是以代码库的方式构建在应用程序内部,这些代码库中包括了服务发现、熔断、限流等这样的一些功能,代码库的方式不但会引入潜在的版本冲突问题,而且一旦代码库变更,整个应用也要随之全部构建变更,即使应用逻辑并没有任何变化。
此外,企业组织和复杂系统中的微服务经常会使用到不同的编程语言和框架实现,针对异构环境的服务治理代码库实现往往存在差异、缺少共性问题的统一解决方案。
为了解决上述问题,社区开始推动Service Mesh服务网格技术。
Istio, Linkerd 作为服务网格技术的代表作,他们通过sidecar代理拦截了微服务之间的所有网络通信,用统一方式实现服务之间的负载均衡、访问控制、速率限制等功能。应用无需对底层服务访问细节感知,sidecar和应用可以独立升级,实现了应用逻辑跟服务治理能力的解耦。
可以将微服务之间的服务连接基础设施层和TCP/IP协议栈进行类比。TCP/IP协议栈为操作系统中的所有应用提供基础通信服务,但TCP/IP协议栈和应用程序之间并没有紧密的耦合关系,应用只需利用TCP/IP协议提供的底层通讯功能,无需不关心TCP/IP协议的具体实现,如IP如何进行路由,TCP如何创建链接,进行拥塞管理等。服务网格的目标就是提供实现无关的服务通信基础协议栈,
这张图是Istio的架构,逻辑上分为数据平面和控制平面。
数据平面由以 sidecar 方式部署的智能代理负责拦截、处理服务进程之间通信。
控制平面包含:
- Pilot: 负责流量管理
- Mixer: 负责提供策略控制和遥测收集
- Citadel: 负责提供通信的安全保护
2018年是Service Mesh服务网格的元年,而Istio 的第一个生产可用版本1.0也在今年8月初发布。在Istio的社区中,我们也已经贡献了在阿里云上如何使用Istio的操作指南,帮助您快速上手。
在阿里云Kubernetes服务(ACK)控制台中,我们也提供了一键部署、开箱即用的功能,方便大家使用。你只需要勾选不同的功能项,就可以决定是否启用日志收集、度量展示等功能。
阿里云ACK上提供了Istio版本实现了和阿里云日志服务、云监控服务的深入整合,提升Istio在生产环境的可用性。
利用 Istio 服务网格,不但可以管理Kubernetes集群上面的Pod之间的访问流量,还可以和ECI(弹性容器实例)/Serverless Add-on集成,实现经典K8S节点和Serverless K8s Pod之间的网络通信。
通过 Mesh Expansion混合部署能力,还可以统一管理现有虚拟机ECS和容器上面的应用负载之间的流量。这是一个重要的特性,可以帮助现有虚拟机上的应用,逐渐地迁移到容器平台上。
Istio 1.0之后提供了一个重要能力,可以创建跨K8s集群的服务网格,这可以在不同集群之间建立一个统一的服务治理层,可以解决混合云、灾备等多个场景。
Istio提供的端到端可观测性是一个重要能力,如果直接使用Jaeger的开源方案,在生产环境中会遇到众多的挑战。Jaeger底层存储依赖Cassandra集群,需要复杂的运维、调优和容量规划。阿里云容器服务提供了一个方案,可以基于日志服务SLS支持Jaeger的全链路分析,数据持久化层无需任何运维。
此外,在Istio官方Mixer Adapters中,我们也提供了阿里云云监控CMS的适配器,通过Adapter的简单配置可以很容易地把运行时的指标数据如请求次数等,发送给监控后端进行统一监控和告警。
Istio模块化的架构非常便于扩展,但是也带来了性能影响。我们在阿里云容器服务中针对Istio 1.0.2做了一个性能测试,使用了Istio社区的性能测试工具Fortio。
可以看到,在不启用Mixer的情况下,使用Istio的服务间调用QPS可达8500左右,响应时间90%都在10ms以内。在启用Mixer之后,QPS指标下降到3500,但是响应延迟没有发生变化。
Istio社区在性能优化部分也还在不断完善,譬如有些治理策略的执行逐渐从Mixer下沉到数据平面Envoy中去处理。如果您的应用对性能非常关注,也建议先使用Pilot提供的流量管理功能,暂时先不用开启Mixer。Istio 1.1版本会在年底发布,我们之后也会对它进行更好地性能测试。
安全生产面临的一大挑战是如何在不影响线上业务的情况下进行应用发布。我们知道事前无论进行了多么完善的测试,都无法保证发现所有潜在问题。我们必须能够进行安全、可控的版本发布,把故障影响控制在可以接受的范围内,并支持快速回滚。
最简单的应用发布方式就是重新发布,也就是先停掉老版本应用,再启动新版本应用。这会导致业务的中断,在生产环境中一般是无法接受的。
Kubernetes自带的 Deployment 提供了 rolling-update 滚动发布支持。这是一种渐进式的更新过程,逐渐从负载均衡服务后端摘除老版本实例并停止,同时启动新版本应用实例并添加到负载均衡后端。这可以实现无中断业务的应用发布。但是由于整个发布过程不可控制,一旦出现由于测试不够充分导致的问题,回滚整个应用代价比较高。
互联网公司大多采用更加可控的灰度发布方式。
首先是蓝/绿发布,新版本应用上线与老版本并存,新版本保持一样的资源,通过路由切部分流量到新版本中。这种方式稳定性非常好,回滚只是做路由切换即可,但是需要2倍的系统资源,不适合大规模的应用发布。
另外一种是金丝雀发布,我们逐渐发布一个新版本应用与老版本并存,开始规模比较小,比如10%,通过路由切部分流量到新版本应用中,如果一切正常就逐渐发布新版本,并把老版本逐渐下线,同时切更多流量到新版本,如果发现问题,只需要回滚部分应用即可。
我们可以看到,应用发布和路由管理是两个正交的事情,利用K8s我们可以实现发布过程的可控,ACK也提供了支持蓝绿、金丝雀发布方式。Istio提供了一个和发布方式无关的路由控制层,我们可以根据请求类型,移动设备/PC,地域灵活地切换应用版本。结合二者可以实现应用安全、可控地发布。
分布式系统存在高度复杂性,在基础设施、应用逻辑、运维流程的任何一个地方都可能存在稳定性风险导致业务系统的失效。
应对稳定性挑战,我们不能依赖“信佛祖,不宕机”,而是应该通过系统化的方法主动预防。
早在 2012 年,Netflix 提出了混沌工程(Chaos Engineering)的概念,并发布了一系列工具。Chaos Monkey在生产和测试环境随机杀死实例,目标测试系统的健壮性,训练后备人员,让恢复更简洁、快速、自动;Latency Monkey 让某台机器的请求或返回变慢,观察系统的表现; Chaos Gorilla 的能力是搞挂一个机房,宏观验证业务容灾和恢复的能力。混沌工程通过在生产、测试环境的分布式系统中实战检验,来验证、提升系统健壮性并持续优化流程。
阿里集团每年双十一大促的顺利成功也离不开背后系统化的稳定性演练,和整个电商平台的全链路压测。这需要对整个平台进行全方位的模拟,确保各个环节的性能、容量和稳定性均做到万无一失。其中几个关键点:
- 直接在生产环境进行全业务的压力测试;避免由于环境差异导致的测试不充分。
- 测试场景尽可能贴近真实业务场景:根据真实用户请求访问,构造测试数据。分布式压测平台可以产生模拟峰值的压力流量。
- 持续模拟故障的发生的场景,检验系统和团队的应对能力,提升自动化处理水平。
故障注入是混沌工程中经常用的一种手段。Istio可以支持2种不同的故障注入方式:一是中断故障注入,终止请求并向下游服务返回错误代码,模拟上游服务出错的状况,同时也支持用来指定中断请求的比例。第二个是时延故障注入,转发之前加入延迟,用于模拟网络故障、上游服务过载等故障。
流量镜像是指将实时流量的副本发送到镜像服务,用于验证测试。镜像流量发生在主服务的关键请求路径之外,比如在把 HTTP 请求转发给预期目标的同时,对流量进行镜像并发送给其他目标,通过这个方式我们可以将生产系统的真实数据和流量模型记录下来,可以用于生成模拟测试数据和计划,进行更加真实地全链路压测。
注意: 出于性能方面的考虑,Sidecar/Gateway 在返回预期目标的响应之前不会等待镜像目标的响应。
下面我们演示一个基于容器和服务网格的异地多活方案:
我们有一个积分兑换的微服务应用,部署在北京和张家口区域的2个K8s集群中,通过快速通道实现了网络互通,通过DTS实现数据库复制。整个系统的服务管理通过一个跨集群的高可用Istio服务网格完成。
在这个演示中,通过阿里云容器服务,我们可以方便地在不同地域K8S集群统一部署和管理应用,同时我们通过Istio服务网格实现了服务管理平面。一开始北京和张北集群同时对外提供服务,当北京集群无法访问时候,我们将切换所有服务调用到张家口区域,保证业务的连续性。
Kubeflow是谷歌牵头发起的一个基于Kubernetes支持机器学习的社区项目,可以通过云原生的方式支持不同的集群学习框架,管理从数据准备、模型训练、到模型预测的整个生命周期。
Arena是阿里云容器服务团队贡献到kubeflow社区的开源项目。用一个工具屏蔽所有底层细节,串联起深度学习流水线。今天我们重点介绍我们可以通过Service Mesh增强线上推理服务支持多模型多版本、灰度发布、精细化流控和弹性。
深度学习模型的持续优化是AI生产应用的重要挑战,比如电商平台,需要根据用户行为记录持续训练模型,才能更好地对用户偏好和消费热点进行有效地预测。同时一个新模型上线也需要一个安全可控的流程来验证新模型带来的改进。
通过arena命令,我们可以轻松实现模型训练,上线以及流量切换的模型持续优化全过程,由数据科学家通过arena submit提交分布式模型训练,该训练可以使用GPU或者CPU。当训练出新的模型后,通过arena serve命令将新的模型部署到生产环境,与旧模型共存。但是此时这个新的模型并没有对外服务,数据工程师此时可以通过arena提供的traffic-split命令实现流量控制和模型版本的更新及回滚。