github.com/containerd/Containerd@v1.4.13/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 build `runc` build, which includes
   180  [seccomp](https://en.wikipedia.org/wiki/seccomp), [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux),
   181  and [AppArmor](https://en.wikipedia.org/wiki/AppArmor) support. Seccomp support
   182  in runc requires `libseccomp-dev` as a dependency (AppArmor and SELinux support
   183  do not require external libraries at build time). Refer to [RUNC.md](docs/RUNC.md)
   184  in the docs directory to for details about building runc, and to learn about
   185  supported versions of `runc` as used by containerd.
   186  
   187  Let's suppose you build an image called `containerd/build` from the above Dockerfile. You can run the following command:
   188  
   189  ```sh
   190  docker run -it --privileged \
   191      -v /var/lib/containerd \
   192      -v ${GOPATH}/src/github.com/opencontainers/runc:/go/src/github.com/opencontainers/runc \
   193      -v ${GOPATH}/src/github.com/containerd/containerd:/go/src/github.com/containerd/containerd \
   194      -e GOPATH=/go \
   195      -w /go/src/github.com/containerd/containerd containerd/build sh
   196  ```
   197  
   198  This mounts both `runc` and `containerd` repositories in our Docker container.
   199  
   200  From within our Docker container let's build `containerd`:
   201  
   202  ```sh
   203  cd /go/src/github.com/containerd/containerd
   204  make && make install
   205  ```
   206  
   207  These binaries can be found in the `./bin` directory in your host.
   208  `make install` will move the binaries in your `$PATH`.
   209  
   210  Next, let's build `runc`:
   211  
   212  ```sh
   213  cd /go/src/github.com/opencontainers/runc
   214  make && make install
   215  ```
   216  
   217  For further details about building runc, refer to [RUNC.md](docs/RUNC.md) in the
   218  docs directory.
   219  
   220  When working with `ctr`, the simple test client we just built, don't forget to start the daemon!
   221  
   222  ```sh
   223  containerd --config config.toml
   224  ```
   225  
   226  # Testing containerd
   227  
   228  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:
   229   - `make test`: run all non-integration tests that do not require `root` privileges
   230   - `make root-test`: run all non-integration tests which require `root`
   231   - `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**.
   232  
   233  To execute a specific test or set of tests you can use the `go test` capabilities
   234  without using the `Makefile` targets. The following examples show how to specify a test
   235  name and also how to use the flag directly against `go test` to run root-requiring tests.
   236  
   237  ```sh
   238  # run the test <TEST_NAME>:
   239  go test	-v -run "<TEST_NAME>" .
   240  # enable the root-requiring tests:
   241  go test -v -run . -test.root
   242  ```
   243  
   244  Example output from directly running `go test` to execute the `TestContainerList` test:
   245  ```sh
   246  sudo go test -v -run "TestContainerList" . -test.root
   247  INFO[0000] running tests against containerd revision=f2ae8a020a985a8d9862c9eb5ab66902c2888361 version=v1.0.0-beta.2-49-gf2ae8a0
   248  === RUN   TestContainerList
   249  --- PASS: TestContainerList (0.00s)
   250  PASS
   251  ok  	github.com/containerd/containerd	4.778s
   252  ```
   253  
   254  ## Additional tools
   255  
   256  ### containerd-stress
   257  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`.
   258  
   259  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:
   260  
   261  ```sh
   262  containerd-stress -c 5 -t 120
   263  ```
   264  
   265  For more information on this tool's options please run `containerd-stress --help`.
   266  
   267  ### bucketbench
   268  [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.
   269  
   270  Bucketbench differs from the `containerd-stress` tool in a few ways:
   271   - 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.
   272   - 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).
   273   - Bucketbench generates detailed reports and timing data at the end of the configured test run.
   274  
   275  More details on how to install and run `bucketbench` are available at the [GitHub project page](https://github.com/estesp/bucketbench).