Flatcar Container Linux

This document describes the process of provisioning Flatcar Container Linux machines using Tinkerbell.

Preparing flatcar-install Docker image

To install Flatcar Container Linux as the target OS on the worker, the Docker image from the following Dockerfile needs to be pushed into the Tinkerbell registry:

FROM ubuntu

RUN apt update && apt install -y udev gpg wget

RUN wget https://raw.githubusercontent.com/flatcar-linux/init/flatcar-master/bin/flatcar-install -O /usr/local/bin/flatcar-install && \
    chmod +x /usr/local/bin/flatcar-install

Before you build the image, make sure you have TINKERBELL_HOST_IP environment variable set, pointing to the Tinkerbell server IP address. This can usually be done by sourcing envrc file, generated by Tinkerbell’s setup.sh script. To load the environment variables from this file, run the following command:

source envrc

You should build the image using the following command:

docker build -t $TINKERBELL_HOST_IP/flatcar-install .

Then, you should push the image to Tinkerbell registry, so it can be pulled by workers during workflow execution:

docker push $TINKERBELL_HOST_IP/flatcar-install

Preparing Flatcar Container Linux images

For the installation, worker requires access to the Flatcar Container Linux images. Those can be accessed in 2 different ways:

Use official mirrors

If your workers have internet access, workers should be able to pull the Flatcar images from the official mirror. Please note, that this method will be slower than setting up local mirror for the images.

If you don’t have dedicated NAT gateway, which you can use for workers, you can make a Tinkerbell provisioner to act as one using the following command:

sudo iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE
sudo iptables -A FORWARD -i enp0s3 -j ACCEPT

Where enp0s3 is the interface name used for Tinkerbell.

Once done, please make sure your workers have gateway field configured in their hardware entries pointing to the Tinkerbell server IP address.

Example snippet of hardware entry with gateway defined:

...
   "ip_addresses" : [
      {
         "address" : "192.168.50.10",
         "address_family" : 4,
         "gateway" : "192.168.50.2",
         "netmask" : "255.255.255.0"
      }
   ]
...

Use local mirror

If your workers do not have internet access or if you want to speed up the provisioning process, you can set up a local Flatcar mirror, from where the Flatcar images will be pulled by workers. The images will be served by nginx running as part of Tinkerbell stack. The mirror can be created and updated using the official script.

Creating mirror

To prepare the directories for the mirror and download the mirroring script, run the following command:

mkdir /var/tinkerbell/nginx/misc/flatcar
cd /var/tinkerbell/nginx/misc/flatcar
wget https://github.com/kinvolk/flatcar-release-mirror/raw/master/flatcar-release-mirror.sh && chmod +x flatcar-release-mirror.sh

Then, run the mirror script:

./flatcar-release-mirror.sh --only-files 'flatcar_production_image\|version' --above-version 2344 --logfile /dev/stderr --channels stable

It will download all Flatcar images above version 2344 only from stable channel. This currently requires downloading around 1.1 GB of data.

If you want to download only the latest version, you can check the Flatcar releases here.

Please note, that downloading only specific channel/versions may limit the usage of the --channel and --version parameters in flatcar-install.

Using local mirror in the template

To use local mirror in the template, add the following arguments to the flatcar-install script in the flatcar-install task described in the next step:

- -b
- http://192.168.50.3/misc/flatcar/stable/amd64-usr

Where 192.168.50.3 is the Tinkerbell nginx IP address, which can be obtained from envrc file generated by setup.sh script, as TINKERBELL_NGINX_IP variable, for example by running the following command (if you previously run source envrc):

echo $TINKERBELL_NGINX_IP

Preparing template

Here is an example template, which can be used as a base for the next steps.

version: "0.1"
name: flatcar-install
global_timeout: 1800
tasks:
  - name: "flatcar-install"
    worker: "{{.machine1}}"
    volumes:
      - /dev:/dev
      - /statedir:/statedir
    actions:
      - name: "dump-ignition"
        image: flatcar-install
        command:
          - sh
          - -c
          - echo '{{.ignition}}' | base64 -d > /statedir/ignition.json
      - name: "flatcar-install"
        image: flatcar-install
        command:
          - /usr/local/bin/flatcar-install
          - -s
          - -i
          - /statedir/ignition.json

Ignition configuration

The recommended way of configuring Flatcar is via an Ignition file during installation.

Example template supports providing Ignition configuration in form of a Base64 encoded string injected when the workflow is created.

See Flatcar documentation about provisioning for more details.

To create a sample configuration, create a file named config.yaml with the following content:

passwd:
  users:
    - name: core
      ssh_authorized_keys:
        - YOUR_SSH_KEY

Then, use the following command to validate and encode your configuration:

ct -in-file config.yaml | base64 -w0; echo

The returned string can be then used while creating the workflow.

Target disk

By default the template installs Flatcar to the smallest disk found on the worker using the -s flag.

Extra installation parameters

See Flatcar documentation to see all available parameters.

Creating

After modifying the example template, you need to create it in Tinkerbell using the following command:

tink template create -n flatcar-install -p /tmp/flatcar-install.tmpl

Please keep the ID of created template, as it will be used in next steps.

Creating workflow

After creating the template, you need to create the workflow object. This can be done using the following command:

tink workflow create -t TEMPLATE_ID -r '{"machine1": "02:42:db:98:4b:1e", "ignition": "eyJpZ25pdGlvbiI6eyJjb25maWciOnt9LCJzZWN1cml0eSI6eyJ0bHMiOnt9fSwidGltZW91dHMiOnt9LCJ2ZXJzaW9uIjoiMi4yLjAifSwibmV0d29ya2QiOnt9LCJwYXNzd2QiOnt9LCJzdG9yYWdlIjp7fSwic3lzdGVtZCI6e319"}'

This command will return the workflow ID, which is needed to check the status of the workflow. Template ID will no longer be used.

The Ignition configuration string in the example is just an empty ignition configuration. You should replace it with your configuration generated as explained in section [Ignition configuration](#Ignition configuration).

Provisioning

With the workflow created, you can boot/reboot your worker(s), so it picks up the new workflow.

You can track progress of the workflow execution using the following commands:

tink workflow state WORKFLOW_ID
tink workflow events WORKFLOW_ID

Once the workflow is finished you can reboot the worker and, after configuring the worker to boot from disk, it should now boot Flatcar Container Linux.