乐趣区

关于kubernetes:Kubernetes构建过程分析

构建形式

Kubernetes 的构建形式能够分为 3 种,别离是本地环境构建、容器环境构建、Bazel 环境构建。

Kubernetes 构建形式:

  • 本地环境构建
    1) make
    2) make all
  • 容器环境构建
    1) make release
    2) make quick-release
  • Bazel 环境构建
    1) make bazel-build

上面将具体介绍前两种构建形式:

本地环境构建

执行 make 或者 make all 命令,会编译 Kubernetes 的所有组件,组件二进制文件输入的相对路径是_output/bin。如果咱们须要对 Makefile 的执行过程进行调试,能够在 make 命令前面加 - n 参数,输入但不执行所有执行命令,这样能够展现更具体的编译构建过程。假如咱们想独自构建某个组价,如 kubectl 组件,则须要指定 WHAT 参数。命令示例如下:

make WHAT=cmd/kubectl

Makefile 是一个十分自动化构建工具,能够用来构建和测试 Go 语言的应用程序,Makefile 还实用于大多数编程语言,在 Kubernetes 的源码根目录中,有两个与 Makefile 相干的文件,性能别离如下:

  • Makefile:顶层 Makefile 文件,形容了整个我的项目所有代码文件的编译程序、编译规定及编译后的二进制文件输入等。
  • Makefile.generated_file:形容了代码生成的逻辑。

本地构建过程

通过调用 hack/make-rules/build.sh 脚本开始构建组件,传入要构建的组件名称,不指定组件名称则构建所有组件。hack/make-rules/build.sh 代码示例如下:

kube::golang::build_binaries "$@"

build_binaries 接管构建的组件名称,设置构建所须要的环境及一些编译时所需的 Go flags 选项,而后通过 go install 构建组件:

go install "${build_args[@]}" "$@"

在 go install 命令执行实现后,二进制输入的目录为_output/bin。
最初,能够应用 make clean 命令来清理构建环境。

容器环境构建

通过容器(Docker)进行 Kubernetes 构建也非常简单,Kubernetes 提供了两种容器环境下得构建形式:make release 和 make quick-release,它们之间的区别如下:

  • make release:构建所有指标平台(Darwin、Linux、Windows),构建过程会比拟久,并同时执行单元测试过程。
  • make quick-release:疾速构建,只构建以后平台,并略过单元测试过程。
    Kubernetes 容器环境构建流程:
 构建环境的配置及验证:kube::build::verify_prereqs
构建容器镜像:kube::build::build_image
构建代码:kube::build::run_build_command make cross
将文件从容器复制到主机:kube::build::copy_output
打包:kube::release::package_tarballs

在容器环境构建过程中,有多个容器镜像参加其中,别离介绍如下:

  • build 容器(kube-cross): 即构建容器,在该容器中会对代码文件执行构建操作,实现后会被删除。
  • data 容器:即存储容器,用于寄存构建过程中所须要的的所有文件。
  • raync 容器:即同步容器:用于在容器和主机之间传输数据,实现后会被删除。
    上面介绍一下 Kubernetes 容器环境构建过程。

1.kube::build::verfy_prereqs

进行构建环境的配置及验证。该过程会查看本机是否装置了 Docker 容器环境,对于 Darwin 平台,该过程会查看本机是否装置了 docker-machine 环境。

2.kube::build::build_image

依据 Dockerfile 文件构建容器镜像。Dockerfile 文件来源于 build/build-image/Dockerfile, 代码示例如下:
代码门路:build/common.sh

function kube::build::build_image() {mkdir -p "${LOCAL_OUTPUT_BUILD_CONTEXT}"
  ...
  cp "${KUBE_ROOT}/build/build-image/Dockerfile" "${LOCAL_OUTPUT_BUILD_CONTEXT}/Dockerfile"
  cp "${KUBE_ROOT}/build/build-image/rsyncd.sh" "${LOCAL_OUTPUT_BUILD_CONTEXT}/"
  dd if=/dev/urandom bs=512 count=1 2>/dev/null | LC_ALL=C tr -dc 'A-Za-z0-9' | dd bs=32 count=1 2>/dev/null > "${LOCAL_OUTPUT_BUILD_CONTEXT}/rsyncd.password"
  chmod go= "${LOCAL_OUTPUT_BUILD_CONTEXT}/rsyncd.password"

  kube::build::update_dockerfile
  kube::build::set_proxy
  kube::build::docker_build "${KUBE_BUILD_IMAGE}" "${LOCAL_OUTPUT_BUILD_CONTEXT}" 'false'
  ...
  kube::build::ensure_data_container
  kube::build::sync_to_container
}

构建容器镜像的流程如下:

  • 通过 mkdir 命令创立构建镜像的文件夹(即_output/images/…)。
  • 通过 cp 命令复制构建镜像所需的相干文件,如 Dockerfile 文件和 rsyncd 同步脚本等。
  • 通过 kube::build::docker_build 函数,构建容器镜像。
  • 通过 kube::build::ensure_data_container 函数,运行存储容器并挂载 Volume。
  • 通过 kube::build::sync_to_container 函数,运行同步容器并挂载存储容器的 Volume,而后通过 rsnyc 命令同步 Kubernetes 源码到存储容器的 Volume。

3.kube::build::run_build_command make cross

此时,容器构建环境曾经筹备好,上面开始运行构建容器并在构建容器外部执行构建 Kubernetes 源码的操作,代码示例如下:
代码门路:build/common.sh

function kube::build::run_build_command_ex() {
  ...
  local detach=false
  ...
  "${docker_cmd[@]}" "${cmd[@]}"
  if [["${detach}" == false ]]; then
    kube::build::destroy_container "${container_name}"
  fi
}

在执行 kube::build::run_build_command_ex 函数中,通过 ${docker_cmd[@]}””${cmd[@]}
命令执行构建操作(即在容器内执行 make cross 命令)。容器内的构建过程与本地环境下的构建过程雷同。其中构建平台有 KUBE_SUPPORTED_SERVER_PLATFORMS 变量管制,代码示例如下:
代码门路:hack/lib/golang.sh

readonly KUBE_SUPPORTED_SERVER_PLATFORMS=(
  linux/amd64
  linux/arm
  linux/arm64
  linux/s390x
  linux/ppc64le
)

构建的组件由 KUBE_SERVER_TARGETS 变量管制,代码示例如下:
代码门路:hack/lib/golang.sh

kube::golang::server_targets() {
  local targets=(
    cmd/kube-proxy
    cmd/kube-apiserver
    cmd/kube-controller-manager
    cmd/kubelet
    cmd/kubeadm
    cmd/kube-scheduler
    vendor/k8s.io/kube-aggregator
    vendor/k8s.io/apiextensions-apiserver
    cluster/gce/gci/mounter
  )
  echo "${targets[@]}"
}

IFS="" read -ra KUBE_SERVER_TARGETS <<<"$(kube::golang::server_targets)"

4.kube::build::copy_output

应用同步容器,将编译后的代码文件复制到主机上。

5.kube::release::package_tarballs

进行打包,将二进制文件打包到_output 目录中。
最终,代码文件以 tar.gz 压缩包的模式输入至_output/release-tars 文件夹。

退出移动版