Kubernetes 编程 / Operator 专题【左扬精讲】—— Kubernetes 构建过程
Kubernetes 编程 / Operator 专题【左扬精讲】—— Kubernetes 1.36.1 构建完全指南
Kubernetes 是一个超大型 Go 项目,包含数百个包(package)。本文通过 Makefile 带初学者从零掌握 Kubernetes 的本地构建与容器构建,配有详细的流程图和命令说明。
构建一个如此庞大的项目,光靠手动一条条敲 `go build` 命令是不现实的——光是记住所有包的路径就足以让人崩溃。本文会从零开始,手把手带你掌握 Kubernetes 的构建系统,让你真正理解"一行 make 命令背后发生了什么"。
k8s v1.36.1 Go 1.26+ Docker Build
🔓 学习重点提示 — 建议先通读全文,再重点回顾标注内容
★ 重点掌握(必须)
• 本地构建命令:make all、make kubectl、make WHAT=... 的用法
• 核心构建流程:build.sh → setup_env → build_binaries → place_bins
• WHAT 参数:最灵活的构建粒度控制,建议结合 make help 理解
☆ 次重点(了解即可)
• 容器构建的完整流程:细节较多,实际用 make cross 一条命令就够了
• 跨平台编译:按需查阅,不要求全部背下来
• 环境变量速查表:用到时再查,不需要提前记忆
目录
一、认识 Kubernetes 的构建系统
1.1 什么是构建系统?
想象一下,你写了一段 Go 代码,要把它变成一个可以运行的程序,就需要"编译"。Kubernetes 是一个超大型的 Go 项目,包含了几百个包,如果每次都要手动一条一条命令去编译,那简直是一场噩梦。
构建系统就是来解决这个问题的。你只需要运行一条 make 命令,剩下的事情交给构建系统来完成。它把"写代码"变成"可运行程序"这个过程变得简单、可靠、可重复。
1.2 构建系统里有哪些文件?
Kubernetes 的构建逻辑分散在多个文件中,每个文件各司其职。初学者不需要了解所有文件,只需要记住最重要的几个:
- build/root/Makefile:所有构建命令的"总入口",定义了 make all、make release 等目标
- hack/make-rules/build.sh:本地构建脚本,负责设置 Go 环境并调用编译器
- hack/make-rules/cross.sh:跨平台构建脚本,一次性编译出 Linux、Windows、macOS 等多平台版本
- build/common.sh:容器构建的核心函数库,定义容器启动、镜像检查等通用逻辑
- hack/lib/golang.sh:Go 编译环境配置,包含平台选择、交叉编译工具链设置等
- build/release.sh:完整发布流程脚本:编译 + 测试 + 打包
hack/make-rules/ 下放的是面向用户的"命令脚本",hack/lib/ 下放的是供脚本调用的"函数库",build/ 下放的是容器构建相关的核心逻辑。
1.3 Kubernetes 能构建出哪些东西?
Kubernetes 的构建产物分为四大类,每一类对应不同的使用场景:
| 类别 | 包含组件 | 支持的平台 |
|---|---|---|
| Server 组件 | API Server、Scheduler、Controller Manager | Linux(amd64、arm64、s390x、ppc64le) |
| Node 组件 | Kubelet、Kube-Proxy、Kubeadm | Linux + Windows |
| Client 工具 | Kubectl、Kubectl-Convert | Linux、Windows、macOS 全平台 |
| Test 工具 | Ginkgo、e2e.test、go-runner | Linux、macOS、Windows |
所有构建产物默认输出到 _output/ 目录下。构建完成后,你会在 _output/local/bin/ 下看到各种二进制文件(如 kubectl、kube-apiserver 等)。
二、本地环境构建
本地构建是最常用的开发方式。构建速度快,产物直接在本地,可以直接运行和调试,非常适合日常开发迭代。
2.1 最基础的构建命令:make
# 构建所有 Kubernetes 组件 make # 等价于: make all
这条命令会构建出 Kubernetes 的所有二进制文件。构建完成后,你可以在 _output/local/bin/ 目录下找到 kubectl、kube-apiserver、kube-controller-manager 等可执行文件。
💡 注意
首次构建需要下载依赖并编译所有组件,耗时较长(约 10-30 分钟)。后续增量构建会快很多,因为大量内容已经被缓存了。
# 调试模式构建(不裁剪调试符号,可用于 dlv 调试) make all DBG=1
2.2 构建单个组件
开发过程中通常不需要每次都构建所有组件,只需要构建自己改的那个就够了。
# 只构建 kubectl make kubectl # 只构建 kubelet make kubelet # 只构建 kube-apiserver make kube-apiserver
WHAT 是最灵活的构建参数,可以指定任意包或目录:
# 指定具体包 make all WHAT=cmd/kubectl # 指定多个包 make all WHAT="cmd/kubelet cmd/kube-proxy" # 指定目录(构建目录下所有包) make all WHAT=./pkg/kubelet
2.3 本地构建的完整流程
当你执行 make all 时,背后发生了以下事情:
make all → build.sh → setup_env → go build → place_bins
build/root/Makefile 中的 all 目标会调用 hack/make-rules/build.sh 脚本。这个脚本只有 4 步:
# 第一步:加载初始化脚本(路径处理、日志工具等基础设置)
source "${KUBE_ROOT}/hack/lib/init.sh"
# 第二步:设置 Go 编译环境
kube::golang::setup_env
# 第三步:编译所有指定的二进制文件
kube::golang::build_binaries "$@"
# 第四步:将编译好的二进制文件复制到输出目录
kube::golang::place_bins
setup_env 函数做以下几件事:
- 设置 GOPATH:将输出目录 _output/local/go 设置为 Go 的工作目录
- 设置缓存:配置 Go 编译缓存目录,加快重复构建速度
- 检查版本:验证 Go 版本是否满足要求(Kubernetes 1.36 需要 Go 1.26 或更高)
- 自动下载:如果当前 Go 版本不对,通过 GOTOOLCHAIN 自动下载正确版本
GOPATH 是 Go 语言的工作目录。Kubernetes 的构建系统将 _output/local/go 作为临时 GOPATH,避免污染系统原有的 Go 环境。
build_binaries 是最核心的编译环节,会根据 WHAT 参数确定要编译哪些包,注入版本信息(Git 提交哈希、构建时间等)到二进制文件。
三、容器环境构建
容器构建适合需要跨平台编译、生产发布等场景。它使用 Docker 容器来保证构建环境的一致性。
3.1 为什么需要容器构建?
本地构建虽然方便,但有一个问题 ——"在我机器上能跑"(It Works On My Machine)。不同开发者的机器上可能安装了不同版本的 Go、不同的编译工具链。
容器构建通过使用官方 kube-cross 镜像来解决这个问题:无论你在哪台机器上构建,都使用完全相同的编译环境。
- 环境一致性:所有人都用同一个 Docker 镜像来编译,杜绝"环境差异"导致的构建问题。
- 跨平台支持:在 Linux 机器上也能编译出 Windows 和 macOS 版本的二进制文件。
3.2 发布构建命令
# 完整发布构建(编译 + 测试 + 打包),最全但耗时最长 make release # 跳过测试的快速发布 make release-skip-tests # 最快的发布构建(只编译 linux/amd64 平台) make quick-release
如果只需要构建 Docker 镜像(不需要打包和测试):
# 构建所有 Linux 平台的 Docker 镜像 make release-images # 只构建 linux/amd64 平台的镜像(最快) make quick-release-images # 调试模式构建(保留调试符号) make release-images DBG=1
如果只想编译出二进制文件(不需要打包成镜像),用 make cross:
# 在容器中编译所有平台的二进制文件 make cross # 指定只构建特定平台 KUBE_BUILD_PLATFORMS="linux/amd64 linux/arm64" make all
3.3 容器构建的完整流程
以 make release 为例,完整流程如下:
前置检查 → 启动容器 → 跨平台编译 → 运行测试 → 打包发布
第一步(前置检查):检查 GNU tar 是否安装、Docker 是否在运行。
第二步(启动容器):构建系统会启动一个名为 kube-build-{哈希值} 的 Docker 容器,基于 kube-cross 镜像。源码目录通过 --volume 挂载到容器内的 /go/src/k8s.io/kubernetes 路径。
容器内的编译过程直接读写宿主机的源码目录。编译完成后,产物在你本地的 _output/ 目录里,不会消失在容器里。
第三步(跨平台编译):cross.sh 会按顺序执行多次 make all,每次针对不同的组件和平台组合:
# 第1批:Server 组件(4个 Linux 平台)
make all WHAT="kube-proxy kube-apiserver kube-controller-manager
kubelet kubeadm kube-scheduler ..."
KUBE_BUILD_PLATFORMS="linux/amd64 linux/arm64 linux/s390x linux/ppc64le"
# 第2批:Node 组件(5个平台,包含 Windows)
make all WHAT="kube-proxy kubeadm kubelet kube-log-runner"
KUBE_BUILD_PLATFORMS="linux/amd64 linux/arm64 linux/s390x
linux/ppc64le windows/amd64"
# 第3批:Client 工具(11个平台:Linux + Windows + macOS)
make all WHAT="kubectl kubectl-convert"
KUBE_BUILD_PLATFORMS="linux/amd64 linux/arm linux/arm64 ..."
第四步(构建镜像):二进制编译完成后,release-images.sh 会用多阶段 Docker 构建将二进制文件打包进镜像:
- 控制平面组件(API Server、Scheduler、Controller Manager):使用 go-runner 镜像(基于 distroless,极简、安全、镜像体积小)
- Kube-Proxy:使用 distroless-iptables 镜像
默认镜像地址是 registry.k8s.io。可以在 build/common.sh 中修改 KUBE_DOCKER_REGISTRY 变量来自定义镜像仓库。
四、常用构建命令汇总
4.1 构建命令一览表
| 命令 | 说明 | 推荐场景 |
|---|---|---|
| make / make all | 构建所有组件(本地) | 日常开发 |
| make kubectl | 只构建 kubectl | 只改了 kubectl 时 |
| make kube-apiserver | 只构建 API Server | 只改了 API Server 时 |
| make cross | 跨平台编译(容器) | 需要多平台二进制 |
| make release | 完整发布 | 正式发布 |
| make release-images | 构建容器镜像 | 镜像构建 |
| make quick-release | 快速发布 | 快速验证 |
| make clean | 清理产物 | 需要干净环境时 |
4.2 测试与验证命令
| 命令 | 说明 |
|---|---|
| make test | 运行单元测试 |
| make test WHAT=./pkg/kubelet | 测试指定目录 |
| make test-integration | 运行集成测试 |
| make test-e2e-node | 运行节点 E2E 测试 |
| make verify | 运行所有代码检查 |
| make quick-verify | 快速验证(跳过慢检查) |
| make lint | 运行代码风格检查 |
五、关键环境变量
5.1 常用变量速查
| 变量名 | 作用 | 示例 |
|---|---|---|
| WHAT | 指定要构建的包 | cmd/kubectl |
| DBG | 调试模式(不裁剪符号) | DBG=1 |
| KUBE_BUILD_PLATFORMS | 目标平台 | linux/arm64 |
| KUBE_FASTBUILD | 快速构建(仅本机平台) | true |
| GOFLAGS | 传给 go 的额外参数 | -v |
| GOLDFLAGS | 链接时的额外标志 | -X key=value |
| KUBE_VERBOSE | 输出详细程度(1-10) | 5 |
| OUT_DIR | 输出目录 | ./output |
| GOPROXY | Go 模块代理 | https://goproxy.cn |
| SOURCE_DATE_EPOCH | 可重现构建的时间戳 | git log -1 --format=%ct |
5.2 实战示例
# 指定只构建 ARM64 平台的 kubectl make kubectl KUBE_BUILD_PLATFORMS="linux/arm64" # 启用详细输出 make all KUBE_VERBOSE=5 # 使用国内 Go 代理加速依赖下载 export GOPROXY=https://goproxy.cn,direct # 可重现构建(每次构建的时间戳一致) export SOURCE_DATE_EPOCH=$(git log -1 --format=%ct) make release-skip-tests # 快速构建(只构建本机架构,跳过其他平台) make all KUBE_FASTBUILD=true
⚠️ 警告
注意:KUBE_GOFLAGS 已弃用,请改用 GOFLAGS。两者同时设置会导致构建报错。
🌟 实用技巧
构建时间参考(现代服务器配置):完整 make cross 约 15-30 分钟;make all WHAT=cmd/kubectl 约 1-2 分钟;KUBE_FASTBUILD=true make cross 约 5-10 分钟。
六、常见问题
以下是初学者最常遇到的构建问题,按类别整理,方便快速定位。
6.1 编译错误类
▼ Q: 提示找不到 Go,应该怎么处理?
A: 原因通常是 Go 没有安装或版本不对。构建系统会自动下载正确版本的 Go。但如果想手动安装,确保安装的是 Go 1.26 或更高版本。你可以在终端执行 go version 确认当前版本。
▼ Q: macOS 上提示 tar 错误,怎么解决?
A: 原因是 macOS 自带的 BSD tar 和 GNU tar 不兼容。解决方案是安装 GNU tar:
brew install gnu-tar
▼ Q: 跨平台编译失败,缺少交叉编译器怎么办?
A: 原因是缺少目标平台的交叉编译器。推荐直接使用容器构建(make cross),容器镜像里已经包含了所有工具链。在 Ubuntu 上也可以手动安装:
apt install gcc-multilib gcc-aarch64-linux-gnu
6.2 容器相关类
▼ Q: 提示无法连接到 Docker,怎么处理?
A: 原因是 Docker daemon 没有运行或没有权限。先执行 docker info 检查 Docker 是否正常。如果权限不足,可能需要将当前用户加入 docker 用户组:
sudo usermod -aG docker $USER # 然后重新登录终端
6.3 构建性能类
▼ Q: 首次构建太慢,有什么办法加速?
A: 首次构建耗时较长是正常的,可以通过以下方式加速:
- 使用 KUBE_FASTBUILD=true 只构建当前平台
- 使用 make WHAT=cmd/your-component 只构建改动的组件
- 确保网络畅通(Go 模块下载速度影响较大)
- 设置国内 Go 代理 GOPROXY=https://goproxy.cn,direct
七、本地构建 vs 容器构建对比
两种构建方式各有优势,下面从几个维度进行对比,帮助你根据实际场景选择合适的方案。
| 对比项 | 本地构建 | 容器构建 |
|---|---|---|
| 适用场景 | 日常开发迭代、快速调试 | 跨平台编译、生产发布 |
| 环境要求 | 需要 Go 1.26+,交叉编译工具链 | 只需要 Docker |
| 构建速度 | 较快(只编译本机平台) | 较慢(多平台串行编译) |
| 环境一致性 | 依赖本机环境,可能有差异 | 镜像保证,完全一致 |
| 常用命令 | make all / make kubectl | make cross / make release |
八、总结
经过全文学习,你现在应该已经掌握了 Kubernetes 构建系统的核心知识:
- 1理解构建流程:make all 背后是 build.sh → setup_env → build_binaries → place_bins 四步
- 2掌握 WHAT 参数:最灵活的构建粒度控制,按需构建,节省时间
- 3选择合适方式:日常开发用本地构建,发布用容器构建
- 4善用环境变量:DBG=1 调试、KUBE_FASTBUILD=true 加速、GOPROXY 加速下载
下一步,你可以尝试:阅读 Kubernetes 官方源码,深入理解各个组件的内部实现;或者基于 Kubernetes 源码进行二次开发,定制你自己的集群功能。
如果你对某个特定组件的构建过程感兴趣,建议直接阅读对应目录下的 Makefile 和构建脚本,Kubernetes 的构建系统文档非常完善,源码就是最好的教材。
相关阅读:
• Kubernetes 官方 GitHub 仓库
• Kubernetes 构建官方文档
• Kubernetes 开发指南(官方)
Kubernetes 1.36.1 构建完全指南 · 基于 build/root/Makefile 及构建脚本解析

浙公网安备 33010602011771号