Kubernetes 开发环境搭建与构建测试全指南:从预提交检查到 make 构建体系
【免费下载链接】communityKubernetes Community Documentation项目地址: https://gitcode.com/GitHub_Trending/com/community
本文是 Kubernetes 社区仓库k8s.io/community中权威开发指南 development.md 的中文深度解读,面向所有希望为 Kubernetes 主仓库(kubernetes/kubernetes)贡献代码的开发者。阅读本文后,你将掌握:PR 提交前的自检规范、Linux/macOS/Windows 下完整开发环境的搭建步骤、用make体系快速构建与交叉编译 Kubernetes、提交前单元/集成/E2E 测试的运行方法,以及基于 go modules 与.go-version文件的依赖与 Go 版本管理方案。文中所有命令均以 Kubernetes 项目目录$GOPATH/src/k8s.io/kubernetes/为基准,并以当前仓库中的 Makefile、hack/verify.sh、go.mod 等真实文件作为佐证。
一、文档定位:开发工具链的事实来源
development.md 是 Kubernetes 构建所支持的工具链版本的权威来源(canonical source of truth)。如果你发现某个需求未被本文档覆盖,或存在其他文档单独规定了工具链要求,都应反馈到本指南统一管理。需要注意的是:开发分支(development branch)的工具链要求会随时间变化,而发布分支(release branch)的要求是冻结不变的。这意味着,在为某个已发布的 Kubernetes 版本做 cherry-pick 修复时,必须遵守该发布分支冻结时的工具链版本,而不是最新开发分支的版本。
二、预提交飞行检查:提交前先回答三个问题
在创建 issue 或 pull request 之前,先判断你的改动属于哪一类。如今 Kubernetes 拥有超过 5 万名贡献者,每个 issue 都应以谨慎的态度提交。一个合理的验收标准是:任何 issue 都不应让评审者花费超过 5 分钟来检查其合理性——即使是最忙碌的评审者,也愿意花 5 分钟审阅一份经过深思熟虑的补丁。
2.1 这是一个简单的 bug 修复吗?
简单 bug 补丁易于评审,因为测试覆盖随补丁一起提交。bug 修复通常不需要大量额外测试,但必须更新单元测试以覆盖该 bug,确保同样的缺陷不会再次溜进代码库。
2.2 这是一次架构改进吗?
"架构"层面的改进包括但不限于:
- 新增功能,或让某个功能更可配置、更模块化;
- 提升测试覆盖率;
- 解耦逻辑、创建新的工具函数;
- 提升代码健壮性(sleep、backoff、减少 flakiness 等)。
这类改进容易评估,尤其是当它们在不破坏功能的前提下减少了代码行数时。但请务必在 PR 中明确说明你究竟在"清理"什么,以免浪费评审者的时间。若你的改动是为了增强健壮性,请附上能演示新行为的测试——例如,如果你的补丁让某个 controller 更好地处理不一致的数据,就构造一个多次返回错误数据的 mock 对象,验证 controller 的新行为。
2.3 这是一次性能改进吗?
性能 bug 报告必须附带证明问题的数据,否则 issue 将被直接关闭。你可以通过 kubemark、scheduler_perf、Go benchmark 测试,或在真实集群上运行带指标图表的 e2e 测试来测量性能。
以下两类表述在性能 issue 中是典型的反例(会导致漫长的评审过程并浪费周期):
- "我们应该用 X 代替 Y,因为那可能带来更好的性能";
- "用 X 代替 Y 会减少对 Z 的调用"。
这两句话对评审者毫无价值,因为它们都没有数据支撑。写这样的 issue 会让你的 PR 陷入"无人区"。
有价值的性能改进方向(记住:必须用数据记录改进效果):
- 改进缓存实现;
- 减少对 O(n^2) 函数的调用;
- 减少对 API server 请求的依赖;
- 调整进程默认参数的值,或让这些值"更智能";
- 对需要在大量 node/pod 对象上执行的计算做并行化。
性能类 issue 应附带以下证据(按价值从高到低排序):
- 一个 Go Benchmark 测试;
- 集群上指标负载下降的可视化图(可通过
metrics/端点加 grafana 测量); - 手工插桩的计时测试(例如在 controller manager 中加入日志)。
正确的做法是遵循"科学方法":先提出假设,再收集数据,再修正假设,在评审第一行代码之前就把问题分析清楚、方案验证到位。
三、两种构建路径:Docker 容器构建与本地 shell 构建
Kubernetes 官方发布版使用 Docker 容器构建,可参考主仓库build/目录下的构建文档。但有时在本地工作站或 shell 环境中开发更为方便,下面详述在 Linux、Windows 和 macOS 上构建所需的软硬件要求。
3.1 硬件要求
Kubernetes 是一个大型项目,编译会消耗大量资源。官方推荐任何用于构建的物理机或虚拟机至少具备:
- 8GB 内存(RAM);
- 50GB 可用磁盘空间。
(注意:早期 Windows 虚拟机方案还额外要求 60GB 磁盘空间,见下文。)
3.2 操作系统准备
Windows:WSL2 或 Linux 虚拟机二选一
先通过Windows 徽标键 + R输入winver点击确定(或在命令行执行ver)确认你的 Windows 版本:
- 若为Windows 10 Version 2004、Build 19041 或更高版本,可使用 Windows Subsystem for Linux(WSL)构建,安装 WSL2 后按 Linux 流程配置;
- 若为更早版本,则需创建一台至少 8GB 内存、60GB 磁盘空间的 Linux 虚拟机。
无论哪种方式,WSL2/虚拟机就绪后,都继续按下面的 Linux 配置流程进行。
macOS:安装 GNU 命令行工具
Kubernetes 假定你使用的是 GNU 命令行工具,而 macOS 自带的是 FreeBSD 风格的 BSD 工具,因此必须额外安装 GNU 版本。一条命令即可安装所需软件包:
brew install coreutils ed findutils gawk gnu-sed gnu-tar grep make jq3.3 必需软件清单与安装方法
GNU 开发工具
Kubernetes 的开发辅助脚本需要一个较新的 GNU 开发工具环境,各主流发行版安装命令如下:
Debian/Ubuntu
sudo apt update sudo apt install build-essentialFedora/RHEL/CentOS
sudo yum update sudo yum groupinstall "Development Tools"OpenSUSE
sudo zypper update sudo zypper install -t pattern devel_C_C++Arch
sudo pacman -Sy base-devel
安装完成后,确认gcc和make可用。macOS 用户除 GNU 工具外,还需安装Command Line Tools for Xcode。
Docker
Kubernetes 开发需要 Docker 来运行部分验证(verify)任务,请按 Docker 官方文档安装。macOS 用户务必确保/usr/local/bin在PATH中。
rsync
构建系统要求环境中存在rsync(常见的文件同步与传输工具)。多数现代操作系统已预装;若未安装,可用系统包管理器安装。
jq
部分辅助脚本需要jq(命令行 JSON 处理器),按官方安装指南为你的平台安装即可。
gcloud
如果你计划远程构建或运行端到端(e2e)测试,还需安装 Google Cloud Platform 的命令行工具gcloud。仅做本地开发时此步可跳过。
Go
Kubernetes 由 Go 编写。若没有 Go 环境,请按 Go 官方入门指南安装,并在继续之前确认GOPATH与GOBIN环境变量设置正确。构建 Kubernetes 需要非常新的 Go 版本,请安装你系统可用的最新稳定版。不同 Kubernetes 版本要求的 Go 版本如下表:
| Kubernetes 版本 | 所需 Go 版本 |
|---|---|
| 1.0 - 1.2 | 1.4.2 |
| 1.3, 1.4 | 1.6 |
| 1.5, 1.6 | 1.7 - 1.7.5 |
| 1.7 | 1.8.1 |
| 1.8 | 1.8.3 |
| 1.9 | 1.9.1 |
| 1.10 | 1.9.1 |
| 1.11 | 1.10.2 |
| 1.12 | 1.10.4 |
| 1.13 | 1.11.13 |
| 1.14 - 1.16 | 1.12.9 |
| 1.17 - 1.18 | 1.13.15 |
| 1.19 - 1.20 | 1.15.5 |
| 1.21 - 1.22 | 1.16.7 |
| 1.23 | 1.17 |
| 1.24 | 1.18 |
| 1.25 | 1.20.10 |
| 1.26 - 1.29 | 1.21.7 |
| 1.30 | 1.22.1 |
要精确查询某个具体 Kubernetes 版本所需的 Go 版本,可在 Kubernetes 工作目录中运行以下命令(示例为查询所有 1.29.z 版本):
K8S_VERSION=1.29 for tag in $(git tag | grep $K8S_VERSION);do git checkout -q tags/$tag;goVersion=$(cat ./build/dependencies.yaml | grep "golang: upstream version" -A 1 | grep version: | awk '{$1=$1;print}' );echo "Kubernetes $tag requires Go $goVersion";done示例输出:
Kubernetes v1.29.0 requires Go version: 1.21.5 Kubernetes v1.29.0-alpha.0 requires Go version: 1.20.6 Kubernetes v1.29.0-alpha.1 requires Go version: 1.21.1 Kubernetes v1.29.0-alpha.2 requires Go version: 1.21.2 Kubernetes v1.29.0-alpha.3 requires Go version: 1.21.3 Kubernetes v1.29.0-rc.0 requires Go version: 1.21.4 Kubernetes v1.29.0-rc.1 requires Go version: 1.21.4 Kubernetes v1.29.0-rc.2 requires Go version: 1.21.5 Kubernetes v1.29.1 requires Go version: 1.21.6 Kubernetes v1.29.2 requires Go version: 1.21.7关于更换 Go 版本的注意事项:如果你已经用某个版本的 Go 编译过 Kubernetes,现在想换一个版本重新编译,请参考 SIG Release 的相关文档。
PyYAML
部分 Kubernetes 验证测试使用 PyYAML,因此要在本地成功运行全部验证测试,需要安装它。按 PyYAML 官方文档为你的平台安装。macOS 用户可能需要用pip3而非pip。
克隆 Kubernetes Git 仓库
软件安装完毕后即可克隆 kubernetes/kubernetes 仓库。完整的 fork 与 clone 流程见 GitHub Workflow 指南——其核心步骤包括:在 GitHub 上 fork 主仓库、将 fork clone 到本地、添加upstream远端并设置git remote set-url --push upstream no_push防止误推主分支、基于upstream/master创建特性分支git checkout -b myfeature。该指南正是 development.md 所引用的标准工作流。
etcd:测试必需的一致性与高可用键值存储
要测试 Kubernetes,需要安装较新版本的 etcd。在 Kubernetes 工作目录下运行:
./hack/install-etcd.sh脚本执行后会提示你修改PATH。要永久生效,可将其加入.bashrc或登录脚本:
export PATH="$GOPATH/src/k8s.io/kubernetes/third_party/etcd:${PATH}"etcd 的安装至关重要:集成测试(integration tests)缺少 etcd 将直接失败。
BASH 版本要求
要在 Kubernetes 中成功运行单元测试,需要bash 版本大于 4.3。
所有必需软件安装完成后,即可进入下一节的构建验证环节——先构建 Kubernetes 的一部分,确认环境没问题,再考虑全量构建。
四、用 make 构建 Kubernetes:WHAT、交叉编译与调试符号
验证开发环境的最佳方式是先构建 Kubernetes 的某一部分,这样可以在不等待全量构建的情况下及时修正配置问题。请使用make help查看所有可用目标的帮助信息。
4.1 构建指定子系统:make WHAT=cmd/<subsystem>
在$GOPATH/src/k8s.io/kubernetes/项目目录下,使用WHAT环境变量指定要构建的子系统:
make WHAT=cmd/<subsystem>将<subsystem>替换为cmd/目录下的某个命令目录名。例如构建kubectlCLI:
make WHAT=cmd/kubectl构建成功后,可在项目目录下的_output/bin/kubectl找到可执行文件。
4.2 全量构建与默认参数
构建整个 Kubernetes 项目:
make all注意:可以省略all,直接运行make效果相同。
Kubernetes 构建系统默认将报告的 Go 编译器错误数限制为 10 个。若想移除该限制,在命令行追加GOGCFLAGS="-e":
make WHAT="cmd/kubectl" GOGCFLAGS="-e"如果需要对编译出的可执行文件使用调试检查工具(如 delve、gdb),设置DBG=1:
make WHAT="cmd/kubectl" DBG=14.3 交叉编译与指定平台
为所有平台交叉编译 Kubernetes:
make cross为特定平台构建二进制,追加KUBE_BUILD_PLATFORMS=<os>/<arch>:
make cross KUBE_BUILD_PLATFORMS=windows/amd644.4 仓库佐证:Makefile 的 target 与容器化构建模式
从源码结构看,make体系是 Kubernetes 项目(包括社区仓库)通用的构建入口。以本仓库根目录的 Makefile 为例,它展示了 Makefile 组织 target 的典型模式:default目标聚合generate,并提供reset-docs、generate、verify、test等目标;同时定义了CONTAINER_ENGINE?=$(shell command -v docker 2>/dev/null || command -v podman 2>/dev/null),即优先使用 docker、否则回退 podman的容器引擎探测逻辑,以及generate-containerized、verify-containerized、test-containerized这类通过$(CONTAINER_ENGINE) run --rm -v $(shell pwd):/go/src/app $(IMAGE_NAME) make -C /go/src/app <target>实现的容器化构建 target。这正印证了 development.md 中"官方发布版使用 Docker 容器构建、本地亦可直接执行 make"的双轨模式——社区仓库如此,Kubernetes 主仓库的make体系同样遵循该设计。
五、提交前测试快速入门:verify、unit、integration、e2e
Kubernetes 只会在单元测试、集成测试和 e2e 测试全部通过时合并 pull request,因此本地开发环境必须能够完整运行这些测试。本小节的所有命令默认在 Kubernetes 项目目录$GOPATH/src/k8s.io/kubernetes/下执行。更深入的内容请参阅 Testing Guide 与 SIG Architecture 的 开发者指南索引。
5.1 提交前验证:make verify与make update
预提交验证(presubmission verification)提供一系列检查与测试,让你的 PR 有最大机会被接受。开发者应在本地尽量多地运行验证测试。
你可以通过项目目录下的hack/verify-*.sh脚本查看全部验证测试清单。运行所有预提交验证测试:
make verify机制解读:make verify背后是对hack/verify-*.sh系列脚本的批量执行。以本仓库的 hack/verify.sh 为参考,其核心逻辑是run-checks "${KUBE_ROOT}/hack/verify-*.sh" bash——遍历所有verify-*.sh脚本逐一执行,跳过被EXCLUDED_PATTERNS排除的条目(如verify-all.sh自身和verify-*-containerized.sh),对每个脚本计时并输出SUCCESS/FAILED结果,最后汇总失败项。主仓库的验证机制与此同构:每个verify-*.sh负责一类检查(格式、license、代码生成一致性等)。
如果某个验证测试失败,可能存在对应的更新脚本hack/update-*.sh帮助修复。例如hack/update-gofmt.sh用于确保所有源码文件格式正确——通常在向项目添加新文件后需要运行。你也可以一次运行全部更新脚本:
make update5.2 单元测试:make test
PR 必须通过全部单元测试。运行所有单元测试:
make testmake test是运行单元测试的入口,它会确保GOPATH设置正确(见 testing.md)。若测试包出现超时 panic,可增大KUBE_TIMEOUT:
make test KUBE_TIMEOUT="-timeout=300s"使用WHAT选项控制测试哪些包,用GOFLAGS改变测试运行方式。例如,仅对单个包进行详细单元测试:
make test WHAT=./pkg/apis/core/helper GOFLAGS=-vWHAT支持包路径(自动添加k8s.io/kubernetes前缀)、...子包通配、多目标与花括号展开等灵活写法(来自 testing.md):
make test WHAT=./pkg/kubelet # 只测 pkg/kubelet make test WHAT=./pkg/api/... # 测 pkg/api 及其全部子包 make test WHAT="./pkg/kubelet ./pkg/scheduler" # 多目标需加引号 make test WHAT=./pkg/{kubelet,scheduler} # shell 花括号展开运行指定测试用例:用KUBE_TEST_ARGS传-run正则给go test:
# 在 pkg/apis/core/validation 中详细运行 TestValidatePod make test WHAT=./pkg/apis/core/validation GOFLAGS="-v" KUBE_TEST_ARGS='-run ^TestValidatePod$' # 匹配 ValidatePod 或 ValidateConfigMap 的用例 make test WHAT=./pkg/apis/core/validation GOFLAGS="-v" KUBE_TEST_ARGS="-run ValidatePod\|ValidateConfigMap$"排查 flaky 测试(本仓库社区目标为 99.9% 无 flake)可反复压测:
# 2 个 worker 各跑 5 遍(共 10 轮迭代) make test PARALLEL=2 ITERATION=55.3 集成测试:make test-integration
所有集成测试通过也是 PR 被接受的前提。此阶段特别依赖 etcd 的正确安装(见 3.3 节),缺少 etcd 集成测试会失败:
make test-integration更深入的集成测试方法见 SIG Testing 集成测试指南。
5.4 E2E 测试
端到端(E2E)测试用于验证系统的端到端行为,主要目标是确保 Kubernetes 代码库行为的一致性与可靠性,尤其是在单元测试与集成测试覆盖不足的领域。E2E 测试会构建测试二进制、拉起测试集群、运行测试,然后拆除集群。
注意:运行全部 E2E 测试耗时极长!关于如何只运行特定测试以节省时间,请参阅 Kubernetes 中的端到端测试 以及 kubetest2 快速入门。从 e2e-tests.md 的结构可以看出,E2E 体系还覆盖版本倾斜(version-skewed)与升级测试、conformance 测试、CI 集成(PR-builder)等主题,是提交前信号链的最后一道保障。
六、依赖管理:go modules、vendor 与 .go-version
Kubernetes 使用go modules管理依赖。需要在vendor/目录树中管理依赖的开发者,应阅读 使用 go modules 管理依赖。
从 vendor.md 可以了解其原理:主模块根目录的go.mod通过两类指令描述依赖——require指令列出依赖的首选版本(由 go 工具链自动更新为模块的最高首选版本),replace指令将依赖固定到特定 tag 或 commit;添加/更新依赖时通过hack/pin-dependency.sh example.com/go/frob v1.0.4这类脚本同时写入require与replace两项。Kubernetes 约定所有go.mod条目都应指向各自仓库的 tag,确实需要使用 SHA 时必须带// comment注明对应 tag/release,并跟踪 issue 推动后续清理。
以本仓库的 go.mod 为实例佐证(模块声明为k8s.io/community,go 版本 1.26.4):其结构正是"主require块 + 间接依赖require块(标注// indirect)+tool指令"的 go modules 标准形态,与主仓库的go.mod组织方式一致。这印证了 go modules 是 Kubernetes 全家族仓库统一的依赖管理方案。
6.1 用指定版本的 Go 构建:.go-version、GO_VERSION与FORCE_HOST_GO
Kubernetes 仓库根目录存在一个.go-version文件,它定义了构建 Kubernetes 应使用的 go 版本。例如希望用go1.20.4构建,就把文件内容改为1.20.4。构建目标选择 go 版本的逻辑如下:
- 若系统上的 go 版本(由
go version输出确定)与.go-version不一致,则默认使用.go-version中定义的版本(必要时自动下载); - 若不想启用该行为,有两种方式:
- 设置
GO_VERSION环境变量:它定义期望的 go 版本,即使系统 go 版本与.go-version不匹配,也会使用GO_VERSION指定的版本(即使需要下载)。版本格式与.go-version文件一致,例如构建go1.20.4就设置GO_VERSION=1.20.4; - 设置
FORCE_HOST_GO为非空值:跳过上述全部逻辑,直接使用系统$PATH上的 go 版本。
- 设置
三个典型示例:
用系统没有、.go-version也没有指定的 go 版本(假设为 go1.20.4)构建:
GO_VERSION=1.20.4 make WHAT=cmd/<subsystem>用系统已有的 go 版本构建、忽略.go-version:
FORCE_HOST_GO=y make WHAT=cmd/<subsystem>或者直接修改.go-version文件为你想要的版本(.go-version内容仅一行):
1.20.4七、与 GitHub 工作流的衔接
开发环境就绪后,代码签出与提交应遵循标准的 GitHub 协作流程,详见 GitHub Workflow 指南。其要点可概括为:fork 云端仓库 → clone 到本地(working_dir通常设为$HOME/src/k8s.io)→ 添加upstream远端并禁止推送 →git fetch upstream后基于最新的upstream/master创建特性分支 → 在分支上开发 → 提交前完整跑一遍本文第五节的验证与测试。该指南还专门链接回 development.md 获取本地构建的快速指引,两份文档互为补充,构成 Kubernetes 贡献者从"搭环境"到"提 PR"的完整闭环。
八、小结:开发者的标准动作清单
综合全文,一名 Kubernetes 贡献者在提交代码前的标准动作可归纳为:
- 定性:明确改动是 bug 修复、架构改进还是性能改进;性能改进必须有数据支撑(benchmark、指标图、插桩计时);
- 搭环境:按硬件要求(8GB RAM / 50GB 磁盘)准备机器,Windows 用 WSL2 或 Linux VM,macOS 安装 GNU 工具与 Xcode CLT,安装 Docker、rsync、jq、gcloud(可选)、匹配版本的 Go、PyYAML、etcd,并确认 bash > 4.3;
- 构建验证:
make WHAT=cmd/kubectl先构建单个组件,必要时make all全量构建,用GOGCFLAGS="-e"放开错误数、DBG=1保留调试符号、make cross KUBE_BUILD_PLATFORMS=<os>/<arch>交叉编译; - 测试:依次通过
make verify(含hack/update-*.sh修复)、make test(可用WHAT/GOFLAGS/KUBE_TEST_ARGS精确控制)、make test-integration(依赖 etcd)与必要的 E2E 测试; - 依赖与版本:通过 go modules(
go.mod的require/replace指令)管理依赖,通过.go-version/GO_VERSION/FORCE_HOST_GO精确控制构建用的 Go 版本; - 提交流程:按 GitHub Workflow 完成分支开发与 PR 提交。
每一步的权威依据都收敛于本文所解读的 development.md,它就是 Kubernetes 工具链与构建流程的事实标准。
【免费下载链接】communityKubernetes Community Documentation项目地址: https://gitcode.com/GitHub_Trending/com/community
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考