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 一条命令就够了
   • 跨平台编译:按需查阅,不要求全部背下来
   • 环境变量速查表:用到时再查,不需要提前记忆


目录

  1. 认识 Kubernetes 的构建系统
  2. 本地环境构建
  3. 容器环境构建
  4. 常用构建命令汇总
  5. 关键环境变量
  6. 常见问题

一、认识 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. 1理解构建流程:make all 背后是 build.sh → setup_env → build_binaries → place_bins 四步
  2. 2掌握 WHAT 参数:最灵活的构建粒度控制,按需构建,节省时间
  3. 3选择合适方式:日常开发用本地构建,发布用容器构建
  4. 4善用环境变量:DBG=1 调试、KUBE_FASTBUILD=true 加速、GOPROXY 加速下载

下一步,你可以尝试:阅读 Kubernetes 官方源码,深入理解各个组件的内部实现;或者基于 Kubernetes 源码进行二次开发,定制你自己的集群功能。

如果你对某个特定组件的构建过程感兴趣,建议直接阅读对应目录下的 Makefile 和构建脚本,Kubernetes 的构建系统文档非常完善,源码就是最好的教材。

相关阅读:
   • Kubernetes 官方 GitHub 仓库
   • Kubernetes 构建官方文档
   • Kubernetes 开发指南(官方)


Kubernetes 1.36.1 构建完全指南 · 基于 build/root/Makefile 及构建脚本解析

posted @ 2026-06-11 13:24  左扬  阅读(19)  评论(0)    收藏  举报