前言
刚开始接触 Kubernetes 源码时,我以为就是简单的 git clone 就能开始阅读了。结果下载下来一看,30 多个组件、各种 staging 目录、还有一堆生成的代码,完全不知道从哪下手。花了一周时间梳理,踩了不少坑,今天把完整的准备工作和阅读方法分享出来,帮你少走冤枉路。
开发环境准备
选择合适的 IDE
推荐方案:
- GoLand :JetBrains 出品的 Go 语言 IDE,对 Kubernetes 这类大型项目支持最好
- 优点:代码跳转、重构、调试都非常流畅
- 缺点:收费(学生可申请免费授权)
- VS Code + Go 插件 :免费方案,配置好也能用
- 需要安装:
gopls(Go 语言服务器)、dlv(调试器)
- 需要安装:
踩坑记录: 我用 VS Code 打开 k8s 项目时,因为项目太大,gopls 经常崩溃,后来还是换回了 GoLand。如果你电脑配置一般,建议直接上 GoLand,省时省力。
源码下载方式
方式一:下载完整仓库(推荐初学者)
bash
# 克隆主仓库,包含所有核心代码
git clone https://github.com/kubernetes/kubernetes.git
# 切换到稳定版本(本教程基于 1.21 版本)
cd kubernetes
git checkout v1.21.0
注意坑点:
- 主仓库约 1GB+,克隆需要较长时间
master分支是开发分支,代码不稳定,务必切换到 release 标签- Windows 用户可能会遇到路径过长问题,建议在 WSL 或 Linux 环境下操作
方式二:单独下载组件仓库(针对特定模块)
Kubernetes 将核心组件拆分到单独的仓库,方便独立开发和版本管理:
| 组件 | 仓库地址 | 适用场景 |
|---|---|---|
| api | k8s.io/api |
学习资源定义(Pod、Service 等) |
| apimachinery | k8s.io/apimachinery |
通用工具库、Scheme、序列化 |
| client-go | k8s.io/client-go |
客户端开发、与 APIServer 交互 |
| kubelet | k8s.io/kubelet |
节点管理、Pod 生命周期 |
| kube-scheduler | k8s.io/kube-scheduler |
调度算法学习 |
| kube-controller-manager | k8s.io/kube-controller-manager |
控制器模式学习 |
| kubectl | k8s.io/kubectl |
命令行工具开发 |
bash
# 下载单个组件(以 client-go 为例)
go get -d k8s.io/client-go
什么时候用这种方式?
- 你只需要研究某个特定组件(如调度器)
- 电脑磁盘空间有限
- 想避免完整仓库的编译依赖
仓库结构解析
下载完源码后,你会看到以下核心目录:
kubernetes/
├── api/ # OpenAPI 规范定义
├── cmd/ # 各组件的 main 入口
│ ├── kubelet/ # kubelet 主程序
│ ├── kube-apiserver/ # API Server 主程序
│ ├── kube-scheduler/ # 调度器主程序
│ └── kubectl/ # kubectl 主程序
├── pkg/ # 核心包代码
│ ├── kubelet/ # kubelet 实现
│ ├── scheduler/ # 调度器实现
│ └── controller/ # 控制器实现
├── staging/ # 独立组件的代码镜像
│ └── src/k8s.io/ # 对应 k8s.io/xxx 仓库
├── vendor/ # 依赖包
└── build/ # 编译脚本
重要提醒: staging/ 目录下的代码是会被同步到独立仓库的,阅读时优先看 pkg/ 和 cmd/ 目录。
高效阅读源码的 4 个技巧
技巧 1:带着功能看代码
不要一上来就从头开始读,而是:
- 先理解功能:比如你要看 Pod 创建流程,先确保你理解 kubectl create pod 会发生什么
- 带着问题找代码:Pod 是怎么被调度到节点的?kubelet 怎么创建容器?
- 从入口开始追踪:从 cmd/ 下的 main 函数开始,跟着调用链一步步深入
实战示例: 看 Pod 调度流程
bash
# 1. 找到调度器入口
cmd/kube-scheduler/scheduler.go
# 2. 跟踪调度逻辑
pkg/scheduler/scheduler.go
pkg/scheduler/core/generic_scheduler.go # 核心调度算法
技巧 2:多看架构图
阅读源码前,一定要先理解架构。推荐几张必看的图:
- Kubernetes 整体架构图:理解各组件关系
- API Server 处理流程图:理解认证、鉴权、准入控制
- 控制器模式图:理解 Informer、Lister、Workqueue 机制
推荐资料:
- 官方文档架构部分:https://kubernetes.io/docs/concepts/architecture/
- Kubernetes 源码剖析(书籍)
技巧 3:换位思考
看到一段晦涩的代码时,问自己:
- 如果是我来实现,我会怎么做?
- 为什么要这样设计?有什么好处?
- 如果去掉这段代码,会怎样?
举个例子,看调度器的 Filter 和 Score 阶段时,可以思考:
- 为什么分成两个阶段而不是一个?
- 预选(Filter)和优选(Score)的职责边界在哪?
- 如果节点很多,怎么保证性能?
技巧 4:善用调试和日志
本地调试技巧:
bash
# 1. 编译并启动 API Server(本地模式)
make WHAT=cmd/kube-apiserver
./_output/bin/kube-apiserver --etcd-servers=http://localhost:2379
# 2. 使用 delve 调试
dlv debug ./cmd/kube-scheduler
日志追踪技巧:
- 在关键位置添加
klog.Infof()打印变量 - 使用
klog.V(4).Infof()控制日志级别 - 通过
kubectl logs查看组件日志
版本兼容性注意
坑点 1:API 版本变化
- Kubernetes 1.16 后弃用了很多旧版 API(如 extensions/v1beta1)
- 不同版本的 client-go 接口可能完全不同
坑点 2:Go 版本要求
- k8s 1.21 要求 Go 1.16+
- 编译前先用
go version检查版本
坑点 3:依赖版本锁定
- 一定要使用 vendor 目录的依赖,不要用 go mod 自动下载
- 否则可能遇到接口不兼容问题
bash
# 使用 vendor 编译
make WHAT=cmd/kubelet KUBE_BUILD_PLATFORMS=linux/amd64
推荐阅读顺序
如果你是第一次阅读 k8s 源码,建议按以下顺序:
-
先读 API 定义 (
pkg/apis/)- 理解 Pod、Node、Service 等资源结构
-
再看 client-go (
staging/src/k8s.io/client-go/)- 学习如何与 APIServer 交互
-
深入 kubelet (
pkg/kubelet/)- 理解 Pod 生命周期管理
-
研究调度器 (
pkg/scheduler/)- 学习调度算法和框架
-
最后看控制器 (
pkg/controller/)- 掌握控制器模式,这是 k8s 的核心思想
总结
阅读 Kubernetes 源码是一场持久战,不要急于求成。记住这几点:
- 环境准备好:用 GoLand,下载对应版本源码
- 带着目的读:先理解功能,再追踪代码
- 善用工具:架构图、调试器、日志都不能少
- 多思考设计:不要只看实现,要看背后的设计思想
最重要的是:不要试图一次性读完所有代码。Kubernetes 代码量巨大,挑你感兴趣的模块深入,比走马观花看一遍效果好得多。
参考资料:
- Kubernetes 官方 GitHub:https://github.com/kubernetes/kubernetes
- Kubernetes 组件仓库列表:https://github.com/kubernetes/kubernetes/blob/master/staging/README.md
- Kubernetes 官方文档:https://kubernetes.io/docs/