前言
刚开始接触 Kubernetes 时,我最先看到的是一堆 kubectl 命令,但真正让我困惑的其实是:这些命令背后的 Kubernetes 到底在解决什么问题?
我试着从一个更熟悉的场景来理解它。
如果把应用部署比作开餐馆,最开始可能只有一个小店:一台机器、一个进程、几个接口。老板自己盯着就行,进程挂了就手动重启,访问量大了就临时加机器。
但当店越来越多,问题就来了:谁负责排班?谁负责检查店铺是否营业?某个店停电了,订单怎么转到别的店?新菜单上线,怎么不影响正在吃饭的顾客?
Kubernetes 做的事情,就像给这些“店铺”配了一套调度和管理系统。
一句话概括:
Kubernetes 是用来管理容器化应用的声明式自动化平台。
我把这句话拆成了三层:
- 容器化:应用以容器形式运行;
- 声明式:人来描述“希望得到什么结果”;
- 自动化:系统持续检查并修正实际状态。
从一台机器开始看问题
假设现在有一个后端服务,最简单的运行方式是:
1 | java -jar app.jar |
在个人项目里,这样完全可以。但服务一旦变重要,问题就会陆续冒出来:
- 进程崩了,谁拉起来?
- 机器宕机了,服务去哪里跑?
- 访问量变大了,怎么增加实例?
- 发布新版本时,怎么避免一下子全挂?
- 多个服务之间,怎么找到彼此?
- 配置、密钥、日志、数据,怎么统一管理?
这时如果只靠人工和脚本,系统会越来越像一张手写排班表:刚开始能用,规模一大就容易乱。
1 | 单机时代 |
所以 Kubernetes 想解决的,就是把“盯机器、盯进程、手动修复”变成“声明目标、自动调度、自动恢复”。
Kubernetes 的核心思想:人来定目标,系统来维护
先对比一下传统脚本。脚本更像是在写步骤:
1 | 先启动 A |
Kubernetes 的思路不一样。它更像是给系统写一张“目标清单”:
1 | 我希望 demo-api 这个应用: |
然后 Kubernetes 会不断检查现实是否符合这张清单。
1 | 期望状态:3 个副本 |
这就是我目前对“声明式”的理解:人重点描述结果,系统负责追结果。
一个最小的 Deployment 示例
下面是一段最小的 Deployment YAML。我第一次看时也觉得字段很多,把它翻译成人话后就清楚了一些。
1 | apiVersion: apps/v1 |
可以把它翻译成人话:
1 | 我要部署一个叫 demo-api 的应用。 |
Kubernetes 收到这份声明后,不是执行一次就结束,而是持续维护它。
控制循环:像一个一直巡检的值班员
Kubernetes 里很重要的一个概念是控制循环。我觉得它很像一个一直在巡检的值班员,不断做三件事:
1 | 读取期望状态 |
例如期望 demo-api 有 3 个副本:
- 某个 Pod 挂了,只剩 2 个:补一个;
- 节点故障,Pod 不见了:换地方重新拉起;
- 镜像版本变了:按策略逐步替换旧版本;
- 多出来 1 个副本:删除多余的。
这也是 Kubernetes 和普通脚本的区别:
1 | 脚本:执行一遍流程 |
集群像一家公司:控制面负责管理,节点负责干活
再往下看,一个 Kubernetes 集群可以先粗略分成两类角色:
1 | Kubernetes 集群 |
控制面像公司的管理层,负责决定“做什么、谁来做、现在状态对不对”。工作节点像具体干活的机器,负责真正运行应用。
控制面里有四个经常出现的组件:
kube-apiserver:前台,所有操作都先到这里;etcd:档案室,保存集群状态;kube-scheduler:调度员,决定 Pod 放到哪个节点;kube-controller-manager:巡检员,持续修正状态。
工作节点里也有三个常见角色:
kubelet:节点上的管家,负责按要求运行 Pod;- 容器运行时:真正启动容器,例如 containerd;
- 网络组件:让 Pod 之间、服务之间能够通信。
这些名字放在一起有点多,我目前先把它们概括成一句话:控制面负责“管”,工作节点负责“跑”。
Pod:Kubernetes 里的最小房间
在 Docker 里,我们经常说“启动一个容器”。但在 Kubernetes 里,最小调度单位不是容器,而是 Pod。
我把 Pod 理解成一个小房间,容器住在房间里。
1 | Pod: demo-api |
大多数入门场景,一个 Pod 里只有一个业务容器。
有些场景下,一个 Pod 里会有多个容器,它们像住在同一间房的室友,共享网络和部分存储:
1 | Pod: demo-api |
看到这里我有一个疑问:为什么 Kubernetes 不直接管理容器,而是管理 Pod?
我的理解是:有些容器天然需要绑在一起运行。Pod 提供了一个更稳定的抽象:同一个 Pod 里的容器一起调度、共享网络、生命周期更接近。
Deployment:不要自己盯着每个 Pod
再看 Deployment。它存在的前提是:Pod 是会消失的。
节点故障、版本发布、资源调整,都可能导致 Pod 被删除和重建。如果直接管理 Pod,就像自己一个人盯着每个临时工:谁走了、谁来了、谁没干活,都要手动处理。
Deployment 就是更高一层的管理者。它不只关心某一个 Pod,而是关心“一组 Pod 应该保持什么状态”。
1 | Deployment |
Deployment 主要负责:
- 保持副本数量;
- 支持滚动发布;
- 支持回滚;
- Pod 少了就补,多了就删。
所以日常部署无状态服务时,通常不是直接创建 Pod,而是创建 Deployment。
Service:给变化的 Pod 一个稳定门牌号
最后是 Service。Pod 会重建,IP 也可能变化。如果其他服务直接访问 Pod IP,就像把朋友家地址记成“今天住在哪个酒店房间”。一旦换房间,地址就失效了。
Service 的作用,就是给一组 Pod 提供一个稳定入口。
1 | 调用方 |
Service 不需要固定写死 Pod 列表,它通过标签选择器找到后端 Pod。
1 | Service selector: app=demo-api |
这样 Pod 可以增加、减少、重建,调用方仍然访问 Service 这个稳定入口。
把几个概念串起来
梳理到这里,我把几个核心关系串成了一张图:
1 | 用户声明 YAML |
如果这张图还能再压缩,可以记成:
1 | Kubernetes = |
小结
Kubernetes 不是单纯的容器启动工具。它更像一个集群管理系统:我们声明应用应该长什么样,它持续检查现实世界,并尽量把现实修正到目标状态。
这一篇整理下来,我目前得到的结论是:
- 控制面负责管理集群;
- 工作节点负责运行应用;
- Pod 是最小运行单位;
- Deployment 维护一组 Pod;
- Service 给变化的 Pod 提供稳定入口;
- Kubernetes 的关键思想是声明式和控制循环。
下一篇准备继续梳理 Kubernetes 的集群架构,重点看看控制面里的几个组件分别负责什么。
参考资料
- Kubernetes Overview:https://kubernetes.io/docs/concepts/overview/
- Kubernetes Cluster Architecture:https://kubernetes.io/docs/concepts/architecture/
- Kubernetes Pods:https://kubernetes.io/docs/concepts/workloads/pods/
- Kubernetes Deployments:https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
- Kubernetes Service:https://kubernetes.io/docs/concepts/services-networking/service/