Kubernetes 这东西,光看名字可能觉得离自己很远,但只要是做后端、运维或者云原生相关工作的,早晚要跟它打交道。我早年刚接触 K8s 的时候,最头疼的就是面对一摞陌生的术语:API Server、etcd、controller、scheduler、kubelet 这些词在文档里反复出现,但没人告诉我它们到底各自在干嘛,整个系统是怎么协作起来的。直到后来自己动手搭集群、排查问题、读源码,才慢慢把这张拼图拼完整。这篇博文就从组件这个角度切入,把控制面、工作节点、核心交互逻辑逐层拆开讲清楚,适合刚入门 K8s、或者已经用过但总觉得概念模糊的读者,目标是让你看完之后,脑子里能有一个清晰的组件地图。
1. 整体架构与控制面核心组件解析
要理解 Kubernetes 组件,首先要明白它的整体设计哲学。K8s 采用的是控制面与工作节点分离的主从架构,控制面负责决策和状态管理,工作节点负责实际运行容器。类比一下,控制面像一个公司的管理层,负责制定计划、审批任务、监控全局;工作节点像一线执行团队,只负责把手头的活儿干完,定期向管理层汇报状态。
1.1 控制面的总体职责与协作模型
Kubernetes 控制面由几个组件共同构成,这些组件各自独立运行,又通过 API 互相协作。这里有一个很重要的设计理念:所有组件之间的通信都是通过 API Server 进行的,组件与组件之间不直接访问数据库、不直接调用对方接口,全部走一层统一的门面。这种设计带来的好处是解耦,任何组件被替换或升级时,只要它还能跟 API Server 交互,整个系统就不受影响。
控制面最核心的职责可以概括为三件事:存储和分发集群状态、响应外部请求并对资源进行编排、持续对比期望状态和实际状态并执行修正。这三件事分别对应着 etcd、API Server 加 Controller Manager、Scheduler 加 Controller Manager 的组合。听起来有点绕,我建议你不要按文档顺序去死记,而是按“数据从哪来、决策在哪做、动作由谁发出”来理解。
先记住控制面组件清单:etcd、kube-apiserver、kube-controller-manager、kube-scheduler,另外还有一个选配的 cloud-controller-manager,一般只有在云厂商环境里才会用到。我先逐个讲清楚每个组件是干什么的,再把它们串起来。
1.2 kube-apiserver:所有请求的唯一入口
kube-apiserver 是 Kubernetes 最重要的组件,没有之一,因为它是全系统唯一和 etcd 直接打交道的组件。所有其他组件、kubectl 命令行工具、外部客户端,需要读写集群状态时都只能找它。它暴露的是 RESTful API,也就是通过 HTTP 请求来操作各种资源对象,比如 Pod、Deployment、Service、ConfigMap 等等。
API Server 的具体工作可以分成这几块:
- 身份认证与鉴权:每个请求必须携带证书或 Token,API Server 验证身份后,再通过 RBAC 机制判断这个用户或组件有没有权限执行相应操作。
- 校验与准入控制:请求进入后,先做合法性校验,比如字段格式对不对、引用的资源是否存在;然后经过 Admission Controller 准入控制,这部分可以做一些策略化的干预,比如自动为 Pod 注入 Sidecar、强制打标签、限制资源配额之类。
- 状态持久化:通过后,API Server 把对象序列化写入 etcd,同时负责监听 etcd 的变化,把变更推送给所有关心这些资源的客户端。
从工作负载角度来看,API Server 是整个集群的数据中枢。比如你运行 kubectl apply -f nginx.yaml,这条命令本质上就是向 API Server 发送一个创建 Deployment 的 POST 请求。API Server 接受后校验、写入 etcd,然后通知所有相关组件,这个新对象需要协调处理。也就是说,你看到的“创建 Deployment”,在底层其实就是对 API Server 的一次 HTTP 调用。
实操中有几个容易踩坑的点。我见过不少人以为 Pod 跑不起来要查 kubelet 日志,结果发现请求根本没到 kubelet 这层,而是被 API Server 的准入控制拦截了。排查这类问题时,第一件事就是看 API Server 日志,它会把请求认证失败、鉴权拒绝、校验报错等信息都记录下来。另外,API Server 的高可用部署通常用负载均衡器在前面挂多个实例,注意它本身是有状态依赖的——依赖 etcd,但 API Server 各实例之间是无状态的,因为状态全在 etcd 里。
1.3 etcd:集群状态的唯一权威存储
etcd 是一个分布式的键值存储数据库,Kubernetes 用它保存所有资源对象的定义和状态。可以理解为整个集群的“脑皮层”,所有记忆都存放在这里。API Server 是唯一能读写 etcd 的组件,其它任何组件都不能直接访问它。这种设计大幅度降低了并发冲突和一致性问题,因为对 etcd 的所有访问都收敛到一个组件。
etcd 本身采用 Raft 一致性算法,保证多个节点之间的数据强一致。生产环境通常部署三个或五个节点,这样即使挂掉少数节点,集群仍能正常读写,不会丢数据。为什么是奇数个节点?因为 Raft 算法需要多数派同意才能提交写入,三个节点容忍一台故障,五个节点容忍两台故障。
关于 etcd 的实操,我要强调两个点。第一是备份的重要性。etcd 里面存着集群的全部状态,一旦数据损坏且没有备份,整个集群的资源定义就全没了。常见的备份方式是定期执行 etcdctl snapshot save,保存快照文件,然后离线保存或放到对象存储。第二是性能监控。etcd 的性能直接影响 API 请求延迟,如果集群规模很大,很多小对象频繁更新,etcd 压力会很大。日常关注 etcd 的磁盘 fsync 延迟、DB 大小、Leader 选举次数这几个指标,能提前发现隐患。
很多人容易把状态数据和应用数据搞混。etcd 里存的是 Deployment 的定义、Pod 的期望状态、Service 的 Endpoint 列表这类元数据,不存业务日志、不存数据库内容。容器跑起来后的实际输出、文件写入都在节点本地磁盘或存储卷里,etcd 不关心这些。搞清这个边界对理解系统架构非常重要。
1.4 kube-scheduler:决定 Pod 跑去哪台机器
kube-scheduler 的核心任务是给新创建的 Pod 挑选一个最合适的节点。它盯着 API Server 的资源变化,一旦发现有还没有被调度到节点的 Pod,就按一套复杂的算法来选节点,然后通过 API Server 把绑定关系写回集群。
调度过程分为两个阶段:过滤器加打分。过滤器阶段先把不满足条件的节点排除掉,比如节点资源不足、有节点亲和性限制不满足、污点不兼容等。打分阶段则对剩余节点根据一系列优先级策略打分,例如资源余量越均衡得分越高、符合 Pod 亲和性得分越高。最终得分最高的节点就被选为调度目标。
这里分享一个常见误解:很多人以为调度器把 Pod 调度到某台机器后,Pod 就立刻在那台机器上运行了。实际上,调度器只是做了一次决策,把“这个 Pod 应该去 Node A”这一结论写入 etcd。真正让容器跑起来的是目标节点上的 kubelet,它通过 API Server 看到有新的 Pod 被分配给自己,才会去拉镜像、创建容器。
如果你在运维中遇到 Pod 一直处于 Pending 状态,大概率是调度器找不到合适的节点。常见原因包括节点资源不足、存在不匹配的污点与容忍、节点被打了调度不可用的标记。此时可以用 kubectl describe pod 查看调度失败的原因,它会给出明确的错误信息,比如 0/5 nodes are available: 5 Insufficient cpu。
1.5 kube-controller-manager:运维大脑与状态纠偏
controller-manager 是一个运行着海量控制器的进程,这些控制器关注的是一种叫“期望状态”的东西。Kubernetes 的核心哲学之一是声明式管理:你告诉系统目标是什么,系统自己去想办法达成。controller-manager 就是那个持续对比期望状态与实际状态、负责纠偏的执行引擎。
常见的控制器包括 Deployment Controller、ReplicaSet Controller、StatefulSet Controller、Node Controller、Namespace Controller 等等。每个控制器都通过 API Server 监听自己关心的资源变化,然后做出相应动作。举一个具体场景:你创建了一个 Deployment,声明要有三个副本。ReplicaSet Controller 看到当前副本数不足三个,就调用 API 创建三个 Pod 对象;之后如果某个 Pod 被误删,控制器发现实际数变少,又会立刻补一个新的。正是因为这套机制,Kubernetes 才能实现不停机自愈。
从实现角度讲,控制器采用"调谐循环"的设计模式:每轮循环从 API 获取期望状态和实际状态,计算差异,执行修正动作,循环往复。这种模式的好处是鲁棒。即使某次修正动作失败,下一轮循环还会再次尝试;即使控制器重启了,它也会在恢复后凭借 API Server 里的状态信息重新拉起全套任务。几乎所有业务里的“自动修复”需求,都能在 Kubernetes 里用这种模式优雅实现,这也是它最有价值的设计思想之一。
2. 工作节点组件与容器运行机制
控制面负责决策,真正让容器跑起来的是工作节点。每个工作节点上都运行着一组固定组件:kubelet、kube-proxy、容器运行时(通常为 containerd)。这些组件的协作模式和控制面有所不同,它们要处理的是具体节点上的事务,比如拉取镜像、启动容器、配置网络规则、上报状态。
2.1 kubelet:节点上的"管家"
kubelet 是每个节点上最重要的代理组件,负责管理本节点上所有 Pod 的生命周期。它持续监听 API Server,看有没有新 Pod 被调度到本节点,一旦发现,就负责去跟容器运行时交互,把容器拉起来。它同时还要定期向 API Server 上报本节点的状态,包括资源使用情况、节点的 Ready/NotReady 条件等。
kubelet 的工作可以拆成几步:从 API Server 获取分配到本节点的 Pod 清单,从镜像仓库拉取镜像,调用容器运行时创建容器,持续监控容器的健康状态,在容器异常退出时根据重启策略决定是否重启。它还负责执行探针(Probe)检查,比如 liveness probe 检测容器是否还活着,readiness probe 检测它是否已经可以接收流量。某一项探针失败,kubelet 就会采取相应措施,要么重启容器,要么从 Service 后端列表里摘除。
实操中,kubelet 是让人又爱又恨的组件。它出问题时,症状往往很直观,比如 Pod 卡在 ContainerCreating、无法启动、反复 CrashLoopBackOff。这时候不要急,先看 kubelet 日志,通常在 /var/log 目录或通过 journalctl -u kubelet 查看。日志里会直接告诉你镜像拉不下来的原因、容器启动失败的原因、健康检查失败的原因。
再强调一个细节:kubelet 与 API Server 的通信中,节点证书需要更新。证书过期是生产环境中比较常见的事故原因之一,会导致 kubelet 无法上报状态,节点在控制面那边被标记为 NotReady。如果不对接自动证书续期流程,务必记好证书到期时间,提前规划轮换流程。我见过不止一次因为证书过期导致整批节点从集群里"消失",排查起来会让人非常焦灼。
2.2 容器运行时:真正启动容器的地方
容器运行时是实际执行容器创建和生命周期管理的组件,Kubernetes 通过 CRI 标准接口与它交互。当前主力运行时是 containerd,更早的时候常见的是 docker,但 K8s 从 1.24 版本开始就移除了对 Docker 直接作为运行时支持的代码,推荐的底层运行时就是 containerd,或者其它符合 CRI 标准的运行时比如 CRI-O。
作为用户,大多数时候不需要直接跟容器运行时打交道,但了解它有几个好处。第一,排查问题时,crictl 工具比 docker 命令更通用,它可以统一查看 containerd 管理的 Pod 和容器,包括容器状态、日志、镜像列表。第二,当容器启动异常时,可以绕过 kubelet 直接用运行时工具手动创建一下容器,帮助判断问题是出在 kubelet 配置,还是镜像本身有问题。
运行时的选择会直接影响节点资源占用和稳定性。在 Docker 时代,容器由 docker-engine 加 containerd 加 dockershim 三层协作;移除了 docker 之后,链路缩短为 kubelet 加 containerd,整体更简洁,资源开销也更低。社区往这个方向走,本质上是想减薄抽象层,让系统更容易排查和优化。
需要留个心眼的是镜像仓库的拉取策略和认证。如果节点无法从镜像仓库拉取镜像,最典型的原因是网络不通、镜像不存在、私有仓库凭证缺失或过期。这些问题在 kubelet 日志里都有明确提示,多花一分钟读日志,往往比胡乱重启节点更高效。
2.3 kube-proxy:流量转发与负载均衡的关键实现
kube-proxy 负责处理集群内部的网络代理和负载均衡,它保证了 Service 的虚拟 IP 能够被正确转发到后端 Pod。注意它并不是传统的代理进程,而是通过设置内核规则来实现流量转发,最常用的模式是 iptables 和 IPVS。
具体原理是这样的:当你创建一个 Service,并配置了 Selector 选中若干 Pod,API Server 会不停更新 EndpointSlice 对象,记录这些后端 Pod 的 IP 列表。kube-proxy 监听 Service 和 EndpointSlice 的变化,把规则写入本机内核。当一个客户端访问 Service 的 ClusterIP 时,流量经过内核规则被 DNAT 到某一个后端 Pod。
那它跟 kubelet 有什么区别?kubelet 负责的是 Pod 和容器的运行,kube-proxy 负责的是网络转发规则。两者是两个维度的事情,即使某个节点上没有运行任何业务 Pod,只有 kube-proxy 在,Service 的转发规则依然会在必要时建立。
实际运维中,用 IPVS 模式通常能获得更好的性能和更灵活的调度算法(比如加权轮询、最少连接等),但配置比较复杂。默认 iptables 模式对大多数中小集群都够用,性能瓶颈通常集中在规则数量极大时。如果集群规模非常大,或者流量模式复杂,再评估切换到 IPVS。想验证 kube-proxy 是否正常,可以在一台节点上访问 ClusterIP,再配合 tcpdump 抓包来验证流量是否被正确转发。
2.4 组件的颗粒度与跨节点协作示例
为了把这些组件真正串起来,这里模拟一次完整的应用发布流程:用户执行 kubectl create deployment nginx --image=nginx:latest。
整个过程的推进顺序大致如下:
- kubectl 命令把创建请求发送到 API Server。
- API Server 校验请求后,将 Deployment 对象写入 etcd。
- Deployment Controller 监测到新的 Deployment,发现它需要三个副本,于是创建 ReplicaSet 对象。
- ReplicaSet Controller 随后发现当前 Pod 数为零,于是创建三个 Pod 对象。
- Scheduler 监测这三个未调度的 Pod,逐一挑选合适的节点,将绑定关系写回 API Server。
- 目标节点的 kubelet 发现新 Pod 被分配到自己,拉取 nginx 镜像,通过 containerd 启动容器。
- kubelet 持续上报 Pod 状态,最终 API Server 记录的所有 Pod 变成 Running。
每一步看起来都不复杂,但正是组件间的这种高度专一和清晰分工,让 Kubernetes 能够支撑大规模集群的自动化管理。如果你把前面每个组件的作用再对照一遍,会发现整个过程确实没有一个组件负责面面俱到,每个组件只管自己那一亩三分地。
3. 通用关键机制与组件间通信原理
组件之间不是凭空"自动协作"的,它们依赖一套完整的 API 与事件机制。了解这套机制的底层逻辑,能让你在排查故障时站得更高,不只是盯着某个组件看,而是能把故障现象投射到整条协作链路里。
3.1 声明式 API 与最终一致性的设计取舍
Kubernetes API 是声明式的,这意味着你提交的是一个"期望状态",而不是一组"待办命令"。比如,你写一份 Deployment YAML,声明"我要三个副本",系统自己去决定先创建 ReplicaSet,再创建三个 Pod。这比命令式操作更复杂,但它带来了一个巨大的优势:自动纠偏。系统不会因为某一步中断就停摆,它会在下一次循环中重新对比期望和实际状态,自己补上没做完的工作。
这种思路的灵感来自于控制理论里的"闭环反馈",实际效果也像一个恒温器:温度低了就加热,高了就停止加热,永不休止。你不需要告诉恒温器"下一步干什么",只需要设定好目标温度。这个比喻套到 Kubernetes 上非常贴切。这也是为什么 K8s 能非常适合做弹性伸缩、自愈、滚动更新这类自动化能力,因为它的架构天然允许以"状态差"为驱动来执行一切操作。
理解这个思想后,你再去看 Deployment、Service、HPA 这些资源对象,就不会觉得它们是孤立的配置数据,而是一整套"期望状态 + 调谐回路"的实现。
3.2 控制器模式:从状态差到自愈能力
"控制器模式"不仅仅是 controller-manager 里的实现方式,它几乎贯穿了 K8s 的所有核心抽象。一个控制器循环通常有四个步骤:
- 从 API Server 获取期望状态(比如 ReplicaSet 期望三个副本)。
- 获取实际状态(比如当前运行的 Pod 列表)。
- 计算两个状态的差异。
- 调用 API Server 执行修正动作(比如创建缺失的 Pod 或清理多余的 Pod)。
这个模式在 Node 层面也一样存在。Node Controller 会定期检查节点的健康状态,如果发现节点失联超过阈值,就会把节点上的 Pod 标记为缺失,并触发重建到其它节点。这种机制意味着故障恢复未必需要人工介入,系统自己就能做大量自愈工作。
但在使用这个能力时,有个前提值得留意:对于有状态应用,比如数据库或队列服务,自愈重建并不等于零丢失。控制器确实能创建新 Pod,但新实例的数据恢复通常需要依赖持久化存储和备份。如果完全不考虑数据复制,节点宕机后看似 Pod 重建了,底层数据可能还只存在于旧节点上,这个坑对新手是很有迷惑性的。
3.3 API 对象的字段、Group 与版本演化
接触 K8s 时经常看到 apiVersion: apps/v1 这样的字段。这个字段表示的是 API 资源的 API 组和版本。Kubernetes 把资源分为不同 Group,例如 apps 组包含 Deployment、StatefulSet 等,core 组包含 Service、Pod 等。版本则用来表示资源结构的演进,比如 v1beta1 是测试版结构,v1 是稳定版。
理解 Group 和 Version 的实际意义在于升级兼容性。旧集群上的资源可能使用旧版本 API,升级 K8s 后某些 API 版本会被弃用,对应的 YAML 清单可能需要改写新版本字段。提前检查资源清单中使用的 apiVersion 可以避免升级事故。我建议在集群升级前,用 kubectl convert 工具结合文档检查所有资源清单,千万别只盯着工作负载,Service、Ingress、CRD 这些都可能是升级引爆点。
另一个复杂的点是 CRD。CRD 允许你自定义新类型的 API 资源,让 K8s 能管理你自己的领域对象。比如 Prometheus Operator 就通过 CRD 定义了 Prometheus 和 ServiceMonitor 这类资源。理解 CRD 和控制器模式之后,你可以把任何"期望状态能被代码调谐的对象"都接入 Kubernetes。这也是为什么 K8s 能从一个容器编排器长成一套"声明式基础设施操作系统"的核心原因。
4. 组件层面的故障实战排查手记
理论讲完了,下面进入实战。基于我多次的排查经历,把组件层面最常见的故障现象、排查路径和解决手段整理成列表,方便按图索骥。请注意排查的第一步一定是先确认"现象",然后再定位组件,而不是在多个组件日志里打转。
4.1 Pod 一直 Pending:先问调度器
现象是 Pod 长时间停留在 Pending,查 API Server 没有报错,节点状态也正常。这种问题大概率出在调度层。当前首要排查动作是 kubectl describe pod ,输出的 Events 字段会显示调度失败原因。
常见原因可以归纳为三类:
- 节点资源不足:CPU、内存、GPU 等任何要求超过节点可用量。优先看节点状态里 Allocated resources,区分 Request 与 Limit 的差异。
- 调度约束不满足:节点亲和性、污点与容忍条件不匹配。需要检查 Pod 的 nodeSelector、affinity、tolerations 配置。
- 节点被标记不可调度:节点上有 node.kubernetes.io/unschedulable 污点,或者没有 Ready 条件。用 kubectl get nodes 查看节点状态与污点即可。
需要注意的一个细节是:调度失败的信息不会出现在 kubelet 日志里,因为请求还没到节点。如果你一直盯着 kubelet 找原因,方向就错了。
4.2 容器反复 CrashLoopBackOff:分清退出码
CrashLoopBackOff 表示容器启动后反复崩溃。这个状态之所以让人迷惑,是因为表面看 Pod 是存在的,但容器却顽固地退出。排查重点是容器退出码和日志。
先用 kubectl logs 查看容器日志,如果没有日志,用 kubectl describe pod 看 State 和 Last State 里的 Exit Code。常见退出码对应的问题包括:
- 退出码 0:容器主动退出,可能是任务类运行完就退出,但 Deployment 期望它常驻,需要调整启动命令让它保持前台运行。
- 退出码 1:一般是应用启动时检查失败,比如配置读取错误、端口绑定失败、依赖服务没就绪。
- 退出码 137:代表被强制 SIGKILL 杀死,最常见原因是容器超过内存 Limit 触发了 OOM,查看 Last State 里的 OOMKilled 字段。
- 退出码 143:容器收到 SIGTERM,常见于手动停止或滚动更新时优雅退出超时。
在广东话有句话叫"痛过才知死",这些退出码背后的意义,都是我在一次次容器崩溃里练出来的。生产环境里,遇到 CrashLoopBackOff 时还要检查探针是否误判。有时容器进程没问题,但 readinessProbe 检测路径不对,kubelet 会一直不把容器标记为就绪,导致它无限重启。
4.3 节点显示 NotReady:检查 kubelet 与运行时健康状态
节点 NotReady 意味着 kubelet 无法正常上报状态给控制面。节点层面的问题往往影响面广,可能导致所有业务 Pod 迁移或被重建,需要在集群层面规划好容量冗余。
排查顺序建议如下:
- 登录节点,执行 systemctl status kubelet 查看 kubelet 服务的运行状态。
- 查看 kubelet 日志里的错误信息,常见的有证书过期、kubelet 无法连接 API Server、容器运行时连接失败。
- 检查容器运行时状态,比如 crictl info 是否正常返回。
- 检查节点资源:磁盘空间不足、inode 耗尽、内存不足都可能让 kubelet 变得不健康,kubelet 会主动将该节点标记为 NotReady 以保护集群。
一个容易被忽略但高频的坑是磁盘压力过大。kubelet 检查到节点磁盘使用率超过阈值(默认 85%)后,会开始驱逐节点上的部分 Pod,并可能将节点置为压力状态。如果你发现节点 NotReady 的同时还在大量清理镜像,这大概率不是网络问题,而是磁盘空间问题。
4.4 组件日志查看快捷手册
为了快速定位问题,我整理这套组件日志查看速查表,建议收藏到自己的运维手册里:
| 组件 | 日志位置 / 查看方式 | 常见排查场景 |
|---|---|---|
| API Server | 静态 Pod 方式:kubectl logs -n kube-system kube-apiserver- | 请求被拒绝、鉴权失败、准入控制报错 |
| Controller Manager | kubectl logs -n kube-system kube-controller-manager- | Deployment、ReplicaSet 不按期望创建或删除 |
| Scheduler | kubectl logs -n kube-system kube-scheduler- | 调度失败、Pending 状态、调度策略不生效 |
| etcd | 依赖部署方式,默认通过 etcdctl 配合日志 | 数据读写异常、长时间延迟、快照失败 |
| kubelet | journalctl -u kubelet -f | 容器启动失败、节点 NotReady、健康检查报错 |
| 容器运行时 | crictl logs、crictl ps | 容器拉取仿真失败、运行状态异常 |
4.5 一次典型故障复盘:镜像拉取失败引发的连锁问题
最后分享一个我实际处理过的案例。某次生产环境发布新版应用后,部分 Pod 卡在 ContainerCreating,并且集中在某几个节点。最初怀疑是镜像仓库不稳定,但单独在这几个节点上手动 crictl pull 却成功。这就有点诡异了。
检查 kubelet 日志后发现,kubelet 在反复重试拉取,但报错却是"image pull deadline exceeded"。手动能成功但 kubelet 失败,说明问题不是仓库而是 kubelet 与运行时之间的镜像缓存同步。后来发现这几个节点的根分区磁盘空间不足,导致 containerd 在拉取镜像后写入镜像层时超时。手动 pull 时镜像已经被缓存,所以检查不出问题。
清理掉这些节点上的无用镜像和日志文件后,Pod 陆续恢复。这个案例想说明的是,K8s 的故障往往不是孤立的,一个磁盘告警可能引发一连串看起来像网络问题、仓库问题、调度问题的假象。排查时千万别只看表面症状,要顺着链路往下多摸一层,很多问题最终都指向资源层,比如磁盘、内存、文件描述符。
5. 从组件到集群:给新手的几条实操建议
组件讲完了,最后说点经验层面的东西。如果你是刚开始搭建和运维 K8s,这里有三条建议我觉得最值得先刻在脑子里。
第一,不要在组件多而复杂时想着一步到位,先跑通最小集群再说。所谓最小集群,最朴素的理解就是一台控制面加至少一台工作节点。你可以在物理机、虚拟机里手动部署,也可以直接用 kubeadm 初始化。这个过程中,你会亲手看到 API Server、etcd、controller-manager、scheduler、kubelet 这些进程被拉起来的顺序和配置方式。比自己幻想"只要敲几行命令就会神奇地跑起来"要踏实得多。
第二,各种"全家桶"工具确实很方便,但不能替代你对每个组件的认识。只用一键脚本或托管服务的人,遇到问题往往只能干瞪眼。真正把集群从零搭一次,你才会理解证书该怎么签发、清单里每个配置的作用是什么、某个组件崩溃时怎么自救。等你能在裸集群上完成一次应用发布、一次节点宕机恢复演练,再回过去用工具类产品,会觉得底气和判断力完全不同。
第三,推荐去试着读一读《深入理解 Kubernetes 源码》这类材料,但不建议一上来就硬啃。更可行的路径是:先跑通基本操作,再在遇到具体故障时针对性地翻阅某个组件的实现。比如你好奇 scheduler 为什么选这台节点不选另一台,就去读它的调度策略源码。带着问题去读,效率远高于逐页阅读。源码没有想象中那么可怕,核心流程代码往往都很清晰,读懂了里面提到的 interfaces、workqueue、informer 这些概念,对整个体系的掌握会进一大步。
组件是整个 K8s 的细胞。每个组件职责清晰、接口固定、数据流动有序,这样的架构才撑得起复杂的生产环境。我第一次手动搭集群时,看着 kubeadm init 一行行吐日志,才真正意识到这些组件之间环环相扣的关系。希望你也能在这个探索过程里找到乐趣——哪怕中途被各种奇怪故障折腾到怀疑人生,等集群终于稳定运行的那一刻,前面所有折腾都会变成你最珍贵的经验。