kubernetes/build
Kubernetes Prow Robot d54e4498fc
Merge pull request #98529 from saschagrunert/buildx
Use buildx in favor of `FROM --platform` syntax
2021-01-28 09:47:41 -08:00
..
build-image [go1.15] Update to go1.15.7 2021-01-27 11:43:01 +01:00
lib Use buildx in favor of FROM --platform syntax 2021-01-28 14:53:09 +01:00
pause Merge pull request #97853 from claudiubelu/patch-1 2021-01-12 20:20:35 -08:00
release-tars Restructure licenses again (revert cd4474a) 2020-05-07 21:48:59 -07:00
root [go1.15] Update to go1.15.7 2021-01-27 11:43:01 +01:00
visible_to Merge pull request #96124 from adtac/apf1ginkgo 2020-11-09 15:14:41 -08:00
bindata.bzl updating github.com/go-bindata/go-bindata to v3.1.1 2019-06-20 11:30:30 -04:00
BUILD Merge pull request #91452 from claudiubelu/windows/pause-image 2020-10-23 04:05:45 -07:00
code_generation_test.bzl Update bazel to 2.2.0 2020-03-24 13:04:39 -07:00
code_generation.bzl Update bazel to 2.2.0 2020-03-24 13:04:39 -07:00
common.sh Bump debian-base to v1.4.0 and debian-iptables to v1.5.0 2021-01-28 13:47:09 +01:00
container.bzl bazel maintain support for arch-less-named tarballs 2019-03-06 12:56:10 -08:00
copy-output.sh make build/copy-output.sh pass shellcheck 2019-01-16 00:39:13 -08:00
dependencies.yaml Merge pull request #97456 from claudiubelu/remove-busybox-helper 2021-01-28 08:21:34 -08:00
go.bzl make kube::util::find-binary not dependent on bazel-out/ structure 2020-09-11 13:19:38 -07:00
kazel_generated.bzl Rename _examples to examples 2021-01-25 10:20:46 -08:00
make-build-image.sh make build/make-build-image.sh pass shellcheck 2019-01-16 00:34:36 -08:00
make-clean.sh make build/make-clean.sh pass shellcheck 2019-01-16 00:33:28 -08:00
nsswitch.conf add nsswitch to busybox control plane images 2018-09-28 17:04:48 -07:00
openapi.bzl bazel: update openapi-gen to use new kazel-generated dictionaries 2019-01-08 14:47:32 -08:00
OWNERS Merge pull request #93821 from dims/sign-up-dims-for-additional-review-roles 2020-08-13 21:48:21 -07:00
package-tarballs.sh make build/package-tarballs.sh pass shellcheck 2019-01-16 00:32:28 -08:00
platforms.bzl fix typo in build/platforms.bzl 2019-08-26 10:31:21 +08:00
README.md Fix the build/README.md documentation file on docker-machine remote 2021-01-12 00:34:09 +01:00
release-images.sh Remove hyperkube 2020-03-17 21:33:50 -04:00
release-in-a-container.sh make build/release-in-a-container.sh pass shellcheck 2019-01-16 00:31:15 -08:00
release.sh make build/release.sh pass shellcheck 2019-01-16 00:27:43 -08:00
run.sh make build/run.sh pass shellcheck 2019-01-16 00:25:52 -08:00
shell.sh make build/shell.sh pass shellcheck 2019-01-16 00:24:27 -08:00
tools.go move linting dependencies to hack/tools/tools.go 2020-04-20 13:45:38 -04:00
util.sh make build/util.sh pass shellcheck 2019-01-16 00:37:13 -08:00
workspace_mirror.bzl workspace mirror: add trailing newline to urls list 2018-05-07 16:52:20 -07:00
workspace.bzl Bump debian-base to v1.4.0 and debian-iptables to v1.5.0 2021-01-28 13:47:09 +01:00

Building Kubernetes

Building Kubernetes is easy if you take advantage of the containerized build environment. This document will help guide you through understanding this build process.

Requirements

  1. Docker, using one of the following configurations:
  • macOS Install Docker for Mac. See installation instructions here. Note: You will want to set the Docker VM to have at least 8GB of initial memory or building will likely fail. (See: #11852).
  • Linux with local Docker Install Docker according to the instructions for your OS.
  • Windows with Docker Desktop WSL2 backend Install Docker according to the instructions. Be sure to store your sources in the local Linux file system, not the Windows remote mount at /mnt/c.
  1. Optional Google Cloud SDK

You must install and configure Google Cloud SDK if you want to upload your release to Google Cloud Storage and may safely omit this otherwise.

Overview

While it is possible to build Kubernetes using a local golang installation, we have a build process that runs in a Docker container. This simplifies initial set up and provides for a very consistent build and test environment.

Key scripts

The following scripts are found in the build/ directory. Note that all scripts must be run from the Kubernetes root directory.

  • build/run.sh: Run a command in a build docker container. Common invocations:
    • build/run.sh make: Build just linux binaries in the container. Pass options and packages as necessary.
    • build/run.sh make cross: Build all binaries for all platforms. To build only a specific platform, add KUBE_BUILD_PLATFORMS=<os>/<arch>
    • build/run.sh make kubectl KUBE_BUILD_PLATFORMS=darwin/amd64: Build the specific binary for the specific platform (kubectl and darwin/amd64 respectively in this example)
    • build/run.sh make test: Run all unit tests
    • build/run.sh make test-integration: Run integration test
    • build/run.sh make test-cmd: Run CLI tests
  • build/copy-output.sh: This will copy the contents of _output/dockerized/bin from the Docker container to the local _output/dockerized/bin. It will also copy out specific file patterns that are generated as part of the build process. This is run automatically as part of build/run.sh.
  • build/make-clean.sh: Clean out the contents of _output, remove any locally built container images and remove the data container.
  • build/shell.sh: Drop into a bash shell in a build container with a snapshot of the current repo code.

Basic Flow

The scripts directly under build/ are used to build and test. They will ensure that the kube-build Docker image is built (based on build/build-image/Dockerfile and after base image's KUBE_BUILD_IMAGE_CROSS_TAG from Dockerfile is replaced with one of those actual tags of the base image, like v1.13.9-2) and then execute the appropriate command in that container. These scripts will both ensure that the right data is cached from run to run for incremental builds and will copy the results back out of the container.

The kube-build container image is built by first creating a "context" directory in _output/images/build-image. It is done there instead of at the root of the Kubernetes repo to minimize the amount of data we need to package up when building the image.

There are 3 different containers instances that are run from this image. The first is a "data" container to store all data that needs to persist across to support incremental builds. Next there is an "rsync" container that is used to transfer data in and out to the data container. Lastly there is a "build" container that is used for actually doing build actions. The data container persists across runs while the rsync and build containers are deleted after each use.

rsync is used transparently behind the scenes to efficiently move data in and out of the container. This will use an ephemeral port picked by Docker. You can modify this by setting the KUBE_RSYNC_PORT env variable.

All Docker names are suffixed with a hash derived from the file path (to allow concurrent usage on things like CI machines) and a version number. When the version number changes all state is cleared and clean build is started. This allows the build infrastructure to be changed and signal to CI systems that old artifacts need to be deleted.

Releasing

The build/release.sh script will build a release. It will build binaries, run tests, (optionally) build runtime Docker images.

The main output is a tar file: kubernetes.tar.gz. This includes:

  • Cross compiled client utilities.
  • Script (kubectl) for picking and running the right client binary based on platform.
  • Examples
  • Cluster deployment scripts for various clouds
  • Tar file containing all server binaries

In addition, there are some other tar files that are created:

  • kubernetes-client-*.tar.gz Client binaries for a specific platform.
  • kubernetes-server-*.tar.gz Server binaries for a specific platform.

When building final release tars, they are first staged into _output/release-stage before being tar'd up and put into _output/release-tars.

Reproducibility

make release, its variant make quick-release, and Bazel all provide a hermetic build environment which should provide some level of reproducibility for builds. make itself is not hermetic.

The Kubernetes build environment supports the SOURCE_DATE_EPOCH environment variable specified by the Reproducible Builds project, which can be set to a UNIX epoch timestamp. This will be used for the build timestamps embedded in compiled Go binaries, and maybe someday also Docker images.

One reasonable setting for this variable is to use the commit timestamp from the tip of the tree being built; this is what the Kubernetes CI system uses. For example, you could use the following one-liner:

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