github.com/containerd/containerd@v22.0.0-20200918172823-438c87b8e050+incompatible/BUILDING.md (about)

     1  # Build containerd from source
     2  
     3  This guide is useful if you intend to contribute on containerd. Thanks for your
     4  effort. Every contribution is very appreciated.
     5  
     6  This doc includes:
     7  * [Build requirements](#build-requirements)
     8  * [Build the development environment](#build-the-development-environment)
     9  * [Build containerd](#build-containerd)
    10  * [Via docker container](#via-docker-container)
    11  * [Testing](#testing-containerd)
    12  
    13  ## Build requirements
    14  
    15  To build the `containerd` daemon, and the `ctr` simple test client, the following build system dependencies are required:
    16  
    17  * Go 1.13.x or above except 1.14.x
    18  * Protoc 3.x compiler and headers (download at the [Google protobuf releases page](https://github.com/google/protobuf/releases))
    19  * Btrfs headers and libraries for your distribution. Note that building the btrfs driver can be disabled via the build tag `no_btrfs`, removing this dependency.
    20  
    21  ## Build the development environment
    22  
    23  First you need to setup your Go development environment. You can follow this
    24  guideline [How to write go code](https://golang.org/doc/code.html) and at the
    25  end you need to have `GOPATH` and `GOROOT` set in your environment.
    26  
    27  At this point you can use `go` to checkout `containerd` in your `GOPATH`:
    28  
    29  ```sh
    30  go get github.com/containerd/containerd
    31  ```
    32  
    33  For proper results, install the `protoc` release into `/usr/local` on your build system. For example, the following commands will download and install the 3.11.4 release for a 64-bit Linux host:
    34  
    35  ```
    36  $ wget -c https://github.com/google/protobuf/releases/download/v3.11.4/protoc-3.11.4-linux-x86_64.zip
    37  $ sudo unzip protoc-3.11.4-linux-x86_64.zip -d /usr/local
    38  ```
    39  
    40  `containerd` uses [Btrfs](https://en.wikipedia.org/wiki/Btrfs) it means that you
    41  need to satisfy this dependencies in your system:
    42  
    43  * CentOS/Fedora: `yum install btrfs-progs-devel`
    44  * Debian/Ubuntu: `apt-get install btrfs-tools`
    45  	* Debian Buster/Ubuntu 19.10:
    46  	    `apt-get install btrfs-progs libbtrfs-dev`
    47  
    48  At this point you are ready to build `containerd` yourself!
    49  
    50  ## Build runc
    51  
    52  `runc` is the default container runtime used by `containerd` and is required to
    53  run containerd. While it is okay to download a runc binary and install that on
    54  the system, sometimes it is necessary to build runc directly when working with
    55  container runtime development. You can skip this step if you already have the
    56  correct version of `runc` installed.
    57  
    58  For the quick and dirty installation, you can use the following:
    59  
    60      go get github.com/opencontainers/runc
    61  
    62  This is not recommended, as the generated binary will not have version
    63  information. Instead, cd into the source directory and use make to build and
    64  install the binary:
    65  
    66  	cd $GOPATH/src/github.com/opencontainers/runc
    67  	make
    68  	make install
    69  
    70  Make sure to follow the guidelines for versioning in [RUNC.md](RUNC.md) for the
    71  best results. Some pointers on proper build tag setupVersion mismatches can
    72  result in undefined behavior.
    73  
    74  ## Build containerd
    75  
    76  `containerd` uses `make` to create a repeatable build flow. It means that you
    77  can run:
    78  
    79  ```
    80  cd $GOPATH/src/github.com/containerd/containerd
    81  make
    82  ```
    83  
    84  This is going to build all the project binaries in the `./bin/` directory.
    85  
    86  You can move them in your global path, `/usr/local/bin` with:
    87  
    88  ```sudo
    89  sudo make install
    90  ```
    91  
    92  When making any changes to the gRPC API, you can use the installed `protoc`
    93  compiler to regenerate the API generated code packages with:
    94  
    95  ```sudo
    96  make generate
    97  ```
    98  
    99  > *Note*: Several build tags are currently available:
   100  > * `no_btrfs`: A build tag disables building the btrfs snapshot driver.
   101  > * `no_cri`: A build tag disables building Kubernetes [CRI](http://blog.kubernetes.io/2016/12/container-runtime-interface-cri-in-kubernetes.html) support into containerd.
   102  > See [here](https://github.com/containerd/cri-containerd#build-tags) for build tags of CRI plugin.
   103  > * `no_devmapper`: A build tag disables building the device mapper snapshot driver.
   104  > * `apparmor`: Enables apparmor support in the cri plugin
   105  > * `selinux`: Enables selinux support in the cri plugin
   106  >
   107  > For example, adding `BUILDTAGS=no_btrfs` to your environment before calling the **binaries**
   108  > Makefile target will disable the btrfs driver within the containerd Go build.
   109  
   110  Vendoring of external imports uses the [`vndr` tool](https://github.com/LK4D4/vndr) which uses a simple config file, `vendor.conf`, to provide the URL and version or hash details for each vendored import. After modifying `vendor.conf` run the `vndr` tool to update the `vendor/` directory contents. Combining the `vendor.conf` update with the changeset in `vendor/` after running `vndr` should become a single commit for a PR which relies on vendored updates.
   111  
   112  Please refer to [RUNC.md](/RUNC.md) for the currently supported version of `runc` that is used by containerd.
   113  
   114  ### Static binaries
   115  
   116  You can build static binaries by providing a few variables to `make`:
   117  
   118  ```sudo
   119  make EXTRA_FLAGS="-buildmode pie" \
   120  	EXTRA_LDFLAGS='-linkmode external -extldflags "-fno-PIC -static"' \
   121  	BUILDTAGS="netgo osusergo static_build"
   122  ```
   123  
   124  > *Note*:
   125  > - static build is discouraged
   126  > - static containerd binary does not support loading shared object plugins (`*.so`)
   127  
   128  # Via Docker container
   129  
   130  ## Build containerd
   131  
   132  You can build `containerd` via a Linux-based Docker container.
   133  You can build an image from this `Dockerfile`:
   134  
   135  ```
   136  FROM golang
   137  
   138  RUN apt-get update && \
   139      apt-get install -y libbtrfs-dev
   140  ```
   141  
   142  Let's suppose that you built an image called `containerd/build`. From the
   143  containerd source root directory you can run the following command:
   144  
   145  ```sh
   146  docker run -it \
   147      -v ${PWD}:/go/src/github.com/containerd/containerd \
   148      -e GOPATH=/go \
   149      -w /go/src/github.com/containerd/containerd containerd/build sh
   150  ```
   151  
   152  This mounts `containerd` repository
   153  
   154  You are now ready to [build](#build-containerd):
   155  
   156  ```sh
   157   make && make install
   158  ```
   159  
   160  ## Build containerd and runc
   161  To have complete core container runtime, you will need both `containerd` and `runc`. It is possible to build both of these via Docker container.
   162  
   163  You can use `go` to checkout `runc` in your `GOPATH`:
   164  
   165  ```sh
   166  go get github.com/opencontainers/runc
   167  ```
   168  
   169  We can build an image from this `Dockerfile`:
   170  
   171  ```sh
   172  FROM golang
   173  
   174  RUN apt-get update && \
   175      apt-get install -y libbtrfs-dev libseccomp-dev
   176  
   177  ```
   178  
   179  In our Docker container we will use a specific `runc` build which includes [seccomp](https://en.wikipedia.org/wiki/seccomp) and [apparmor](https://en.wikipedia.org/wiki/AppArmor) support. Hence why our Dockerfile includes `libseccomp-dev` as a dependency (apparmor support doesn't require external libraries). Please refer to [RUNC.md](/RUNC.md) for the currently supported version of `runc` that is used by containerd.
   180  
   181  Let's suppose you build an image called `containerd/build` from the above Dockerfile. You can run the following command:
   182  
   183  ```sh
   184  docker run -it --privileged \
   185      -v /var/lib/containerd \
   186      -v ${GOPATH}/src/github.com/opencontainers/runc:/go/src/github.com/opencontainers/runc \
   187      -v ${GOPATH}/src/github.com/containerd/containerd:/go/src/github.com/containerd/containerd \
   188      -e GOPATH=/go \
   189      -w /go/src/github.com/containerd/containerd containerd/build sh
   190  ```
   191  
   192  This mounts both `runc` and `containerd` repositories in our Docker container.
   193  
   194  From within our Docker container let's build `containerd`:
   195  
   196  ```sh
   197  cd /go/src/github.com/containerd/containerd
   198  make && make install
   199  ```
   200  
   201  These binaries can be found in the `./bin` directory in your host.
   202  `make install` will move the binaries in your `$PATH`.
   203  
   204  Next, let's build `runc`:
   205  
   206  ```sh
   207  cd /go/src/github.com/opencontainers/runc
   208  make BUILDTAGS='seccomp apparmor selinux' && make install
   209  ```
   210  
   211  When working with `ctr`, the simple test client we just built, don't forget to start the daemon!
   212  
   213  ```sh
   214  containerd --config config.toml
   215  ```
   216  
   217  # Testing containerd
   218  
   219  During the automated CI the unit tests and integration tests are run as part of the PR validation. As a developer you can run these tests locally by using any of the following `Makefile` targets:
   220   - `make test`: run all non-integration tests that do not require `root` privileges
   221   - `make root-test`: run all non-integration tests which require `root`
   222   - `make integration`: run all tests, including integration tests and those which require `root`. `TESTFLAGS_PARALLEL` can be used to control parallelism. For example, `TESTFLAGS_PARALLEL=1 make integration` will lead a non-parallel execution. The default value of `TESTFLAGS_PARALLEL` is **8**.
   223  
   224  To execute a specific test or set of tests you can use the `go test` capabilities
   225  without using the `Makefile` targets. The following examples show how to specify a test
   226  name and also how to use the flag directly against `go test` to run root-requiring tests.
   227  
   228  ```sh
   229  # run the test <TEST_NAME>:
   230  go test	-v -run "<TEST_NAME>" .
   231  # enable the root-requiring tests:
   232  go test -v -run . -test.root
   233  ```
   234  
   235  Example output from directly running `go test` to execute the `TestContainerList` test:
   236  ```sh
   237  sudo go test -v -run "TestContainerList" . -test.root
   238  INFO[0000] running tests against containerd revision=f2ae8a020a985a8d9862c9eb5ab66902c2888361 version=v1.0.0-beta.2-49-gf2ae8a0
   239  === RUN   TestContainerList
   240  --- PASS: TestContainerList (0.00s)
   241  PASS
   242  ok  	github.com/containerd/containerd	4.778s
   243  ```
   244  
   245  ## Additional tools
   246  
   247  ### containerd-stress
   248  In addition to `go test`-based testing executed via the `Makefile` targets, the `containerd-stress` tool is available and built with the `all` or `binaries` targets and installed during `make install`.
   249  
   250  With this tool you can stress a running containerd daemon for a specified period of time, selecting a concurrency level to generate stress against the daemon. The following command is an example of having five workers running for two hours against a default containerd gRPC socket address:
   251  
   252  ```sh
   253  containerd-stress -c 5 -t 120
   254  ```
   255  
   256  For more information on this tool's options please run `containerd-stress --help`.
   257  
   258  ### bucketbench
   259  [Bucketbench](https://github.com/estesp/bucketbench) is an external tool which can be used to drive load against a container runtime, specifying a particular set of lifecycle operations to run with a specified amount of concurrency. Bucketbench is more focused on generating performance details than simply inducing load against containerd.
   260  
   261  Bucketbench differs from the `containerd-stress` tool in a few ways:
   262   - Bucketbench has support for testing the Docker engine, the `runc` binary, and containerd 0.2.x (via `ctr`) and 1.0 (via the client library) branches.
   263   - Bucketbench is driven via configuration file that allows specifying a list of lifecycle operations to execute. This can be used to generate detailed statistics per-command (e.g. start, stop, pause, delete).
   264   - Bucketbench generates detailed reports and timing data at the end of the configured test run.
   265  
   266  More details on how to install and run `bucketbench` are available at the [GitHub project page](https://github.com/estesp/bucketbench).