Kubernetes已经成为美团云基础设施的管理引擎,它带来的不仅仅是高效的资源管理,同时也大幅降低了成本,而且为美团云原生架构的推进打下了坚实的基础,支持了Serverless、云原生分布式数据库等一些平台完成容器化和云原生化的建设。 本文根据美团基础架构部王国梁在KubeCon 2020云原生开源峰会Cloud Native + Open Source Virtual Summit China 2020上的演讲内容整理而成。
Kubernetes是让容器应用进入大规模工业生产环境的开源系统,也是集群调度领域的事实标准,目前已被业界广泛接受并得到了大规模的应用。
从2013年开始,美团就以虚拟化技术为核心构建了云基础设施平台;2016年,开始探索容器技术并在内部进行落地,在原有OpenStack的资源管理能力之上构建了Hulk1.0容器平台;2018年,美团开始打造以Kubernetes技术为基础的Hulk2.0平台;2019年年底,我们基本完成了美团云基础设施的容器化改造;2020年,我们坚信Kubernetes才是未来的云基础设施标准,又开始探索云原生架构落地和演进。
当前,我们构建了以Kubernetes、Docker等技术为代表的云基础设施,支持整个美团的服务和应用管理,容器化率达到98%以上,目前已有数十个大小Kubernetes集群,数万的管理节点以及几十万的Pod。不过出于容灾考虑,我们最大单集群设置为5K个节点。
当前,我们构建了以 Kubernetes、Docker 等技术为代表的云基础设施,支持整个美团的服务和应用管理,容器化率达到 98% 以上,目前已有数十个大小 Kubernetes 集群,数万的管理节点以及几十万的 Pod。不过出于容灾考虑,我们最大单集群设置为 5K 个节点。
下图是当前我们基于 Kubrnetes 引擎的调度系统架构,构建了以 Kubernetes 为核心的统一的资源管理系统,服务于各个 PaaS 平台和业务。除了直接支持 Hulk 容器化之外,也直接支持了 Serverless、Blade 等平台,实现了 PaaS 平台的容器化和云原生化。
对于一个技术栈比较成熟的公司而言,整个基础设施的转变并不是一帆风顺的,在 OpenStack 云平台时期,我们面临的主要问题包括以下几个方面:
为了解决虚拟机存在的问题,美团开始探索更加轻量级的容器技术的落地,也就是 Hulk1.0 项目。不过基于当时的资源环境和架构,Hulk1.0 是以原有的 OpenStack 为基础资源管理层实现的容器平台,OpenStack 提供底层的宿主机的资源管理能力,解决了业务对弹性资源的需求,并且整个资源交付周期从分钟级别降低到了秒级。
但是,随着 Hulk1.0 的推广和落地,也暴露出一些新的问题:
上述的问题经过一段时间的优化和改善,始终不能彻底解决。在这种情况下,我们不得不重新思考整个容器平台的架构合理性,而此时 Kubernetes 已逐步被业界认可和应用,它清晰的架构和先进的设计思路让我们看到了希望。所以我们基于 Kubernetes 构建了新的容器平台,在新的平台中 Hulk 完全基于原生的 Kubernetes API,通过 Hulk API 来对接内部的发布部署系统,这样两层 API 将整个架构解耦开来,领域明确,应用管理和资源管理可以独立迭代,Kubernetes 强大的编排和资源管理能力凸显。
容器化的核心思路是让 Kubernetes 做好资源层面的管理,而通过上层的控制层解决对美团应用管理系统和运维系统的依赖问题,保持 Kubernetes 的原生兼容性,减少后续的维护成本,并完成了快速收敛资源管理的需求。同时,也减少了用户基于新平台的资源申请的学习成本,这点非常重要,也是后续我们能快速大规模迁移基础设施资源的“基础”。
美团产品众多,业务线和应用特点五花八门,所以相应的,我们对于资源类型和调度策略的需求也是非常多。例如,有些业务需要特定的资源类型(SSD、高内存、高 IO 等等),有些业务需要特定的打散策略(例如机房、服务依赖等),所以如何很好地应对这些多样化的需求,就是一个很大的问题。
为了解决这些问题,我们为扩容链路增加了策略引擎,业务可以对自己的应用 APPKEY 自定义录入策略需求,同时基于大数据分析的服务画像,也会根据业务特点和公司的应用管理策略为业务策略推荐,最终这些策略会保存到策略中心。在扩容过程中,我们会自动为应用的实例打上对应的需求标签,并最终在 Kubenretes 中生效,完成预期的资源交付。
精细化的资源调度和运营,之所以做精细化运营主要是出于两点考虑:业务的资源需求场景复杂,以及资源不足的情况较多。
我们依托私有云和公有云资源,部署多个 Kubenretes 集群,这些集群有些是承载通用业务,有些是为特定应用专有的集群,在集群维度对云端资源进行调配,包括机房的划分、机型的区分等。在集群之下,我们又根据不同的业务需要,建设不同业务类型的专区,以便做到资源池的隔离来应对业务的需要。更细的维度,我们针对应用层面的资源需求、容灾需求以及稳定性等做集群层的资源调度,最后基于底层不同硬件以及软件,实现 CPU、MEM 和磁盘等更细粒度的资源隔离和调度。
不管是 VM,还是最初的容器平台,在应用稳定性方面一直都存在问题。为此,我们需要在保障应用的 SLA 上做出更多的努力。
在生产环境中,宿主机的发生重启是一种非常常见的场景,可能是主动重启也可能是被动,但用户角度来看,宿主机重启意味着用户的一些系统数据就可能丢失,代价还是比较高的。我们需要避免容器的迁移或重建,直接重启恢复。但我们都知道,在 Kubernetes 中,对于 Pod 中的容器的重启策略有以下几种:Always、OnFailure 和 Never,宿主机重启后容器会重新被创建。
为了解决这个问题,我们为容器的重启策略类型增加了 Reuse 策略。流程如下:
用户的另一个痛点与容器性能和稳定性相关。我们不断收到业务反馈,同样配置的容器性能存在不小的差异,主要表现为部分容器请求延迟很高,经过我们测试和深入分析发现:这些容器存在跨 Numa Node 访问 CPU,在我们将容器的 CPU 使用限制在同一个 Numa Node 后问题消失。所以,对于一些延迟敏感型的业务,我们要保证应用性能表现的一致性和稳定性,需要做到在调度侧感知 Numa Node 的使用情况。
为了解决这个问题,我们在 Node 层采集了 Numa Node 的分配情况,在调度器层增加了对 Numa Node 的感知和调度,并保证资源使用的均衡性。对于一些强制需要绑定 Node 的敏感型应用,如果找不到合适的 Node 则扩容失败;对于一些不需要绑定 Numa Node 的应用,则可以选择尽量满足的策略。
相信做过 ToB 业务的同学应该都了解,任何产品都存在大客户方案,那么对于美团这样的公司,内部也会存在这种情况。平台型业务的容器化有个特点是:实例数多,以千或万计,所以资源成本就比较高;业务地位比较高,一般都是非常核心的业务,对性能和稳定性要求很高。所以,如果想要通过“一招鲜”的方式解决此类业务的问题,就有些不切实际。
这里,我们以 MySQL 平台为例,数据库业务对于稳定性、性能和可靠性要求非常高,业务自己又主要以物理机为主,所以成本压力非常大。针对数据库的容器化,我们主要是从宿主机端的资源分配定制和优化为切入口。
最终,我们将数据库的交付效率提升了 60 倍,并且在大多数情况下性能比之前的物理机器还要好。
对于一个企业而言,基于成本考虑,资源一直会处于不足的状态,那么如何保障资源的供给和分配就显得非常重要。
在迁移到 Kubernetes 之后,我们进一步实现了云原生架构的落地。
为了解决云原生应用管理的障碍,我们设计实现了美团特色的云原生应用管理引擎——KubeNative,将应用的配置和信息管理对平台透明化,业务平台只需要创建原生的 Pod 资源即可,不需要关注应用的信息同步和管理细节,并支持各 PaaS 平台自己来扩展控制层面的能力,运行自己的 Operator。
下图就是目前我们整个的云原生应用管理架构,已支持 Hulk 容器平台、Serverless 以及 TiDB 等平台的落地。
在整个基础设施迁移过程中,除了解决历史遗留问题和系统建设,随着 Kubernetes 集群规模和数量快速增长,我们遇到的新的挑战是:如何稳定、高效地运营大规模 Kubernetes 集群。我们在这几年的 Kubernetes 运营中,也逐渐摸索出了一套验证可行的运营经验。
我们最初使用的 Kubernetes 是 1.6 版本,性能和稳定性是比较差的,当我们达到 1K 节点的时候就逐渐出现问题,达到 5K 节点时基本集群不可用。例如,调度性能非常差,集群吞吐量也比较低,偶尔还发生“雪崩”的情况,扩缩容链路耗时也在变长。
针对核心组件的分析和优化,这里从 kube-apiserver、kube-scheduler、etcd 以及容器等四个方面来概括下。
另外,社区版本的迭代是非常快的,高版本在稳定性和特性支持上更好,不可避免我们需要进行版本的升级,但如何确保升级成功是一个很大的挑战,尤其是我们在没有足够的 Buffer 资源进行资源腾挪情况下。
集群升级,业界通用的方案是直接基于原有集群升级,方案存在以下几点问题:
为此,我们深入研究了 Kubernetes 对容器层面的控制方式,设计实现了一种能够平滑将容器数据从低版本集群迁移到高版本集群的方案,将集群升级细化为 Node 粒度的逐个宿主机上容器的原地热升级,随时可以暂停和回滚。新方案主要是通过外部工具将 Node 和 Pod 数据从低版本集群迁移到高版本集群,并解决 Pod 对象和容器的兼容性问题。核心思路是两点:通过低版本兼容高版本的 API,通过刷新容器的 Hash 保障 Pod 下的容器不会被新;通过工具实现 Pod 和 Node 资源数据从低版本集群迁移到高版本集群。
该方案亮点主要包括以下 4 个方面:
大规模的集群运营是非常有挑战的事情,满足业务的快速发展和用户需求也是对团队极大的考验,我们需要从不同纬度的考虑集群的运营和研发能力。
在 Kubernetes 与 etcd 集群的整个运营和运维能力建设上,我们关注的目标是安全运营、高效运维、标准化管理以及节约成本。所以针对 Kubernetes 与 etcd 集群,我们已经完成了平台化的管理运营,覆盖了特性扩展、性能与稳定性、日常运维、故障恢复、数据运营以及安全管控等 6 个方面。
对于一个非公有云业务的 Kubernetes 团队,人力还是非常有限的,除了集群的日常运营还有研发任务,所以我们对于运营效率的提升非常关注。我们将日常运维逐步的沉淀转换,构建了一套美团内部的 Kubernetes 集群管理平台。
规模大、覆盖业务广,任何的集群故障都会直接影响到服务的稳定性甚至用户的体验,在经历了多次运维故障和安全压力下,我们形成了一套可复制的风险控制和可靠性保障策略。
在整个风险管控链路中,我们分为指标、告警、工具、机制 & 措施和人员 5 个层面:
在可靠性验证和运营方面,我们笃信需要把功夫用在评审,通过集群巡检来评估集群的健康情况,并推送报表;定期的宕机演练保障真实故障能够快速恢复,并将日常问题补全到全链路测试中,形成闭环。
在容器时代,不能只看 Kubernetes 本身,对于企业内的基础设施,“向上”和“向下”的融合和兼容问题也很关键。“向上”是面向业务场景为用户提供对接,因为容器并不能直接服务于业务,它还涉及到如何部署应用、服务治理、调度等诸多层面。“向下”,即容器与基础设施相结合的问题,这里更多的是兼容资源类型、更强大的隔离性、更高的资源使用效率等都是关键问题。
作者介绍:
国梁,美团技术专家,现负责美团 Kubernetes 集群的整体运营和维护以及云原生技术落地支持。
领取专属 10元无门槛券
私享最新 技术干货