|
| 1 | +--- |
| 2 | +title: Customizing Docker |
| 3 | +description: > |
| 4 | + How to select which runtime to use, make docker available on a |
| 5 | + TCP socket, enable TLS, and other customizations. |
| 6 | +weight: 30 |
| 7 | +aliases: |
| 8 | + - ../os/customizing-docker |
| 9 | +--- |
| 10 | + |
| 11 | +The Docker systemd unit can be customized by overriding the unit that ships with the default Flatcar Container Linux settings or through a drop-in unit. Common use-cases for doing this are covered below. |
| 12 | + |
| 13 | +For switching to using containerd with Kubernetes, there is an [extra guide](../switching-from-docker-to-containerd-for-kubernetes/). |
| 14 | + |
| 15 | +## Use a custom containerd configuration |
| 16 | + |
| 17 | +The default configuration under `/run/torcx/unpack/docker/usr/share/containerd/config.toml` can't be changed but you can copy it to `/etc/containerd/config.toml` and modify it. |
| 18 | +**NOTE** that newer Flatcar major releases (above major release version 3760) ship the default configuration under `/usr/share/containerd/config.toml`. |
| 19 | + |
| 20 | +Create a `/etc/systemd/system/containerd.service.d/10-use-custom-config.conf` unit drop-in file to select the new configuration: |
| 21 | + |
| 22 | +```ini |
| 23 | +[Service] |
| 24 | +ExecStart= |
| 25 | +ExecStart=/usr/bin/containerd |
| 26 | +``` |
| 27 | + |
| 28 | +On a running system, execute `systemctl daemon-reload ; systemctl restart containerd` for it to take effect. |
| 29 | + |
| 30 | +## Enable the remote API on a new socket |
| 31 | + |
| 32 | +Create a file called `/etc/systemd/system/docker-tcp.socket` to make Docker available on a TCP socket on port 2375. |
| 33 | + |
| 34 | +```ini |
| 35 | +[Unit] |
| 36 | +Description=Docker Socket for the API |
| 37 | + |
| 38 | +[Socket] |
| 39 | +ListenStream=2375 |
| 40 | +BindIPv6Only=both |
| 41 | +Service=docker.service |
| 42 | + |
| 43 | +[Install] |
| 44 | +WantedBy=sockets.target |
| 45 | +``` |
| 46 | + |
| 47 | +Then enable this new socket: |
| 48 | + |
| 49 | +```shell |
| 50 | +systemctl enable docker-tcp.socket |
| 51 | +systemctl stop docker |
| 52 | +systemctl start docker-tcp.socket |
| 53 | +systemctl start docker |
| 54 | +``` |
| 55 | + |
| 56 | +Test that it's working: |
| 57 | + |
| 58 | +```shell |
| 59 | +docker -H tcp://127.0.0.1:2375 ps |
| 60 | +``` |
| 61 | + |
| 62 | +### Butane Config |
| 63 | + |
| 64 | +To enable the remote API on every Flatcar Container Linux machine in a cluster, use a [Butane Config][butane-configs]. We need to provide the new socket file and Docker's socket activation support will automatically start using the socket: |
| 65 | + |
| 66 | +```yaml |
| 67 | +variant: flatcar |
| 68 | +version: 1.0.0 |
| 69 | +systemd: |
| 70 | + units: |
| 71 | + - name: docker-tcp.socket |
| 72 | + enabled: true |
| 73 | + contents: | |
| 74 | + [Unit] |
| 75 | + Description=Docker Socket for the API |
| 76 | +
|
| 77 | + [Socket] |
| 78 | + ListenStream=2375 |
| 79 | + BindIPv6Only=both |
| 80 | + Service=docker.service |
| 81 | +
|
| 82 | + [Install] |
| 83 | + WantedBy=sockets.target |
| 84 | +``` |
| 85 | +
|
| 86 | +To keep access to the port local, replace the `ListenStream` configuration above with: |
| 87 | + |
| 88 | +```yaml |
| 89 | + [Socket] |
| 90 | + ListenStream=127.0.0.1:2375 |
| 91 | +``` |
| 92 | + |
| 93 | +## Enable the remote API with TLS authentication |
| 94 | + |
| 95 | +Docker TLS configuration consists of three parts: keys creation, configuring new [systemd socket][systemd-socket] unit and systemd [drop-in][drop-in] configuration. |
| 96 | + |
| 97 | +### TLS keys creation |
| 98 | + |
| 99 | +Please follow the [instruction][self-signed-certs] to know how to create self-signed certificates and private keys. Then copy the following files into `/etc/docker` Flatcar Container Linux's directory and fix their permissions: |
| 100 | + |
| 101 | +```shell |
| 102 | +scp ~/cfssl/{server.pem,server-key.pem,ca.pem} flatcar.example.com: |
| 103 | + |
| 104 | +sudo mv {server.pem,server-key.pem,ca.pem} /etc/docker/ |
| 105 | +sudo chown root:root /etc/docker/{server-key.pem,server.pem,ca.pem} |
| 106 | +sudo chmod 0600 /etc/docker/server-key.pem |
| 107 | +``` |
| 108 | + |
| 109 | +On your local host copy certificates into `~/.docker`: |
| 110 | + |
| 111 | +```shell |
| 112 | +mkdir ~/.docker |
| 113 | +chmod 700 ~/.docker |
| 114 | +cd ~/.docker |
| 115 | +cp -p ~/cfssl/ca.pem ca.pem |
| 116 | +cp -p ~/cfssl/client.pem cert.pem |
| 117 | +cp -p ~/cfssl/client-key.pem key.pem |
| 118 | +``` |
| 119 | + |
| 120 | +### Enable the secure remote API on a new socket |
| 121 | + |
| 122 | +Create a file called `/etc/systemd/system/docker-tls-tcp.socket` to make Docker available on a secured TCP socket on port 2376. |
| 123 | + |
| 124 | +```ini |
| 125 | +[Unit] |
| 126 | +Description=Docker Secured Socket for the API |
| 127 | +
|
| 128 | +[Socket] |
| 129 | +ListenStream=2376 |
| 130 | +BindIPv6Only=both |
| 131 | +Service=docker.service |
| 132 | +
|
| 133 | +[Install] |
| 134 | +WantedBy=sockets.target |
| 135 | +``` |
| 136 | + |
| 137 | +Then enable this new socket: |
| 138 | + |
| 139 | +```shell |
| 140 | +systemctl enable docker-tls-tcp.socket |
| 141 | +systemctl stop docker |
| 142 | +systemctl start docker-tls-tcp.socket |
| 143 | +``` |
| 144 | + |
| 145 | +### Drop-in configuration |
| 146 | + |
| 147 | +Create `/etc/systemd/system/docker.service.d/10-tls-verify.conf` [drop-in][drop-in] for systemd Docker service: |
| 148 | + |
| 149 | +```ini |
| 150 | +[Service] |
| 151 | +Environment="DOCKER_OPTS=--tlsverify --tlscacert=/etc/docker/ca.pem --tlscert=/etc/docker/server.pem --tlskey=/etc/docker/server-key.pem" |
| 152 | +``` |
| 153 | + |
| 154 | +Reload systemd config files and restart docker service: |
| 155 | + |
| 156 | +```shell |
| 157 | +sudo systemctl daemon-reload |
| 158 | +sudo systemctl restart docker.service |
| 159 | +``` |
| 160 | + |
| 161 | +Now you can access your Docker's API through TLS secured connection: |
| 162 | + |
| 163 | +```shell |
| 164 | +docker --tlsverify -H tcp://server:2376 images |
| 165 | +# or |
| 166 | +docker --tlsverify -H tcp://server.example.com:2376 images |
| 167 | +``` |
| 168 | + |
| 169 | +If you've experienceed problems connection to remote Docker API using TLS connection, you can debug it with `curl`: |
| 170 | + |
| 171 | +```shell |
| 172 | +curl -v --cacert ~/.docker/ca.pem --cert ~/.docker/cert.pem --key ~/.docker/key.pem https://server:2376 |
| 173 | +``` |
| 174 | + |
| 175 | +Or on your Flatcar Container Linux host: |
| 176 | + |
| 177 | +```shell |
| 178 | +journalctl -f -u docker.service |
| 179 | +``` |
| 180 | + |
| 181 | +In addition you can export environment variables and use docker client without additional options: |
| 182 | + |
| 183 | +```shell |
| 184 | +export DOCKER_HOST=tcp://server.example.com:2376 DOCKER_TLS_VERIFY=1 |
| 185 | +docker images |
| 186 | +``` |
| 187 | + |
| 188 | +### Butane Config (TLS) |
| 189 | + |
| 190 | +A Butane Config for Docker TLS authentication will look like: |
| 191 | + |
| 192 | +```yaml |
| 193 | +variant: flatcar |
| 194 | +version: 1.0.0 |
| 195 | +storage: |
| 196 | + files: |
| 197 | + - path: /etc/docker/ca.pem |
| 198 | + mode: 0644 |
| 199 | + contents: |
| 200 | + inline: | |
| 201 | + -----BEGIN CERTIFICATE----- |
| 202 | + MIIFNDCCAx6gAwIBAgIBATALBgkqhkiG9w0BAQswLTEMMAoGA1UEBhMDVVNBMRAw |
| 203 | + DgYDVQQKEwdldGNkLWNhMQswCQYDVQQLEwJDQTAeFw0xNTA5MDIxMDExMDhaFw0y |
| 204 | + NTA5MDIxMDExMThaMC0xDDAKBgNVBAYTA1VTQTEQMA4GA1UEChMHZXRjZC1jYTEL |
| 205 | + ... ... ... |
| 206 | + - path: /etc/docker/server.pem |
| 207 | + mode: 0644 |
| 208 | + contents: |
| 209 | + inline: | |
| 210 | + -----BEGIN CERTIFICATE----- |
| 211 | + MIIFajCCA1SgAwIBAgIBBTALBgkqhkiG9w0BAQswLTEMMAoGA1UEBhMDVVNBMRAw |
| 212 | + DgYDVQQKEwdldGNkLWNhMQswCQYDVQQLEwJDQTAeFw0xNTA5MDIxMDM3MDFaFw0y |
| 213 | + NTA5MDIxMDM3MDNaMEQxDDAKBgNVBAYTA1VTQTEQMA4GA1UEChMHZXRjZC1jYTEQ |
| 214 | + ... ... ... |
| 215 | + - path: /etc/docker/server-key.pem |
| 216 | + mode: 0644 |
| 217 | + contents: |
| 218 | + inline: | |
| 219 | + -----BEGIN RSA PRIVATE KEY----- |
| 220 | + MIIJKAIBAAKCAgEA23Q4yELhNEywScrHl6+MUtbonCu59LIjpxDMAGxAHvWhWpEY |
| 221 | + P5vfas8KgxxNyR+U8VpIjEXvwnhwCx/CSCJc3/VtU9v011Ir0WtTrNDocb90fIr3 |
| 222 | + YeRWq744UJpBeDHPV9opf8xFE7F74zWeTVMwtiMPKcQDzZ7XoNyJMxg1wmiMbdCj |
| 223 | + ... ... ... |
| 224 | +systemd: |
| 225 | + units: |
| 226 | + - name: docker-tls-tcp.socket |
| 227 | + enabled: true |
| 228 | + contents: | |
| 229 | + [Unit] |
| 230 | + Description=Docker Secured Socket for the API |
| 231 | +
|
| 232 | + [Socket] |
| 233 | + ListenStream=2376 |
| 234 | + BindIPv6Only=both |
| 235 | + Service=docker.service |
| 236 | +
|
| 237 | + [Install] |
| 238 | + WantedBy=sockets.target |
| 239 | + - name: docker.service |
| 240 | + dropins: |
| 241 | + - name: flags.conf |
| 242 | + contents: | |
| 243 | + [Service] |
| 244 | + Environment="DOCKER_OPTS=--tlsverify --tlscacert=/etc/docker/ca.pem --tlscert=/etc/docker/server.pem --tlskey=/etc/docker/server-key.pem" |
| 245 | +``` |
| 246 | + |
| 247 | +## Use attached storage for Docker images |
| 248 | + |
| 249 | +Docker containers can be very large and debugging a build process makes it easy to accumulate hundreds of containers. It's advantageous to use attached storage to expand your capacity for container images. Check out the guide to [mounting storage to your Flatcar Container Linux machine][mounting-storage] for an example of how to bind mount storage into `/var/lib/docker`. |
| 250 | + |
| 251 | +## Enabling the Docker debug flag |
| 252 | + |
| 253 | +Set the `--debug` (`-D`) flag in the `DOCKER_OPTS` environment variable by using a drop-in file. For example, the following could be written to `/etc/systemd/system/docker.service.d/10-debug.conf`: |
| 254 | + |
| 255 | +```ini |
| 256 | +[Service] |
| 257 | +Environment=DOCKER_OPTS=--debug |
| 258 | +``` |
| 259 | + |
| 260 | +Now tell systemd about the new configuration and restart Docker: |
| 261 | + |
| 262 | +```shell |
| 263 | +systemctl daemon-reload |
| 264 | +systemctl restart docker |
| 265 | +``` |
| 266 | + |
| 267 | +To test our debugging stream, run a Docker command and then read the systemd journal, which should contain the output: |
| 268 | + |
| 269 | +```shell |
| 270 | +docker ps |
| 271 | +journalctl -u docker |
| 272 | +``` |
| 273 | + |
| 274 | +### Butane Config (flags) |
| 275 | + |
| 276 | +If you need to modify a flag across many machines, you can add the flag with a Butane Config: |
| 277 | + |
| 278 | +```yaml |
| 279 | +variant: flatcar |
| 280 | +version: 1.0.0 |
| 281 | +systemd: |
| 282 | + units: |
| 283 | + - name: docker.service |
| 284 | + dropins: |
| 285 | + - name: flags.conf |
| 286 | + contents: | |
| 287 | + [Service] |
| 288 | + Environment="DOCKER_OPTS=--debug" |
| 289 | +``` |
| 290 | + |
| 291 | +## Use an HTTP proxy |
| 292 | + |
| 293 | +If you're operating in a locked down networking environment, you can specify an HTTP proxy for Docker to use via an environment variable. First, create a directory for drop-in configuration for Docker: |
| 294 | + |
| 295 | +```shell |
| 296 | +mkdir /etc/systemd/system/docker.service.d |
| 297 | +``` |
| 298 | + |
| 299 | +Now, create a file called `/etc/systemd/system/docker.service.d/http-proxy.conf` that adds the environment variable: |
| 300 | + |
| 301 | +```ini |
| 302 | +[Service] |
| 303 | +Environment="HTTP_PROXY=http://proxy.example.com:8080" |
| 304 | +``` |
| 305 | + |
| 306 | +To apply the change, reload the unit and restart Docker: |
| 307 | + |
| 308 | +```shell |
| 309 | +systemctl daemon-reload |
| 310 | +systemctl restart docker |
| 311 | +``` |
| 312 | + |
| 313 | +Proxy environment variables can also be set [system-wide][systemd-env-vars]. |
| 314 | + |
| 315 | +### Butane Config (proxy) |
| 316 | + |
| 317 | +The easiest way to use this proxy on all of your machines is via a Butane Config: |
| 318 | + |
| 319 | +```yaml |
| 320 | +variant: flatcar |
| 321 | +version: 1.0.0 |
| 322 | +systemd: |
| 323 | + units: |
| 324 | + - name: docker.service |
| 325 | + enabled: true |
| 326 | + dropins: |
| 327 | + - name: 20-http-proxy.conf |
| 328 | + contents: | |
| 329 | + [Service] |
| 330 | + Environment="HTTP_PROXY=http://proxy.example.com:8080" |
| 331 | +``` |
| 332 | + |
| 333 | +## Increase ulimits |
| 334 | + |
| 335 | +If you need to increase certain ulimits that are too low for your application by default, like memlock, you will need to modify the Docker service to increase the limit. First, create a directory for drop-in configuration for Docker: |
| 336 | + |
| 337 | +```shell |
| 338 | +mkdir /etc/systemd/system/docker.service.d |
| 339 | +``` |
| 340 | + |
| 341 | +Now, create a file called `/etc/systemd/system/docker.service.d/increase-ulimit.conf` that adds increased limit: |
| 342 | + |
| 343 | +```ini |
| 344 | +[Service] |
| 345 | +LimitMEMLOCK=infinity |
| 346 | +``` |
| 347 | + |
| 348 | +To apply the change, reload the unit and restart Docker: |
| 349 | + |
| 350 | +```shell |
| 351 | +systemctl daemon-reload |
| 352 | +systemctl restart docker |
| 353 | +``` |
| 354 | + |
| 355 | +### Butane Config (ulimits) |
| 356 | + |
| 357 | +The easiest way to use these new ulimits on all of your machines is via a Butane Config: |
| 358 | + |
| 359 | +```yaml |
| 360 | +variant: flatcar |
| 361 | +version: 1.0.0 |
| 362 | +systemd: |
| 363 | + units: |
| 364 | + - name: docker.service |
| 365 | + enabled: true |
| 366 | + dropins: |
| 367 | + - name: 30-increase-ulimit.conf |
| 368 | + contents: | |
| 369 | + [Service] |
| 370 | + LimitMEMLOCK=infinity |
| 371 | +``` |
| 372 | + |
| 373 | +## Using a dockercfg file for authentication |
| 374 | + |
| 375 | +A json file `.dockercfg` can be created in your home directory that holds authentication information for a public or private Docker registry. |
| 376 | + |
| 377 | +[docker-socket-systemd]: https://github.com/docker/docker/pull/17211 |
| 378 | +[drop-in]: ../setup/systemd/drop-in-units |
| 379 | +[mounting-storage]: ../setup/storage/mounting-storage |
| 380 | +[self-signed-certs]: ../setup/security/generate-self-signed-certificates |
| 381 | +[systemd-socket]: https://www.freedesktop.org/software/systemd/man/systemd.socket.html |
| 382 | +[systemd-env-vars]: ../setup/systemd/environment-variables/#system-wide-environment-variables |
| 383 | +[butane-configs]: ../../provisioning/config-transpiler |
0 commit comments