本节摘要:Kubernetes 是源自谷歌内部集群管理系统 Borg 的开源容器编排平台,现由云原生计算基金会托管,是容器编排领域的事实标准。它的聪明之处不在于功能多,而在于把整个集群变成一台"声明式播种机":用户提交期望,控制循环负责达成并维持。本节讲清它的来路、它与命令式工具的本质差别,以及它适合谁、不适合谁。
2003 年前后,谷歌内部运行着一个叫 Borg 的集群管理系统,掌管着公司数十亿容器级别的日常调度,搜索、邮件、地图都长在它上面。Borg 的核心思想只有一句话:资源池化,声明驱动。工程师不指定机器,只描述负载;Borg 决定放哪、何时迁移、怎么让位。2014 年,几位 Borg 老兵把这套思想以开源形式重写,起名 Kubernetes,希腊语"舵手"。次年交给云原生计算基金会孵化,此后逐步成为容器编排的事实标准——各大云厂商的托管集群、绝大多数企业的云原生底座,都建立在它之上。
对我这种用过脚本时代的运维的人,第一次用 Kubernetes 的震撼不在界面,而在心智模型的变化:以前我在意"怎么把容器启动起来",现在我在意"我希望田里是什么样"。前者的产物是一堆一次性命令的历史,后者的产物是一份可以入库、可以评审、可以回滚的期望状态档案。
命令式工具(脚本、手工指令)回答"怎么做",声明式系统回答"要什么"。差别看似微妙,落到工程上是天壤之别:
| 维度 | 命令式(脚本/手工) | 声明式(Kubernetes) |
|---|---|---|
| 交付物 | 一串执行过的命令,事后难追 | 一份 YAML 清单,可入库可评审 |
| 状态偏离 | 没人管,越漂越远 | 控制循环持续扳回期望 |
| 重复执行 | 可能重复加盆,要人防 | 天然幂等,重复 apply 无害 |
| 故障恢复 | 依赖人的记忆 | 系统按清单重建 |
| 协作方式 | 口口相传加交接文档 | 以清单为准,见单如见田 |
第二行是灵魂。上一节事故夜里所有的问题,都可以概括成"实际状态与合理状态脱节,而没有人负责扳回来"。Kubernetes 里管扳回来的角色叫控制器(园丁),它的工作方式是一个永不停歇的循环:观察实际,对比期望,采取行动。这套循环有一个正式名字,控制循环,第二章会拆开细讲。
空谈无益,先看一份最小的"种子袋"。虽然此刻你还没有集群(第九章才开试验田),但这份单子的样子值得先记住:
# 一份最小播种单:期望田里有三个网页盆 apiVersion: apps/v1 kind: Deployment # 单据类型:一份播种计划 metadata: name: greenlib-web # 这茬作物的名字 spec: replicas: 3 # 期望株数:三 selector: matchLabels: app: greenlib-web # 认苗方式:按标签认 template: metadata: labels: app: greenlib-web spec: containers: - name: web image: greenlib/web:0.9.1 # 图纸版本
提交它只需一条命令,输出也朴素:
kubectl apply -f web-deployment.yaml # deployment.apps/greenlib-web created
从这一刻起,"田里要有三个网页盆"就成了集群公认的期望状态。某个盆死了,园丁会补;你把株数改成五,园丁会加;你改回三,园丁会减。**你不再指挥动作,你只维护档案。**这就是手册把 YAML 叫种子袋的原因:袋子上写的是品种和数量,不是耕作步骤。
编排系统曾经百花齐放,Mesos、Swarm、Nomad 都各有拥趸,最后 Kubernetes 胜出,我认为有三层原因:
入门册也要把边界说清楚,免得期望错位:
💡 一个可以直接带走的判断标准:当"保持系统正常运行"开始消耗你的注意力,就到了把注意力换成清单的时候。Kubernetes 经营的就是这笔交换。
绿荫书屋正是如此:事故夜之后,团队决定把书屋迁进集群。下一章我们就去认地,看看这台播种机内部长什么样——控制平面里的几个科室各自管什么,工作节点上的落苗人如何干活,以及为什么所有种子都必须从 API Server 这扇门进地。
不是一条赛道。Docker 解决"怎么把一株苗装进花盆",Kubernetes 解决"怎么经营一片田"。田里的每株苗几乎都来自 Docker 格式的图纸,容器运行时至今与这套生态兼容。真正被 Kubernetes 替代的,是"手工经营"这件事本身。
Kubernetes 的 K 与 s 之间隔着八个字母,取首尾加八便成了圈内通行的简写。读法不拘一格,正式文档里仍写全名,聊天里怎么省事怎么来。