Build a way
The construction methods of Kubernetes can be divided into three kinds, namely, local environment construction, container environment construction and Bazel environment construction.
Kubernetes build method:
- Local Environment Construction
- make
- make all
- Container environment construction
- make release
- make quick-release
- Bazel environment build
- make bazel-build
The first two are described in detail below:
Local Environment Construction
Make or make all compiles all components of Kubernetes. The relative path of the component binary output is _output/bin. If we need to debug the execution of the Makefile, we can show a more detailed build by adding the -n argument to the make command to print but not execute all the execution commands. Suppose we want to build some valence separately, such as a Kubectl component, we need to specify the WHAT parameter. The following is an example command:
make WHAT=cmd/kubectl
Copy the code
Makefile is a very automatic build tool that can be used to build and test Go applications. Makefile is also suitable for most programming languages. In the source directory of Kubernetes, there are two Makefile related files, which are as follows:
- Makefile: A top-level Makefile that describes the compilation order, compilation rules, and binary output of all code files in a project.
- Makefile.generated_file: describes the logic for code generation.
Local build process
Start building components by calling the hack/make-rules/build.sh script, passing in the name of the component to build, and building all components without specifying a component name. The following is an example of the hack/make-rules/build.sh code:
kube::golang::build_binaries "$@"
Copy the code
Build_binaries takes the name of the built component, sets the environment required for the build and some Go flags options required at compile time, and then builds the component with Go Install:
go install "${build_args[@]}" "$@"
Copy the code
After the go install command is executed, the binary output directory is _output/bin. Finally, you can use the make clean command to clean up the build environment.
Container environment construction
Kubernetes is also very easy to build with containers (Docker). Kubernetes provides two ways to build with containers: make Release and make Quick-release.
- Make release: Build all target platforms (Darwin, Linux, Windows), take a long time to build and unit test at the same time.
- Make Quick-release: Build quickly, build only the current platform and skip the unit testing process. Kubernetes container environment construction process:
Build environment configuration and verification :kube::build:: verify_PREReqs Build container image :kube::build::build_image Build code :kube::build::run_build_command make cross Copy files from the container to the host :kube::build::copy_output Package :kube:: Release ::package_tarballsCopy the code
In the process of container environment construction, there are several container images involved, as follows:
- Build container (kube-cross): A build container in which a build operation is performed on the code file, which is then deleted.
- Data container: Storage container for all files needed during the build process.
- Raync container: Synchronization container: Used to transfer data between the container and the host. It will be deleted after completion. Here is the Kubernetes container environment construction process.
1.kube::build::verfy_prereqs
Configure and verify the build environment. This procedure checks whether the Docker container environment is installed on the machine, and in the case of Darwin platforms, whether the Docker-Machine environment is installed on the machine.
2.kube::build::build_image
Build the container image from Dockerfile. The Dockerfile file is from build/build-image/Dockerfile. The code is as follows: The code path is 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
}
Copy the code
The process for building a container image is as follows:
- Create the folder to build the image (that is, _output/images/…) with the mkdir command. .
- Use the cp command to copy the files required for image construction, such as Dockerfile files and rsyncd synchronization scripts.
- Build the container image using the kube::build::docker_build function.
- Run the storage container and mount the Volume using the kube::build::ensure_data_container function.
- Using the kube::build::sync_to_container function, run the synchronization container and mount the Volume of the storage container, and then use the rsnyc command to synchronize the Kubernetes source code to the Volume of the storage container.
3.kube::build::run_build_command make cross
Now that the container build environment is ready, run the build container and build Kubernetes source code inside the build container as shown in the following code path: 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
}
Copy the code
In executing kube::build::run_build_command_ex, Dockercmd [@]””{docker_cmd[@]}””dockercmd[@]””{CMD [@]}} command to perform the build operation (that is, make cross within the container). The build process within the container is the same as the build process in the local environment. Where build platform has KUBE_SUPPORTED_SERVER_PLATFORMS variable control, code examples are as follows: code path: hack/lib/golang.sh
readonly KUBE_SUPPORTED_SERVER_PLATFORMS=(
linux/amd64
linux/arm
linux/arm64
linux/s390x
linux/ppc64le
)
Copy the code
The build component is controlled by the KUBE_SERVER_TARGETS variable. The code is as follows: code path: 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)"
Copy the code
4.kube::build::copy_output
Use a synchronous container to copy the compiled code file to the host.
5.kube::release::package_tarballs
Package the binaries into the _output directory. Finally, the code file is exported as a tar.gz package to the _output/release-tars folder.