首页
/ kubernetes 根 README 深度解读:从源码构建 K8s 到把 K8s 组件当库用的实践指南

kubernetes 根 README 深度解读:从源码构建 K8s 到把 K8s 组件当库用的实践指南

2026-09-04 14:32:30作者:范垣楠Rhoda

本文基于 kubernetes 仓库根目录 README.md 展开,带你完整掌握三件事:Kubernetes 的定位与设计渊源(Google Borg 经验)、两种官方支持的源码构建方式(Go 环境 make 与 Docker 环境 make quick-release)、以及“如何把 K8s 发布组件当作 Go 库引入自己的项目、哪些模块禁止这么用”的边界规则。文中所有构建细节均以当前仓库 Makefilehack/make-rules/build.shhack/lib/golang.shstaging/README.md 的源码级证据为准,读完后可直接在本仓库中完成一次完整的构建并理解其底层调用链。

一、Kubernetes 是什么:README 给出的权威定义

README.md 开篇即给出项目的正式定义:

Kubernetes(K8s)是一个用于跨多台主机管理容器化应用的开源系统。它提供了应用部署、维护和扩展的基础机制。

README 同时交代了项目的技术渊源与治理背景,这两点在理解整个代码库时非常关键:

  • Borg 经验:Kubernetes 建立在 Google 十余年使用名为 Borg 的系统在超大规模场景下运行生产负载的经验之上,并结合了社区的最佳理念与实践;
  • CNCF 托管:Kubernetes 由云原生计算基金会(CNCF)托管,社区可通过加入 CNCF 参与容器化、动态调度与微服务方向的技术演进。

这个定位决定了仓库的代码组织方式:调度(scheduling)、声明式 API(api/)、各核心控制面组件(cmd/)与发布到各 SIG 的库(staging/)共同构成“生产级容器调度与管理”的完整实现。从 CHANGELOG/ 目录可以看到,当前仓库包含从 v1.2 到 v1.37 的完整发布历史,说明这是一个持续演进的活跃主干。

二、把 K8s 组件当库用:README 划出的“可用/禁用”边界

README 中 “To start using K8s” 一节的核心规则只有一条,但极其重要:

  • 官方文档以 kubernetes.io 为准,并提供了免费课程入口;
  • 要把 Kubernetes 代码作为库引入其他应用,必须使用“已发布组件列表”中的模块(即 staging 区域对应的一批 k8s.io/* 仓库);
  • 明确不支持k8s.io/kubernetes 模块或其 k8s.io/kubernetes/... 下的包作为库依赖使用。

这条规则的仓库级证据有两处:

2.1 staging 目录就是“权威副本”

staging/README.md 解释了该目录的性质:

staging 目录是已拆分到独立仓库的包的暂存区。这里的内容会定期发布到对应的 k8s.io 顶层仓库……staging/ 目录中的代码是权威副本(authoritative),即代码的唯一副本,可以直接修改。

当前 staging 区域包含的已发布仓库覆盖 K8s 的核心基础设施,例如:

分类 仓库(对应 staging/src 子目录)
API 与客户端 k8s.io/apik8s.io/apimachineryk8s.io/client-gok8s.io/apiserver
控制面组件库 k8s.io/kube-schedulerk8s.io/kube-controller-managerk8s.io/kubeletk8s.io/kube-proxy
存储与网络 k8s.io/mount-utilsk8s.io/csi-translation-libk8s.io/cloud-providerk8s.io/endpointslice
CLI 与示例 k8s.io/kubectlk8s.io/cli-runtimek8s.io/sample-apiserverk8s.io/sample-controller

2.2 导入是如何被解析到本地的

staging/README.md 说明:Kubernetes 代码通过 Go workspace 与模块 replace 语句使用这些仓库。以 k8s.io/client-go 为例,K8s 代码中的 import "k8s.io/client-go/dynamic" 会被解析到仓库内的 staging/src/k8s.io/client-go/dynamic,而不是去下载外部模块。

这一点可以在根目录 go.work 中得到直接验证:该文件声明了 go 1.26.0,并在 use 块中逐一列入了根模块与全部 staging 模块(./staging/src/k8s.io/api./staging/src/k8s.io/client-go./staging/src/k8s.io/kube-scheduler 等)。因此构建时所有 k8s.io/* 内部依赖都在本地解析,这也解释了为什么“把 k8s.io/kubernetes 当库用”不被支持——它依赖的正是这种 workspace 内部的替换关系,外部项目无法复现。

实践结论:你的项目需要客户端能力就依赖 k8s.io/client-go,需要写新 API 服务就参考 k8s.io/sample-apiserver + k8s.io/apiserver,需要控制器框架就使用 k8s.io/controller-runtime/k8s.io/sample-controller 一类已发布模块;而永远不要 go get k8s.io/kubernetes/...

三、Go 环境构建:make 背后的完整调用链

README 给出的第一种构建方式是:在有可用的 Go 环境下,克隆 kubernetes 仓库后执行 make。下面结合源码还原这条命令到底做了什么。

3.1 入口:Makefile 的 all 目标

Makefileall 目标最终只调用一个脚本:

all:
	hack/make-rules/build.sh $(WHAT)

其帮助信息(Makefile 中的 ALL_HELP_INFO 宏)定义了以下可用参数:

参数 作用
WHAT 要构建的目录或 Go 包名;含 main 包的目录会在 $(OUT_DIR)/bin 下产出可执行文件;缺省构建“一切”;支持 vendor/<module>/<path> 别名与 ginkgo 别名
GOFLAGS 额外传给 go 的构建参数
GOLDFLAGS 额外链接参数
GOGCFLAGS 额外编译参数
DBG=1 关闭优化以便调试;不设置时默认带 -s -w 剥离调试信息

官方示例:

make                          # 构建全部组件
make all WHAT=cmd/kubelet GOFLAGS=-v
make all DBG=1                # 生成未剥离的调试版二进制,可用 delve 调试

其中 OUT_DIR 默认为 _outputMakefileOUT_DIR ?= _outputBIN_DIR := $(OUT_DIR)/bin),所以构建产物统一落在 _output/bin

3.2 脚本层:build.sh 只干三件事

hack/make-rules/build.sh 全文很短,逻辑是:

source "${KUBE_ROOT}/hack/lib/init.sh"
kube::golang::setup_env        # 初始化 Go 环境变量
kube::golang::build_binaries "$@"   # 真正的构建循环
kube::golang::place_bins      # 把产物拷贝到 _output/bin

3.3 核心:kube::golang::build_binaries 的关键细节

真正的工作集中在 hack/lib/golang.shkube::golang::build_binaries 中,几个值得记住的实现细节:

  1. 构建标志golang.sh):
    • DBG=1 时追加 all=-N -l(禁用优化与内联,便于调试);
    • 非调试模式追加 -s -w(剥离符号与 DWARF)与 -trimpath(剥离嵌入路径),并使用 grpcnotrace build tag 避免 x/net trace 依赖、启用死代码消除;
    • 默认 build tags 为 selinux,notest,grpcnotraceGOFLAGS 中通过 -tags= 指定的 tag 会被合并进来。
  2. 平台矩阵golang.sh):目标平台取自 KUBE_BUILD_PLATFORMS 环境变量(空格分隔的 GOOS/GOARCH 列表);未设置时只构建当前宿主平台。这解释了本机 make 的默认行为——只编一份本机可用二进制。
  3. 目标集合:未指定 WHAT 时构建 KUBE_ALL_TARGETS 定义的全部组件,对应 cmd/ 下的各入口(kube-apiserver、kube-controller-manager、kube-scheduler、kube-proxy、kubelet、kubectl、kubeadm、cloud-controller-manager 等)。
  4. 并行策略golang.sh):多平台构建时,先探测物理内存,达到 KUBE_PARALLEL_BUILD_MEMORY 阈值才并行,否则串行,防止 OOM。
  5. 版本注入:ldflags 通过 kube::version::ldflags 将版本号等编译进二进制,这就是每个 K8s 组件 --version 信息的来源。

因此,一次带平台的构建可以这样表达(变量均可通过 Makefile 与构建脚本覆盖):

# 只构建调度器,交叉编译到 linux/arm64
make all WHAT=cmd/kube-scheduler KUBE_BUILD_PLATFORMS=linux/arm64

四、Docker 环境构建:make quick-release 的参数真相

README 的第二种方式是:在有可用的 Docker 环境下执行 make quick-release。这个名字容易让人以为它会产出“正式发布”,但 Makefile 揭示了它的真实语义:

.PHONY: release-skip-tests quick-release
release-skip-tests quick-release: KUBE_RELEASE_RUN_TESTS = n
release-skip-tests quick-release: KUBE_FASTBUILD = true
release-skip-tests quick-release:
	build/release.sh

quick-releaserelease-skip-tests同一个目标,固定注入两个变量:

  • KUBE_RELEASE_RUN_TESTS = n:跳过测试;
  • KUBE_FASTBUILD = true:不做全量多架构交叉编译(仅构建快速路径,默认仅 linux/amd64 一类最小集合)。

它最终调用 build/release.sh 在容器中完成构建与制品生成。Makefile 中该目标的帮助信息还列出了可调参数:

参数 说明
KUBE_RELEASE_RUN_TESTS y 可强制在快速发布路径上跑测试
KUBE_FASTBUILD false 则开启其他架构的交叉编译
KUBE_DOCKER_REGISTRY 发布镜像的仓库,默认 registry.k8s.io
KUBE_BASE_IMAGE_REGISTRY 控制面二进制的基础镜像仓库,默认 registry.k8s.io/build-image

此外还有一个姊妹目标 quick-release-imagesMakefile),只构建 linux/amd64 的发布镜像,支持 DBG=1 生成未剥离二进制的调试版镜像。

两种方式的取舍:本机 Go 环境齐全时用 make(产物在 _output/bin,适合开发与调试);只有 Docker 环境时用 make quick-release(在容器内复现 CI 构建,产物用于进一步验证或本地起集群)。两者都以当前仓库实际的脚本为准,README 并未承诺特定版本能力,请以 CHANGELOG/ 对应版本的发布说明确认你所用版本的行为。

五、README 指向的其余入口与仓库结构对照

README 剩余章节都是导航性质,这里给出它们在仓库内的对应落点,方便按图索骥:

README 章节 仓库内对应内容
使用文档(kubernetes.io) 本仓库不含用户文档,api/openapi-spec/swagger.jsonapi/discovery/ 下按 API 组/版本组织的 discovery JSON 是 API 的机器可读事实来源
开发文档(community 仓库) 仓库内 CONTRIBUTING.mdAGENTS.md 提供贡献与 Agent 操作约定;hack/README.md 是构建/验证脚本的总目录
Support SUPPORT.md 说明支持渠道,排障优先走官方 troubleshooting 指南
治理 / Roadmap 由 Kubernetes 社区仓库与 Enhancements 仓库承载,本仓库 OWNERSOWNERS_ALIASES 与各级目录下的 OWNERS 文件体现代码归属

从源码结构看,pkg/(业务实现,如 pkg/scheduler/pkg/controller/pkg/proxy/)、staging/src/(可发布库)、test/(e2e、conformance、integration)与 cmd/(各组件入口)四者分工清晰,这也正是前文“k8s.io/kubernetes 不可作库、须用 staging 组件”这一规则在目录层面的体现。

六、适用前提与版本说明

  • Go 版本go.workgo.mod 均声明 go 1.26.0,源码构建要求本地 Go 工具链不低于该版本;
  • 产物位置make 系构建的产物位于 _output/binKUBE_VERBOSE 控制构建日志级别(默认 1);KUBE_GOFLAGS 已弃用,请使用 GOFLAGS(见 Makefile 的弃用提示);
  • 构建校验:CI 侧的验证入口为 hack/verify-all.shhack/make-rules/verify.sh,本地改完代码可用其做等价自检;
  • 本文所有参数与行为描述均以当前仓库快照为准;如需针对特定发布版本操作,请对照 CHANGELOG/ 中对应版本的变更记录。
登录后查看全文
热门项目推荐
相关项目推荐