深圳幻海软件技术有限公司 欢迎您!

容器云平台物理集群配置实践

2023-02-28

​前言最初建设容器云平台的时候,笔者也讨论过容器虚拟集群和物理集群的优缺点。在容器云平台应用实践过程中,也逐渐部署了虚拟节点和物理节点。随着实践的深入,虚拟节点和物理节点的不同资源配置,也带来了一些问题和思考。起初觉得容器既然是轻量化的,每个节点其实是不需要配置那么高的资源的。不过很快就被现实打脸,

​前言

最初建设容器云平台的时候,笔者也讨论过容器虚拟集群和物理集群的优缺点。在容器云平台应用实践过程中,也逐渐部署了虚拟节点和物理节点。随着实践的深入,虚拟节点和物理节点的不同资源配置,也带来了一些问题和思考。起初觉得容器既然是轻量化的,每个节点其实是不需要配置那么高的资源的。不过很快就被现实打脸,不合适的节点资源配置不但增加了管理的复杂度,也带来了资源的浪费。另外由于容器云平台自身功能的限制,以及总体架构和总体资源受限,难以实现真正的弹性调度、按需扩展。

比如说经常会出现一台宿主机上的虚拟机资源争抢现象,但从容器云平台看到的却是容器节点资源使用不高但应用出现请求异常等问题。所以这并不是一个简单的容器云问题,需要实现各个层次的联动,比如实现虚拟化平台与容器云平台的联动,基础设施资源管理平台与容器云平台的联动以实现异构资源调度等。

从虚拟机节点到物理机节点

基于虚拟化平台来部署容器云则相对容易实现容器节点的扩缩容,但由于缺乏统一的监控平台和囿于单体竖井系统建设思路,虚拟化层宿主机的信息往往在容器云平台无法看到,无法及时有效平衡容器节点在虚拟化宿主机上的负载。

笔者一直建议通过多云管理平台(也管理虚拟化平台)来实现不同基础设施资源的管理,但目前市面上的云管平台基本都是一个大杂烩,没有真正理解云管的定位和范围。等等诸多原因,使难以实现基础设施资源的自动化弹性扩容和平衡调度。

另外,虚拟化层也导致了机器性能损失约20%,造成很大的浪费。比如Java应用对资源的需求相对比较大,基于SpringCloud框架开发的微服务,如果部署在资源配置比较小的虚拟机上,容器经常会因为资源不足而被驱逐,会看到很多Evicted状态的容器。

再者,随着容器节点的增多,很多问题就暴露出来了,比如说Master节点配置(随着节点增多,Master节点资源不足响应变慢)、ETCD配置(pod、service等对象越来越多)、Ingress配置(高可用、负载均衡等不同需求所带来配置的不同)、Portal配置(Portal组件划分、组件集中部署或分布式部署、组件资源配额)问题等。

一方面可能国内很多容器平台的应用都是浮于表面,缺乏真正的实践经验,没有太多可以借鉴的,也导致很多功能不完善;另一方面,传统单体竖井的建设思路,已经完全不适应云计算和云原生的理念,从而也导致冲突,制约容器云的深度应用和实践。

为了更好的实现可见性和可管理性,为了更好的性能和资源节省,经过一段实践之后,我们将一些物理服务器部署到了容器虚拟集群,用于部署运行重要的业务应用,形成虚实节点混合部署集群。

混合节点集群

私有云环境往往无法充分配置各种类型的资源,所以大都是通用性资源,用于部署各种业务应用。容器云平台既要考虑节点的敏捷扩容,也要考虑重点业务应用的稳定运行和执行效率。物理服务器的采购往往需要一个周期,需要提前准备相应的资源。物理节点扩容相对于虚拟化来说就没那么方便,也难以实现资源的复用,这是物理节点不足的地方。但物理节点没有性能损失,适合运行一些比较重要的业务,或对处理性能要求比较高的业务。因此可以在容器集群中同时部署虚拟节点和物理节点,实现混合节点的集群。在业务应用部署的时候,根据业务应用特点调度到合适的节点上。

节点配置多大的资源是合适的?坦率说到目前为止也没有一个明确的标准,往往和具体的业务密切相关。笔者所在场景中虚拟机可以配置16C 64G、16C48G或者32C64G,磁盘200G,CPU和内存的比为1:4、1:3、1:2。根据业务运行对资源的消耗需求,经过一段时间的运行观察,可以根据实际资源使用再调整节点资源配置、容器资源配置。在交易高峰时段,CPU经常是满负荷的,但其他时段CPU往往用的又比较低。共享分区、独享分区、节点容量、资源碎片、纵向扩容能力、横向扩容能力、迁移规则、服务优先级、甚至异构资源的费用等等,都可能会影响到pod的调度。这其实带来了一个物理节点资源配置的问题。物理机不做虚拟化,就无法从虚拟层来实现复用(不过也减少了虚拟化损耗),另外,物理节点如果出现异常,需要维护重启,其上面的服务都会受到影响。如果部署的服务比较多,带来的影响就比较大。所以一个容器节点的资源配置也不是越大越好,需要基于实践和实际找到一个平衡。

容器物理集群配置

物理集群中节点什么样的配置比较合适?可能需要从几个方面来考虑。最初笔者也想当然觉得可以用很多低配PC机,不过从机房的使用效率来说,低配PC明显不是很合适,毕竟需要占据很多机房机位的,这个成本其实很高的。但如果配置过高,一个容器节点通常也不适合部署很多个容器,k8s建议不超过110个pod。另外,配置过高,节点数量相对就比较少,弹性调度的范围就比较小。特别多个重要的容器部署到同一个节点上,一旦节点出现异常,影响可能会非常大。不过物理节点相对有效的减少了资源碎片和资源虚拟化损失,资源利用率相对更高。

基于前期的实践和实际的情况,采购了一批96C 512G 4T的服务器,用于搭建容器物理集群,部署一些重要的业务应用。采用物理节点,对应用资源的调度能力要求反而更高了。资源调度可以有不同的规则,比如说是平衡调度?还是单节点优先调度?或是预留部分资源平衡调度等等;还有大的pod和小的pod的均衡调度、服务亲和性和非亲和性调度等需求。在节点量相对少的情况下,可能需要重点考虑应用pod的均衡调度问题。

深入认识容器使用场景

我们都知道容器轻量、无状态、生命周期短。不过实际应用可能会发现,一个业务应用容器可能并不轻量、有众多的数据需要持久化、往往需要长期持续稳定运行等等。可能也会经常遇到几个G、十几个G的镜像,把容器直接当虚拟机用。虽然说这是一些不好的习惯,不过问题确实是存在的。理论上,容器要尽可能删除无用的组件和文件,使容器尽可能轻量,但实际项目中,很多厂商都不会去做这些工作,因为这需要很多的时间来清理,需要遵循很多的规则,需要额外很多测试;另外在业务异常处理过程中可能会用到一些工具或组件,安装这些工具和组件到容器就会导致这些容器比较重,同时也增加了安全的接触面,带来了更多的安全漏洞或潜在安全漏洞和安全风险。比如说,打包Java服务时用JDK镜像还是用JRE镜像?运行java,JRE就够了,用JDK其实就额外浪费了很多资源。

笔者就一直强调像数据库、Kafka、Redis、ES等不适合部署在容器中,当然,测试环境中为了敏捷构建业务测试环境,快速回归初始状态以便于执行回归测试等,是很便利的。不过生产环境追求的是稳定、可靠(这就是Google SRE的价值所在),和测试环境的敏捷需求是不一样的。不同的场景所采取的方案可能是不同的,因此在实现容器内小环境一致性的之外,企业内生产和测试环境可能还是会有差别的。在生产环境,稳定性和可靠性比弹性更重要,因此,生产环境除了数据库、中间件等适合部署在物理机上外,一些重要的业务也可用容器物理节点更好的满足性能等需求。

笔者曾经尝试配置不同的容器节点以满足不同业务应用的需求,但资源分配出去之后无法控制各团队的使用,特别有众多的厂商和外包人员,对容器和相关的技术理解不深,不知道怎么设置资源配置、调度配置等参数,对业务服务的资源需求不知道怎么预估,因此往往会不自觉地配置很大的资源以此来避免资源所带来的问题,但这样造成了很大的资源浪费(分出去的资源被独占,无法与其他服务共享)。因此也需要及时的监控提醒和培训,调整不合理的资源配置。

容器在迁移、重启、被驱逐等都会导致Pod重建,造成短时间的中断;业务服务如果无法启动比如初始化连接不上kafka或数据库可能会导致Pod频繁重建,k8s自身的一些bug也会导致系统某些资源耗尽,带来节点异常。实际运行种也曾发现有容器服务创建了数百个到数千个进程。由于容器POD的封装,不去检查这些指标的话可能无法发现问题,导致环境经常出现异常,特别生产环境,业务不稳定不止体验不好,更会带来资金损失,所以容器的短生命周期自恢复特性,如果不注意其内封装的业务应用和运行环境,依然会带来很多问题。

一点建议

大家往往都喜欢最佳实践,其实不同环境不同场景不同需求等所应采取的方案可能也不同的,所以笔者也一直建议基于实际来考虑。经验可以作为参考,但不能照搬。容器云平台在使用虚拟节点和物理节点时各有优缺点,不过随着管理手段的增强,以及政策的支持,物理集群可能会越来越多。物理集群的配置也需要基于具体的业务需求来确定。

如果每个服务对资源的需求都不大,可以配置稍微低点的物理节点;如果部署的容器对资源需求比较大,比如部署Kafka、ES等中间件容器,可能一个Pod就需要32C64G甚至更多的资源,可能需要配置高些。随着应用资源调度能力逐步完善,实现不同业务分时共享复用来有效提升资源利用率,可能会越来越普遍。已经有公司通过应用混合部署来提升资源效率,比如说白天处理交易业务为主,晚上处理批量计算为主,使业务忙时和闲时的资源都能充分利用。这对于容器物理节点来说可能会更合适些。