Pushing configuration to a node after installation
Kairos configuration mechanism is based on the cloud-config
file given during installation, however, it’s possible to extend the configuration by providing additional cloud-configs in either /oem
or /usr/local/cloud-config
.
By default, kairos
reads in lexicographic order YAML cloud-config files in the directories above, indeed, after installation you should be able to see the configuration generated by the interactive-installer as /oem/99_custom.yaml
in the system.
This mechanism can be used to set and enable persistent configuration on boot after node deployment.
We are going to see how to do that manually or with Kubernetes by using the
Manually
SSH into the node and copy the config file you want to add into /oem
. For instance, to add zram on boot we can copy the following file in /oem/100_zram.yaml
or /usr/local/cloud-config/100_zram.yaml
and reboot:
stages:
boot:
- name: "zram setup"
commands:
- modprobe zram
- echo lzo > /sys/block/zram0/comp_algorithm
- echo 1G > /sys/block/zram0/disksize
- mkswap --label zram0 /dev/zram0
- swapon --priority 100 /dev/zram0
name: "zfs setup"
With Kubernetes
To push configurations to a node, it is necessary system-upgrade-controller to be deployed in the target cluster which executes plan to the cluster nodes. In the example below, we use a plan to push a swapfile of 3gb enabled during boot, and restart the node afterward.
To install system-upgrade-controller, use kubectl:
kubectl apply -f https://github.com/rancher/system-upgrade-controller/releases/download/v0.13.4/system-upgrade-controller.yaml
Note
Several roll-out strategies can be used withsystem-upgrade-controller
which are not illustrated here in this example. For instance, it can be specified in the number of hosts which are running the upgrades, filtering by labels, and more. Refer to the project documentation on how to create efficient strategies to roll plans on the nodes. In the example above, the plans are applied to every host of the cluster, one-by-one in sequence.
The following pushes a new cloud config over the /oem
directory and reboots the node:
cat <<'EOF' | kubectl apply -f -
---
apiVersion: v1
kind: Secret
metadata:
name: custom-script
namespace: system-upgrade
type: Opaque
stringData:
swapfile.yaml: |
stages:
boot:
- name: "Setup swapfile"
if: "[ ! -e /usr/local/swapfile ]"
commands:
- dd if=/dev/zero of=/usr/local/swapfile bs=1M count=3K
- mkswap /usr/local/swapfile
- name: "Enable swapfile"
if: "[ -e /usr/local/swapfile ]"
commands:
- swapon /usr/local/swapfile
add-oem-file.sh: |
#!/bin/sh
set -e
if diff /host/run/system-upgrade/secrets/custom-script/swapfile.yaml /host/oem/10_swapfile.yaml >/dev/null; then
echo Swapfile present
exit 0
fi
# Note: this is a symlink. We can also cp -L, but be aware that standard cp doesn't work.
cat /host/run/system-upgrade/secrets/custom-script/swapfile.yaml > /host/oem/10_swapfile.yaml
sync
mount --rbind /host/dev /dev
mount --rbind /host/run /run
nsenter -i -m -t 1 -- reboot
exit 1
---
apiVersion: upgrade.cattle.io/v1
kind: Plan
metadata:
name: add-swapfile
namespace: system-upgrade
spec:
concurrency: 1
# This is the version (tag) of the image.
version: "@flavorRelease-standard-amd64-generic-v3.1.3-k3sv1.31.0-k3s1"
nodeSelector:
matchExpressions:
- { key: kubernetes.io/hostname, operator: Exists }
serviceAccountName: system-upgrade
cordon: false
upgrade:
# Here goes the image which is tied to the flavor being used.
# Currently can pick between opensuse and alpine
image: quay.io/kairos/@flavor
command:
- "/bin/bash"
- "-c"
args:
- bash /host/run/system-upgrade/secrets/custom-script/add-oem-file.sh
secrets:
- name: custom-script
path: /host/run/system-upgrade/secrets/custom-script
EOF