0%

编译Kubernetes源码(官方指导)

如果利用容器化的构建环境,则构建Kubernetes很容易。本文档将帮助了解构建过程。

依赖

  1. Docker,使用以下配置之一:
    • macOS:可以使用Mac的Docker或docker-machine。请参阅此处的安装说明。注意:需要将Docker VM设置为具有至少4.5GB的初始内存,否则构建可能会失败。(请参阅:#11852)。
    • 带有本地Docker的Linux:根据OS的说明安装Docker。
    • 远程Docker引擎:在云中使用大型计算机来加快构建速度。这有点棘手,所以请稍后再看。
  2. 可选的Google Cloud SDK

如果要将发布版本上传到Google Cloud Storage,则必须安装和配置Google Cloud SDK,否则可以放心地省略此设置。

概述

虽然可以使用本地golang来构建Kubernetes,但我们有一个在Docker容器中运行的构建过程。这简化了初始设置,并提供了非常一致的构建和测试环境。

关键脚本

build/目录中找到以下脚本。请注意,所有脚本必须从Kubernetes根目录运行。

  • build/run.sh: 在构建docker容器中运行命令。常用调用:
    • build/run.sh make: 在容器中仅构建linux二进制文件。根据需要传递选项和软件包。
    • build/run.sh make cross: 构建所有平台的所有二进制文件。
    • build/run.sh make kubectl KUBE_BUILD_PLATFORMS=darwin/amd64: 为特定平台构建特定二进制文件。
    • build/run.sh make test: 运行所有单元测试。
    • build/run.sh make test-integration: 运行集成测试。
    • build/run.sh make test-cmd: 运行CLI测试。
  • build/copy-output.sh: 这会将 _output/dockerized/bin 的内容从Docker容器拷贝到本地 _output/dockerized/bin目录. 它还将复制在构建过程中生成的特定文件模式。这是作为 build/run.sh的一部分自动运行的。
  • build/make-clean.sh: 清除 _output的内容,删除所有本地构建的容器镜像,然后删除数据容器。
  • build/shell.sh: 将带有当前存储库代码快照的构建容器内加入bash shell。

基本流程

位于build/目录下的脚本直接用于构建和测试。它们将确保构建kube-build Docker镜像(基于build/build-image/Dockerfile),然后在该容器中执行适当的命令。这些脚本将确保每次运行都缓存正确的数据以进行增量构建,并将结果复制回容器。

首先,通过在_output/images/build-image中创建一个“context”目录来构建kube-build容器镜像。它是在此处完成的,而不是在Kubernetes存储库的根目录进行,以最大程度地减少构建镜像时需要打包的数据量。

从此,该镜像运行3个不同的容器实例。每次运行后,数据容器在运行期间都将保留,而rsync和构建容器将被删除。

  1. 数据容器:用于存储需要持久存储以支持增量构建的所有数据。
  2. rsync容器:用于将数据传入和传出到数据容器。
  3. 构建容器:用于实际执行构建操作。

rsync容器在后台透明地使用,以有效地将数据移入和移出容器。这将使用Docker选择的临时端口。可以通过设置KUBE_RSYNC_PORT env变量来修改它。

所有Docker名称都以从文件路径派生的哈希作为后缀(以允许在CI机器上同时使用)和版本号。当版本号更改时,所有状态都将清除,并开始全新构建。这允许更改构建基础结构,并向CI系统发出需要删除旧设施的信号。

代理设置

如果使用了代理,并且让这些脚本使用docker-machine在macOS上设置本地VM,则需要设置Kubernetes构建的代理,应定义以下环境变量。

1
2
export KUBERNETES_HTTP_PROXY=http://username:password@proxyaddr:proxyport
export KUBERNETES_HTTPS_PROXY=https://username:password@proxyaddr:proxyport

可以选择为Kubernetes构建指定没有代理的地址,例如

1
export KUBERNETES_NO_PROXY=127.0.0.1

如果使用sudo进行Kubernetes的构建(例如make quick-release),则需要运行sudo -E make quick-release来传递环境变量。

远程Docker引擎

可以使用远程运行的Docker引擎。必须将Docker配置为连接到该计算机,并且本地rsync端口必须从localhost转发(通过SSH或nc)到远程计算机。

要使用GCP和docker-machine轻松做到这一点,请执行以下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Create the remote docker machine on GCE.  This is a pretty beefy machine with SSD disk.
KUBE_BUILD_VM=k8s-build
KUBE_BUILD_GCE_PROJECT=<project>
docker-machine create \
--driver=google \
--google-project=${KUBE_BUILD_GCE_PROJECT} \
--google-zone=us-west1-a \
--google-machine-type=n1-standard-8 \
--google-disk-size=50 \
--google-disk-type=pd-ssd \
${KUBE_BUILD_VM}

# Set up local docker to talk to that machine
eval $(docker-machine env ${KUBE_BUILD_VM})

# Pin down the port that rsync will be exposed on the remote machine
export KUBE_RSYNC_PORT=8730

# forward local 8730 to that machine so that rsync works
docker-machine ssh ${KUBE_BUILD_VM} -L ${KUBE_RSYNC_PORT}:localhost:${KUBE_RSYNC_PORT} -N &

通过docker-machine stop, docker-machine startdocker-machine rm 管理创建的VM。

发布版本

build/release.sh脚本将构建发行版。它将构建二进制文件,运行测试,(可选)构建运行时Docker镜像。

主要输出是tar文件:kubernetes.tar.gz。这包括:

  • 交叉编译的客户端实用程序
  • 脚本(kubectl),用于基于平台选择和运行正确的客户端二进制文件
  • 例子
  • 各种云的集群部署脚本
  • 包含所有服务器二进制文件的Tar文件

此外,还创建了其他一些tar文件:

  • kubernetes-client-*.tar.gz 特定平台的客户端二进制文件
  • kubernetes-server-*.tar.gz 特定平台的服务器二进制文件

构建最终发行版tar时,首先将它们暂存为_output/release-stage,然后再将其放入_output/release-tars

重现性

make release,其变体make quick-release和Bazel都提供了一个封闭的构建环境,应该为构建提供一定程度的可重复性。make自身不是密封的。

Kubernetes构建环境支持Reproducible Builds项目指定的SOURCE_DATE_EPOCH环境变量,可以将其设置为UNIX纪元时间戳。这将用于嵌入已编译的Go二进制文件中的构建时间戳,也许还有一天还会用于Docker镜像。

这个变量的一个合理设置是使用从正在构建的树的顶端开始的提交时间戳。这就是Kubernetes CI系统使用的。例如,可以使用以下命令获取:

1
SOURCE_DATE_EPOCH=$(git show -s --format=format:%ct HEAD)