一文看懂云原生架构的演变过程


(K8S技术分水岭,图片来源于网络)
譬如诺豆公司「化名」使用K8S已经2年了,而最近遇到的 Node 节点 NotReady 的问题,还不能完全凭借自有运维团队的能力解决,最终还是依靠公有云技术支持才得以定位到问题,在解决问题的过程中有如下插曲:
- 根据日志报错,完全搜索不到相关技术贴「怀疑公有云厂商修改了K8S的调度脚本」;
- 大量非关键日志掩盖/var/log/message中K8S pleg核心报错,经验不足,忽略关键日志,错失关键切入点;
- 某公有云厂商的首次诊断结果是:runc 通道阻塞,需更换自研OS方可解决;
- 方案被严厉拒绝后,派遣高工介入,修改结论为:docker 19.3.5 版本 runc 有BUG,升级至 19.3.15 可解决。
- 核因并未找到,怀疑 max_pid 和 ulimit不足、机器负载高、及container频繁exec health check导致 runc hang,但无实据,而服务器状态很健康。
继而引发的思考:
- 问题一:如何在公有云上获得更自主可控的运维管理能力;
- 问题二:版本升级成本高昂,如何平滑升级;
- 问题三:「上述问题出现在测试环境」,生产环境出问题的SLA如何保障。
问题一和三很容易解决,多云或者混合云方案,加强对供应商管理与对接。问题二很难,纵观整个行业,少有公司掌握自我升级能力,基本都要依赖公有云方案或者第三方协助。核心原因依旧在于K8S和云原生的技术门槛太高。但云原生和K8S大火是客观存在的事实,今天我们来聊聊云原生时代下技术演进。
一、架构演变

(大型机到微服务架构演变,图片来源于网络)
- 1.1 中心化->去中心化
该思想一直沿用至今,软件工程上诸如:Satstack、Puppet、OpenStack等。去中心化的代表:Ansible、Git、P2p协议、区块链技术、共识机制。前两者具备去中心化思想,后两者属于完全去中心化。两者没有绝对的好与坏。现代工程软件多为两者结合。
- 1.2 IaaS->PaaS->SaaS->Serverless
- 各职能各司其职,关注各自领域即可;
- 资源按需付费,相对自建,中小规模下有较大成本优势;
- 弹性架构设计;
- 服务开箱即用等。
近年云原生概念逐步普及并落地,强调软件应用应该生于云上,长于云上 。云原生本质并非一门确切的技术或者定义, 而是整套完整的生态体系,或者理解为愿景。
云原生给予的标准化架构及解决方案、高度运维自动化、自愈及配套基础设施等运维能力,倒逼运维向更高层领域转向。据公有云财报,目前,IaaS仍在市场上占据最大份额,云原生协助厂商打造不可变基础设施,本质上讲云原生是系统化能力,因此,未来PaaS、SaaS一定会后来居上。
- 1.3 All in One->微服务
- Build-and-Fix Model模型
- 瀑布模型
- 迭代模型
- 增量模型
- 喷泉模型
- 演化模型
- 敏捷开发模型
- 混合模型
无论哪种模式均不是万能解药,最终目标都是准确快速交付。交付结果通常依赖:
- 软件开发模型
- 项目周期长短
- 技术人员水平
但以上都无法解决“1个孕妇10个月生一胎,10个孕妇1个月生一胎”的问题。微服务解决了如上问题,且提供各接口遵循gRPC或Restful接口。但在服务切割、解耦、依赖关联上无法细化,经验主义。
- 过粗的拆分效果不佳;
- 过细的拆分,导致微服务爆增,资源浪费严重,接口和服务维护成本高昂;
- 需求变更导致过去拆分策略不佳;
无论以上哪种情况,最终都要面临微服务暴增导致的“死星”式调用链。该情况并非只发生在巨头身上的极端情况。

死星调用链路
我们一再强调,云原生提供的解决方案,是系统不可变基础设施。服务网格(Service mesh)、边车(Sidecar)、服务编排和容器之类的新兴架构模式可以有效地阻止基于云的世界中出现的各类错误实践。
二、云原生的架构
- 流量控制
- 服务发现
- 负载平衡
- 弹性
- 可观察性
- 安全性等
它使应用程序可以从应用程序级库中卸载这些功能,并允许开发人员专注于业务逻辑。

(云原生技术应用演进,图片来源于网络)
应用和云通过Sidecar旁路容器作为桥梁交互,每个容器通过代理应用将本身所需要的进出,所以云就可以非常容易地通过这样一个代理,调节流量、做流量切分,这也是 Service Mesh 的基本原理。
服务网格非常适合放在平台即服务(PaaS)和容器即服务(CaaS)之上,并通过这些通用平台服务提升推行云计算过程的体验。
- 2.1 无服务器架构
在无服务器中,我们将业务服务编写为函数,并将这些函数部署到云基础架构中。无服务器技术的一些例子包括Amazon Lambda、Spring Cloud Function、Google Cloud Functions和Microsoft Azure Functions等。
无服务器模型位于云托管范围内的 PaaS 和 SaaS 之间,如下图所示:

(各类服务架构,图片来源于网络)
根据我们应用程序的功能性和非功能性需求(例如性能和可伸缩性以及事务边界等),我们应该为每个特定用例选择适当的单体、微服务或无服务器模型。常见的情况是,我们可能需要在一个解决方案架构中使用所有这三种模式。
如果设计不当,无服务器解决方案最终将变成纳米片,其中每个函数都与其他函数或微服务紧密结合,并且无法独立运行。
- 2.2 服务编排
在传统的单体式架构的应用中,开发、测试、交付、部署单个组件不存在编排概念。而云原生时代,主要为了解决微服务和容器通信和HPA、VPA场景,运维将面临新挑战:我们需要将单体式的架构拆分成越来越多细小的服务,运行在各自的容器中,那么该如何解决它们之间的依赖管理、服务发现、资源管理、高可用等问题?
在容器环境中,编排通常涉及到三个方面:
- 资源编排
- 负载编排
- 服务编排
Kubernetes常见控制器编排方式:
- Deployment
- StatefulSet
- DaemonSet
- CronJob
- Job

(K8S编排调用链,图片来源于网络)
- 2.3 服务网格
连接性:
- 流量控制(路由、分流)
- 网关(入口、出口)
- 服务发现
- A/B 测试、金丝雀
- 服务超时、重试
可靠性:
- 断路器
- 故障注入/混沌测试
安全性:
- 服务间身份验证(mTLS)
- 证书管理
- 用户身份验证(JSON Web Tokens)
- 用户授权(基于角色的访问控制)
- 数据加密
可观测性:
- 监控
- 遥测、仪表盘、指标
- 分布式跟踪
- 服务图
服务网格技术常见实现:
- Istio
- Linkerd
- Consul Connect

(面对K8S的托管服务网格,图片来源于网络)
三、总结
- 互联网技术日新月异,技术不是终点,只是工具的一种,协助达成目标的过渡过程;
- 云原生不是工具,而是体系架构和生态,是一套系统解决方案,更是标准基础设施;
- 架构是演变出来的,不是设计规划出来的。
最后,拥抱云原生,拥抱未来。
关注天旦公众号
跟旦旦一起,
让运维稳定无忧,
运营做你所想。

