众所周知,基于微服务的应用更加适合运行在容器上,可以最大化发挥微服务的优势。但在微服务应用上容器的过程中,由于用户实际情况和发展规划的差异,采取的路径和方案也有不同。如何选择最合适的方案,其中的关注点有哪些,并如何应对,都需要去认真考虑。
今天我们跟大家一起聊一聊这个主题《当我们说微服务上容器,我们在说什么》,分享的内容主要包括微服务应用容器化的几个典型场景、需要关注的问题以及对应的解决方案。
本文是 6 月 30 日“CloudTech 博云说”第五期分享内容《当我们说微服务上容器时,我们在说什么?》的回顾整理。扫描上方海报二维码或点击文章末尾的阅读原文,回看精彩视频!
01 微服务与容器:1+1>2
大家肯定都听说过云原生或者 PaaS 落地的三驾马车,即微服务、容器和 DevOps,三者相辅相成并有着广泛的联系。在云原生技术落地过程中,应用敏捷迭代和健壮运行的需求正是促进微服务应用产生并发展的重要因素。而虚拟机作为 IT 基础设施的支撑,从单体应用到微服务应用的时代,已经无法很好地满足微服务应用部署的核心需求,即保证资源利用率不降低甚至提升,高性能、高可用、高弹性的保证等。容器技术的兴起并非偶然,而是正好契合了微服务应用时代的需求。
云原生技术社区中最为人所认可的思想家之一,Adrian Cockcroft,他曾经说过在与容器结合使用后,微服务架构的优点得到了进一步的放大。原因在于,微服务鼓励软件开发者将整个软件解耦为较小的功能片段,并且这些功能片段能够应对外界的故障。而容器进一步对这种解耦性进行了扩展,它能够将软件从底层的硬件中分离出来。
根据信通院《中国云原生用户调研报告》显示,国内 64% 的用户将容器技术应用于部署微服务化应用,这也是国内使用容器的最多场景。
02 微服务的发展历程
在谈微服务容器化部署之前,我们先看看微服务的发展历程。虽然微服务的架构有多种类型,但从总体来说主要分为两种:一种是有一定侵入性的传统微服务架构,如 Spring Cloud、Dubbo、gRPC 等,另一种是近些年兴起的非侵入式微服务架构 ServiceMesh,如 Istio、Linkerd、Sofamosn 等。
其实从微服务发展演进的角度来看,除了所谓的侵入和不侵入的差异,微服务的另一个趋势是向容器靠拢。传统的微服务架构没有考虑太多的容器化部署,而 ServiceMesh 天生就与 kubernetes 紧密结合,不得不说,这也是一种明显的需求主导的技术变革趋势。
03 微服务上容器,需要注意什么?
当然,微服务从虚拟机部署到容器化部署,肯定会带来很多变化。那么会有哪些主要变化呢?我们从以下主要五个角度做了一些简单总结。
部署形态:从虚拟机到容器的变化;
通信模式:部署在容器上需要增加一层容器网络层;
服务框架:在服务框架上会更多的考虑服务网格方案,从而带来传统微服务框架和服务网格共存以及演进的问题;
管理架构:容器化服务/集群与非容器服务的共存,需要有容器+非容器的统一部署和运维管理场景
应用架构:需要进一步地做服务的云原生/无状态化改造。
基于这些变化,我们可能会产生一些疑惑和不确定性。例如,如果是某某框架自研或采购的某某厂商的微服务应用,能上容器吗?好上容器吗?会不会很麻烦?带来哪些问题?注册是 nacos,或者是用到了某某组件、中间件,影响上容器吗?带着这些问题,我们先基于一个典型的微服务架构应用来看一下。
这个图是一个比较典型的微服务架构应用。从业务维度来看,它由前后端的服务组成,基于传统的管理框架提供注册和配置。从组件视角来看,它包括了前端、后端服务、注册中心、配置中心、网关和中间件。并且对于微服务的管理,还有服务调用、负载均衡、限流熔断、服务监控、事务追踪、分布式消息等,通过 Dubbo 或 SpringCloud 可以提供这类管理组件的统一集成方案。基于以上,这时候我们会初步形成两类微服务应用容器化的方案:
第一种,对于各类组件、前后端应用去做容器化,改变它们的部署形态。这个时候业务和治理逻辑还没有完全解耦,治理和监控对业务代码还是有一定的侵入。
第二种,就是框架也进行演进,采用服务网格 ServiceMesh 的方案,再进行容器化。
第一种场景我们可能会比较关心这些组件和服务的容器化改造的顺序,而第二种场景会产生诸如 ServiceMesh 方案选型,传统微服务治理框架如何更便捷地演进到 ServiceMesh 框架。针对这些问题,我们也梳理了几个典型场景。
从整体上看,主要有三大典型场景:
传统微服务架构应用上容器场景,包括了部分上容器和全部上容器。
服务网格应用上容器场景,涉及应用直接采用 ServiceMesh 框架和传统微服务架构迁移或兼容 ServiceMesh。
微服务应用容器化之后进行统一治理、运维的场景。
下面我们一起来看一下,针对不同的场景,在这些场景里有哪些需要重点关注的地方。首先是微服务应用上容器的两种方式。在应用全部容器化的场景,会关注应用状态保持、配置、通信、日志,版本发布和部署等。在应用部分容器化的场景,需要关注网络互通、配置正确等。由于时间关系,这里就不一一展开了,这里可以参考我们最近发布的《应用上容器指南》。
下面针对一些关键点我们来展开详细阐述一下。
04 微服务上容器,中间件不上容器,如何解决网络问题
首先在应用部分容器化中,即微服务应用上容器,中间件不上容器的场景中,存在着一个痛点或者关注点,也就是容器集群内外如何高效、安全的互通,就如之前使用虚拟机网络那样。
这张图很好地展现了这个场景,一部分服务部署在了 kubernetes 容器集群上,但注册中心、数据库中间件等还是部署在虚拟机或者物理机上,甚至还有一部分服务也是运行在容器集群外部的。
那么对于注册中心来说,它希望各个服务还是像以前虚拟机部署一样去做注册,网络直通,同时服务对于数据库中间件的访问性能不要降低。这其实是对容器集群的网络方案提出了更高的要求。
目前,业界有这两种容器网络方案,Underlay 和 Overlay 模型。这两种模型比较好理解,一种是容器网络使用虚拟机网络的扁平化网络方案,就是 Underlay,另一种是容器网络在虚拟机网络之上再架设一层私有网络,就是 Overlay。
对于这种容器集群内外直通的场景,比较推荐使用 Underlay 方案,因为这种方案提供了更高的网络性能,更低的性能损耗,并且使用原有的虚拟机网络实现二层互通,基于固定 IP 地址可以配置精确完整的防火墙策略。
如果选择 Overlay 网络方案,则需要通过 nodeport 或 Ingress 等特殊配置实现内外网互联互通,Overlay 网络方案更推荐微服务和中间件全部容器化的场景,其中跨集群的通信可以通过网络联邦来实现高性能的互联互通。
05 微服务和中间件都上容器,如何解决中间件容器化?
刚刚有讲过,在微服务和中间件都上容器的场景,除了网络选型,还有一个重点关注的内容,就是中间件的容器化。例如 MySQL、Redis、Kafka、Nacos 之类,这些中间件不光需要考虑怎么容器化部署,还要进行包括全生命周期管理、可观测性、灾备、自动运维和无缝升级等中间件管理能力的建设。
既保障容器化的中间件的高性能高可靠,同时也要实现具备更高的自动化运维能力。在这块,业界有一个基本达成共识的方案,即采用 Operator,来对中间件的单实例/高可用方式进行自动部署编排,并提供相关的全生命周期和监控运维、备份恢复的能力。
通过 Operator 来实现中间件容器化,或者说云原生化,相比于传统的中间件管理和运维方案,例如基于 ansible 的方案,具有特有的一些优势。一是可以发挥容器的高性能和高弹性,同时具备更强的自动化运维能力和快速部署能力。现在社区里也有很多中间件的开源 Operator,但如果要做到真正的企业级落地,还需要做很多的增强。
例如,多版本、个性化指标、大规模数据迁移,网络的高性能通信、安全可靠和运维排障效率高,存储也有高性能、消耗小、原地重启、智能编排、运维简单等要求,同时开源的 Operator 在跨数据中心的容灾双活和备份能力上也比较缺乏。所以在实际落地中,这些问题都需要考虑,要根据自己的使用场景和需求来合理选择 Operator 以及是否要去做相关增强。
06 传统微服务如何向 ServiceMesh 演进?
在微服务应用使用 ServiceMesh 框架的场景中,有个问题绝大部分的用户都绕不过,就是现有传统微服务框架如何演进到 ServiceMesh 架构?我们可以反过来想想,首先这个事有必要做吗?或者为什么要做?
这时候我们需要先了解,传统微服务框架下存在的大量难以解决的痛点有哪些?
业务代码与微服务框架 SDK 强耦合(同一进程);
业务升级与微服务框架升级强绑定导致微服务框架自身演进困难;
少量语言独大进展快,小众语言进展慢带来的微服务框架 SDK 多语言并行开发与维护成本高;
异构服务框架难以共存完成渐进式演进,导致单体应用改造微服务应用的启动成本高;
单一的语言限制了应用场景和人才的多样性,就如 Springcloud 主要支持 Java,对多语言支持比较差。
而采用 ServiceMesh 框架后,实现了业务逻辑与治理功能的分离。在服务网格中,将治理能力下沉到基础设施后,业务的开发、部署、升级都和服务治理的基础设施解耦了。业务开发者可以专注自己的业务部分,只要没有修改业务代码,就无需重新编译和上线变更。当治理能力升级只需基础设施升级即可,基础设施的升级对用户业务完全没有影响。我们可以看到,ServiceMesh 方案具备多语言、多协议支持,无侵入、治理解耦和下沉、让开发更加规范化和难度降低等非常明显的优势。
这时大家可能会有个疑问,传统微服务架构应用迁移到 ServiceMesh 上,是不是很麻烦?
我们在相关的项目实践和落地中,总结了两种常见改造方案,两者共同的核心是要去做解耦、剥离以及裁剪的事情。首先是流量治理的相关工作要通过 Envoy 等 Sidecar 来做,另外要考虑的是要不要动业务代码本身。
一种比较好理解,就是裁剪掉服务治理 SDK;另一种比较保守的方式是只修改配置,SDK 依然保留,但实际保留的主要是代码框架、应用协议等开发功能,涉及到微服务治理的内容都卸载到基础设施去做。这需要原来的注册中心,治理等相关功能要借助 Kubernetes 和 ServiceMesh 去做,包括注册中心使用 kubernetes service 能力,直接使用 kubernetes 的服务名和端口访问目标服务,结合自身需求,使用网格中的治理能力来逐步替换原有的相关能力。
修改配置的方式需要手动的配置 ribbon,利用这种机制给对应微服务的后端实例地址中配置服务的 Kubernetes 服务名和端口。当 Spring cloud 框架中还是访问原有的服务端微服务名时,会将请求转发到 kubernetes 的服务和端口上。这样访问会被网格数据面拦截,从而走到网格数据面上来。服务发现负载均衡和各种流量规则都可以应用网格的能力,就是说原来的 SDK 里的内容还在,治理组件什么的也还在,但被旁路掉了。这种方式可以实现代码 0 修改,不需要重新编译,实现真正的不侵入代码的转型和迁移。
但裁剪 SDK 的方式,改造更彻底,从最终的镜像大小看,整个项目的体量也能得到极大的瘦身。这种方式客户根据自己的实际使用方式,进行各种裁剪,最终大部分是把 Spring Cloud 退化成 Spring Boot。这种方式会有一定的代码改造工作量,并且需要重新编译。
这两种方案可以根据业务开发现状、规模和需求酌情选用。
说到微服务的管理和运维,我们会关注”两个统一“。一个是微服务框架的统一管理,另一个是容器和非容器部署架构的统一管理。我们的实际现状可能是一些应用是 Springcloud 框架,有些应用是 Dubbo 框架,有些是 ServiceMesh 框架,而这些应用有可能会部分部署在虚拟机部分在容器上。整体的、完整统一的发布和运维管理体系的建立还是很有必要,否则又会产生多套管理平台,导致运维的工作量增大,运维效率也比较低。
这是一个比较典型的建议,我们推荐微服务的运维管理要做成异构化的支撑,包含监控和治理两块的内容需要考虑。我们可以在服务监控上做统一设计,服务治理可以在创建应用时选择不同的架构进行不同治理方案的选择,而后根据平台的统一治理组件管理能力或者 Sidecar 能力来实现不同的治理能力支撑。
07 关于博云
最后也简单介绍一下博云针对我们今天讨论的场景,在产品和解决方案维度做了哪些事情。
针对企业微服务转型,博云可以提供微服务咨询服务,并且有相关的企业级产品微服务应用管理平台 BMS,覆盖开发、发布、运行阶段,同时提供中间件统一管理和企业级 API 网关等组件,并且具有在大量客户尤其金融客户那里积累了丰富经验的服务团队,可以提供一整套完整的产品及服务解决方案。
在产品设计上,我们以应用为核心,提供开发与发布视角的统一双模应用发布、管理、运维视角的统一监控,以及运行视角的多框架统一治理,真正实现了书同文、车同轨。
针对中间件管理场景,博云的中间件管理平台 BMM 基于开源 Operator 做了大量企业级增强,对于之前提到的开源 Operator 的一些不足,如高性能网络和存储的需求、跨机房的容灾备份需求等都做了全面设计提升。目前已经支持了 MySQL、Redis、Elasticsearch、Kafka、RocketMQ、PostgreSQL、Nacos、Zookeeper 等主流中间件的全生命周期管理能力。在多个项目的实践中,对于中间件交付效率的提升、运维成本的降低、资源成本的节省都有非常显著的效果。
在之前讨论到容器网络的两种网络模型,博云自研的 BeyondFabric 产品都可以提供完整的解决方案支持,它结合了大量实践场景,从功能的完整性、高性能、稳定可靠性、易用性等多个维度做了全面设计。其中 Fabric Underlay 方案提供 pod 和 workload 的固定 IP 地址和地址段,多数据面管理,pod 多网卡多协议支持,通过 DPDK 和动态 qos 提供高性能低延时的支撑,在 IPAM 地址池管理场景,支持大规模 IP 快速分配。
Fabric Overlay 方案提供网络联邦,在同构的联邦场景下提供高性能互通方案,不需要使用网关,另外提供多种隧道协议及隧道加密支持,可以提供分布式的 Egress 网关,在 namespace 和 workload 的级别均可以设置 eip。另外还有一些其他的核心能力,例如通过微分段的方式解决大规模集群流表性能问题,分布式控制器保障网络运行稳定可靠,支持 windows 网络支持 arm 架构集群等,在这里就不一一赘述了。我们在公众号上也有容器网络专题的文章,有兴趣的朋友可以搜索看一下。
今天的分享也到此结束,感谢大家。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。