Colton Wolkins

Moving Docker to it's own Server

Introduction

Difficulty: Intermediate

What you should know:

What you will need:

What you will learn: How to install and setup Flatcar Linux as a remote docker installation

In this guide, the following representations are made:

Situation

One of the most prolific problems that I’ve run into while developing with docker is running out of disk space. This can become quite the problem if you are working on things that are not related to docker. Suddenly finding out that you can’t run a git commit, update the system, or save a file because you ran out of disk space is a pain in the neck.Using tools such as ncdu to locate where all my space has gone, nearly every time I find that the cause is due to docker containers, images, and volumes. It’s no surprise that docker takes up a lot of space during development. Hundreds of “dangling” docker images are left over with the constant docker-compose up --build and docker-compose down.

You might say that I’m running out of space because I’m not regularly cleaning out my docker images, that I didn’t partition my system correctly, or that I’m not effectively using docker volumes to simplify my work. You might be right about that, but I much prefer using a remote host to develop on using Flatcar Linux. I now let a VM running Flatcar handle all the data issues and if it needs to be re-installed, that’s not a problem and can be easily done.

A Potential Solution

Years ago, I had heard about an operating system called CoreOS whose update process was based upon the work done for Chrome OS. The idea was that you could have many machines (based upon the “Machines are cattle, not pets” principle) running docker in a clustered environment and updates were performed by merely rebooting the host machines. All applications would run inside of Docker and no real user accounts would exist on the machine.

However, CoreOS is no longer available. The wonderful thing about Open Source is the fact that, if something is useful, people will keep it available in some way. Enter, Flatcar Linux.

What is Flatcar Linux

Flatcar Linux is a fork of Container Linux (formerly CoreOS) and works off the principle that the only thing it runs is docker. This means that all applications, whether they are production or used for development, are run within docker containers. A setup like this allows users to build images and run containers with more flexibility than running docker on your main machine. If you run out of disk space on your Flatcar instance, you still have space on your development machine to save your work. Or maybe you’d like to reboot your dev machine for system updates? That can be done as well without shutting down your containers. Unless, of course, Flatcar is running as a VM on the same machine that you’re rebooting. In which case, the VM can be paused and resumed after you’ve updated. If starting fresh is necessary, everything is a simple reinstall away from being in a fresh, clean, state. Or maybe testing in a kubernetes cluster is needed, that can be done too.

Suffice it to say, you’ve got options and it’s awesome! You’re no longer limited to your local box.

Downloading Flatcar Linux

There are a few different ways to download and install Flatcar Linux. For the sake of this tutorial, I will be going over the installation process for installing Flatcar Linux on a Bare Metal Server. While it’s not the easiest, it is the most portable setup and can work with any operating system. These steps can even be followed on that old laptop that’s been collecting dust for the past few years!

So first, go to the docs that detail installing from an ISO and download the Stable ISO. Once it’s downloaded, insert it into the virtual CD drive of your preferred virtual machine software and boot from it.

Next, we’ll need a machine capable of running docker containers to setup the installation config.

Flatcar Pre-Requisites

Aside from having a VM that can support Flatcar and all the containers that you plan to run, Flatcar also requires an installation file called ignition.json. Throughout the following steps, it is expected that you will end up with a directory structure similar to the following:

flatcar-project
├ data                    - used for mounting into the docker container
│ ├ flatcar.yml           - easy to read config file
│ └ ignition.json         - generated config file from flatcar.yml
├ create-ignition-file.sh - executable used to easily regenerate ignition.json
├ Dockerfile              - docker build file for a simple web host
├ docker-compose.yml      - composition config for a simple web host
└ index.html              - default index file used to indicate if things are
                            setup correctly or not

The next steps should serve as a guide for creating the ignition.json and serving it via a simple web server so that we can download it onto our Flatcar installation live CD.

Create ignition.json

The data/ignition.json file is Flatcar’s installation config. However, most of the configuration is actually done via yaml, rather than json. I’ve got an example yaml file here that you are free to use, however. A username, password hash, and SSH key will need to be provided. If you want to disable password login, line 9 containing password_hash: "PASSWORD_HASH" will need to be deleted.

If you would like to skip to where the ignition.json file is generated, please click here

flatcar.yml

Generating the JSON Ignition File

Once the YAML config has been created, it is time to convert it into a json file. By following the Flatcar Documentation, they recommend using an application called ct. Luckily, ct can be run from a docker container and is still in a docker registry under the CoreOS project. The script below expects the flatcar.yml file to be in a subdirectory called data. It then reads it’s contents and sends them to the standard input of the ct command (by running docker). Then, the resulting ignition.json will be written to the same data directory that flatcar.yml resides in (the data dir will be used later).

Assuming that the above flatcar.yml is in the data directory, the below commands within create-ignition-file.sh should create an ignition.json in the same folder.

Docker Webhost Configuration

The docker configuration consists 3 files.

  1. Dockerfile - used for creating a lighttpd web host container
  2. index.html - a dummy file to determing if the docker volume was mounted correctly
  3. docker-compose.yml - used for quick orchestration

The contents of these files should be the same as the ones in the following Github gists:

Setup lighttpd to serve ignition file

With everything in place, we can now bring up our webserver and verify that we can access the ignition.json file. Within the project directory, the webserver can be brought up by running

docker-compose up --build

Once the container has fully started up, visiting http://127.0.0.1:8080/ in a web browser should bring up a file list and ignition.json should be visible. Make sure that you know your computer’s IP1, as it will be needed for the next section.

Install Flatcar Linux

You can find the official Install Guide for Flatcar on their docs, but for a bare-metal install (which has been used throughout this guide), the installation commands boil down to 2 commands. The first to pull down out config and the second to install it to disk. Make sure that you replace 192.168.0.21 in the highlighted line with the IP address of your machine running the simple webhost that was setup earlier.

1
2
curl http://192.168.0.2:8080/ignition.json > ignition.json
flatcar-install -d /dev/sda -C stable -i ignition.json

At this point, flatcar should be installing itself into the VM that was setup earlier. Once it has been completed, you are free to remove the ISO file from the VM and reboot it. Before rebooting the machine, make sure that you have it’s IP address in hand2.

Point docker commands to remote docker instance

Most guides out there (including the one from the Flatcar docs) suggest setting the environment variable DOCKER_HOST to the IP of the remote docker server2.

1export DOCKER_HOST=tcp://192.168.0.3:2375

While there is nothing wrong with doing it that way, I prefer to use the newer docker context commands3 that allow the registration of 1 (or more) docker servers. The docker context ls command shows what will be setup by the end of this section.

1$ docker context ls        
2NAME       DESCRIPTION                               DOCKER ENDPOINT               KUBERNETES ENDPOINT   ORCHESTRATOR
3default    Current DOCKER_HOST based configuration   unix:///var/run/docker.sock                         swarm
4flatcar *                                            tcp://192.168.0.3:2375                              swarm

Normally, the only context that exists is the default context which connects to the local docker daemon via unix file sockets. The flatcar context shown above can be created with the following command (replace the VM IP with the IP of your own Flatcar installation2):

1docker context create flatcar \
2    --docker "host=tcp://192.168.0.3:2375" \
3    --default-stack-orchestrator swarm

Once the flatcar context command has been created, it can now be used in any docker or docker-compose commands. Like so:

docker --context=flatcar images -a

docker-compose --context=flatcar ps Both of those commands will run on the flatcar instance4. However, adding --context=flatcar to all docker and docker-compose commands can become quite tedious. Luckily, docker allows the selection of the default context. Running the following command should allow the use of the flatcar context, without ever needing to type the --context parameter ever again:

1docker context use flatcar

Conclusion

After following this guide, all docker containers and commands should now run on a VM (or bare-metal machine) running Flatcar Linux. The final step (though completely optional) in preventing usage of the docker daemon on the dev machine is by disabling docker with systemctl disable docker --now. That should stop docker and make sure it doesn’t start when rebooting. This setup can be used amongst multiple machines and it will provide flexibility as the software industry continues to evolve.


  1. 192.168.0.2 is the representation of your machine running docker ↩︎ ↩︎ ↩︎

  2. 192.168.0.3 is the representation of your flatcar VM ↩︎ ↩︎ ↩︎ ↩︎

  3. Docker contexts appear to be more flexible and don’t feel like a “hacked together solution” in my eyes. ↩︎

  4. Caveat: I have found that running docker-compose --context=flatcar build does not build the docker image on the remote host for whatever reason. A workaround is to prepend the command with COMPOSE_DOCKER_CLI_BUILD=0 to set an environment variable that forces docker-compose to run the builds on the remote host. ↩︎

#docker #flatcar-linux #linux #tutorial

Reply to this post by email ↪