Installing Talos Linux on Raspberry Pi 4

Explore the full setup process for running Talos Linux on a Raspberry Pi 4 in this guide.

If you have never heard of Talos Linux, it is a complete Kubernetes Linux distribution which can run anywhere. It does not have the classic SSH connection or even a shell, everything is managed with a single configuration file and a gRPC API. According to the official documentation:

Talos is a container optimized Linux distro; a reimagining of Linux for distributed systems such as Kubernetes. Designed to be as minimal as possible while still maintaining practicality. For these reasons, Talos has a number of features unique to it:

  • it is immutable

  • it is atomic

  • it is ephemeral

  • it is minimal

  • it is secure by default

  • it is managed via a single declarative configuration file and gRPC API

Talos can be deployed on container, cloud, virtualized, and bare metal platforms.

Tip
It would be a good idea if you set up the static IPs of each of the Raspberry Pi boards via their MAC address on your router before beginning. This is so you don’t have to look for the dynamically assigned IP when you boot them up. If you don’t know how to find out the MAC address, check this guide.

First, you need to update the EEPROM of your Raspberry Pi 4. To do so, you can use the rpi-imager tool. To install it:

1
2
3
4
5
# Debian based systems
sudo apt install rpi-imager

# Arch based systems
yay -S rpi-imager

After you have installed it, insert the SD card in the SD card reader of your laptop (or into an external reader if you have one). Now open up rpi-imager and do the following:

  1. Click on Choose OS in the Operating System section.

  2. Select the `Misc utility images submenu.

  3. Select Bootloader and select the SD Card Boot image.

  4. Click on Choose Storage in the Storage section.

  5. Click on Write to flash the image on the SD Card.

Insert the card into the Raspberry Pi and wait around 10 seconds to finish. If you have a screen connected, when it’s finished, the whole screen will be green. If you do not have a screen, and if the flash was successful, the green LED light on the board will blink rapidly forever. You can now power off the RPI and take the SD card out.

First, you need to download the image. Replace the version if you wish, for all available versions, check the Talos release page on Github:

1
2
3
export TALOS_VERSION=v1.0.2
curl -LO https://github.com/siderolabs/talos/releases/download/$TALOS_VERSION/metal-rpi_4-arm64.img.xz
xz -d metal-rpi_4-arm64.img.xz

Now, insert the SD card in your machine, and find its name with:

1
lsblk

It should display something like mmcblk0 for the SD card. Now you are ready to flash the image:

1
sudo dd if=metal-rpi_4-arm64.img of=/dev/mmcblk0 conv=fsync bs=4M

Now you can insert the SD card back into the Raspberry Pi and power it on!

To be able to communicate with the system, you need to install the talosctl tool. You can do that by running the following:

1
2
3
export TALOS_VERSION=v1.0.2
curl -Lo /usr/local/bin/talosctl https://github.com/siderolabs/talos/releases/download/$TALOS_VERSION/talosctl-$(uname -s | tr "[:upper:]" "[:lower:]")-amd64
chmod +x /usr/local/bin/talosctl

Now, the official guide suggests that you can do it with an interactive mode, and you can do it that way. However, I prefer having more control over the configuration, so I suggest that you generate a config first and edit the fields.

To generate a config, do the following:

1
2
3
4
export TALOS_CLUSTER_NAME=example
export RASPBERRY_PI_IP=192.168.0.241
talosctl gen config $TALOS_CLUSTER_NAME https://$RASPBERRY_PI_IP:6443 -o $HOME/.talos/
talosctl config merge $HOME/.talos/talosconfig

These commands will generate the configuration file as talosconfig in the $HOME/.talos directory, and because by default talosctl looks for the file $HOME/.talos/config, we are merging it, so we don’t have to specify the --talosconfig flag on each command.

The generation of the config also created a controlplane.yaml and worker.yaml example configuration files in the $HOME/.talos directory. Now it’s time to configure them. If you have a single Raspberry Pi only, you will only edit the controlplane.yaml configuration file. If you have several, you will also create separate worker.yaml files.

From the generated examples, create the files and copy over the YAML configuration in them before you edit. The $HOME/.talos directory structure should look like this if you have a setup of 3 Kubernetes nodes, where you have a single control plane and 2 worker nodes:

1
2
3
4
5
6
7
.talos
├── config
├── example-agent-0.yaml
├── example-agent-1.yaml
└── example-main-0.yaml

0 directories, 4 files

The examples are filled with comments which clearly explain what every field is for. For even more information about each field, visit the official reference where you will find everything you need.

Now open each file and configure it. You can take a look at the additional guides here on Kubito:

If something is not listed, or it is unclear, check if Kubito has anything else that can help you out in the Talos Linux Category!

Now that you have configured every node, you are ready to apply the configuration. Do the following:

  • Bootstrap the first control plane node of type controlplane. You can read more in the control plane configuration. If everything is configured, proceed with:

    1
    2
    
    export RASPBERRY_PI_IP=192.168.0.241
    talosctl apply-config --insecure --nodes $RASPBERRY_PI_IP --file $HOME/.talos/example-main-0.yaml
    

    This command will start installing everything. If you don’t have a screen connected via HDMI to the node, you can follow the logs with:

    1
    
    talosctl dmesg -f -n $RASPBERRY_PI_IP
    
  • Once you see that the installation has finished and the logs say that the node is ready, add the endpoint configuration to $HOME/.talos/config. If you chose a virtual IP (see the guide) the endpoint IP should be that one. If not, it needs to be the control plane node IP:

    • Without virtual IP:

      1
      
      talosctl config endpoint $RASPBERRY_PI_IP
      
    • With virtual IP:

      1
      2
      
      export TALOS_VIRTUAL_IP=192.168.0.250
      talosctl config endpoint $TALOS_VIRTUAL_IP
      
  • Finally, get the kubeconfig, merge it with your local one, and set the current context to it:

    1
    
    talosctl kubeconfig --force-context-name example --nodes $RASPBERRY_PI_IP
    
  • Check if the node is up and running:

    1
    
    kubectl get nodes -o wide
    

Now that the control plane is up and running, just apply the configuration for your worker nodes:

1
2
3
4
export RASPBERRY_PI_IP_WORKER_1=192.168.0.242
export RASPBERRY_PI_IP_WORKER_2=192.168.0.243
talosctl apply-config --insecure --nodes $RASPBERRY_PI_IP_WORKER_1 --file $HOME/.talos/example-agent-0.yaml
talosctl apply-config --insecure --nodes $RASPBERRY_PI_IP_WORKER_2 --file $HOME/.talos/example-agent-1.yaml

For easier management, create aliases in ~/.zshrc or ~/.bashrc for each of the nodes. We are not setting the nodes in the $HOME/.talos/config because we want to use explicit commands for each node. This helps us prevent mistakes like rebooting all nodes at once and similar:

1
2
3
alias example-main-0='talosctl --nodes 192.168.0.241'
alias example-agent-0='talosctl --nodes 192.168.0.242'
alias example-agent-1='talosctl --nodes 192.168.0.243'

One example of using the aliases is editing the machine configuration:

1
example-main-0 edit machineconfig