早在 2011 年,阿里巴巴内部便开始了应用容器化,当时最开始是基于 LXC 技术构建容器,然后逐渐切换到 Docker,自研了大规模编排调度系统。到了 2018 年,我们团队依托 K8s 体系开始推进“轻量级容器化”,同时投入了工程力量跟开源社区一起解决了诸多规模与性能问题,从而逐步将过去“类虚拟机”的运维链路和阿里巴巴整体应用基础设施架构升级到了云原生技术栈。
到了 2019 年,Kubernetes 基础设施底盘在阿里巴巴经济体中已经覆盖了阿里巴巴方方面面的业务,规模化的接入了包括核心电商、物流、金融、外卖、搜索、计算、AI 等诸多头部互联网场景。这套技术底盘,也逐步成为了阿里巴巴支撑 618、双11 等互联网级大促的主力军之一。
目前,阿里巴巴与蚂蚁金服内部运行了数十个超大规模的 K8s 集群,其中最大的集群约 1 万个机器节点,而其实这还不是能力上限。每个集群都会服务上万个应用。在阿里云 Kubernetes 服务(ACK)上,我们还维护了上万个用户的 K8s 集群,这个规模和其中的技术挑战在全世界也是首屈一指的。
我们的 Kubernetes 面临的新挑战
在规模和性能等基础设施领域问题逐步解决的同时,规模化铺开 Kubernetes 的过程中,我们逐步发现这套体系里其实还有很多意想不到的挑战。这也是今天分享的主题。
第一个是 K8s 的 API 里其实并没有“应用”的概念
而且,Kubernetes API 的设计把研发、运维还有基础设施关心的事情全都糅杂在一起了。这导致研发觉得 K8s 太复杂,运维觉得 K8s 的能力非常凌乱、零散,不好管理,只有基础设施团队(也就是我们团队)觉得 Kubernetes 比较好用。但是基础设施团队也很难跟研发和运维解释清楚 Kubernetes 的价值到底是什么。
我们来看个实际的例子。
就拿上图中的 replica 为 3 来说,开发人员怎么知道实例数应该配几个呢?如果运维想要改replica,敢不敢改?能不能改?如果 replica 还能理解的话,那像 shareProcessNamespace 这种字段真是灵魂拷问了。 开发人员仅从字面意思知道这个可能跟容器进程共享有关,那么配置了这个应用会有什么影响呢?会不会有安全问题?
在阿里巴巴内部,很多 PaaS 平台只允许开发填 Deployment 的极个别字段。为什么允许填的字段这么少?是平台能力不够强吗?其实不是的,本质原因在于业务开发根本不想理解这众多的字段。
所以这个 PaaS 平台只允许用户填个别字段,其实反倒是帮助业务开发人员避免了这些灵魂拷问。但反过来想,屏蔽掉大量字段真的就解决问题了吗?这种情况下,整个组织的基础设施能力还如何演进?应用开发和应用运维人员的诉求又该怎么传递给基础设施呢?
实际上,归根到底,Kubernetes 是一个 Platform for Platform 项目,它的设计是给基础设施工程师用来构建其他平台用的(比如 PaaS 或者 Serverless),而不是直面研发和运维同学的。从这个角度来看,Kubernetes 的 API,其实可以类比于 Linux Kernel 的 System Call,这跟研发和运维真正要用的东西(Userspace 工具)完全不是一个层次上的。你总不能让本来写 Java Web 的同学每天直接调用着 Linux Kernel System Call,还给你点赞吧?
第二, K8s 实在是太灵活了,插件太多了,各种人员开发的 Controller 和 Operator 也非常多。
这种灵活性,让我们团队开发各种能力很容易,但也使得对于应用运维来说, K8s 的这些能力管理变得非常困难。比如一个环境里的不同运维能力,实际上有可能是冲突的。
我们来看一个例子,基础设施团队最近开发上线了一个新的插件,叫做 CronHPA,一个具体的 Spec 如下所示。
作为基础设施团队,我们觉得这种 K8s 插件很简单, CRD 也很容易理解。就像这个 CronHPA 的功能,从早上六点开始到下午七点钟这个实例最少有 20 个、最多有 25 个,到第二天早上六点钟最少 1 个、最多有 9 个,在每个阶段会根据 CPU 这个指标衡量调整实例数。
然而,就在我们美滋滋的上线这个插件后不久,应用运维同学就开始跟我们抱怨了:
- “这个能力到底该怎么使用呢?它的使用手册在哪里?是看 CRD 还是看文档呢?”
- “我怎么知道这个插件在某个集群里有没有装好呢?”
- “我们运维不小心把 CronHPA