NOTE: If you're doing this in VMware, now would be a good time to take a snapshot, so that you can repeatedly test provisioning on a clean box.
Now that our server hardware has been prepared, we can install the OS. We provide an Ignition script that specifies how we want the system to be configured, that will be run on first boot, to provision the system. However, the Ignition file format is a bit difficult to work with, so scripts are written in Butane format, which is then converted to Ignition.
Here's a simple Butane script that configures the password[1]You would normally use SSH keys for login, but my server is for internal use only, so I just use a password. for the default core user (use mkpasswd to generate the hash):
variant: fcos
version: 1.5.0
passwd:
users:
- name: core
password_hash: $y$j9T$DUQ4JpHLE86HQpQemBNs3.$W2K2ymcyTaADWJfrZGbBnYFndwfYGtx6fs0lhzQJtu5
And to convert it to Ignition format[2]You will need to install the butane package.:
butane --pretty --strict config.bu >config.ign
We then run a command in the pre-installation environment that loads the base CoreOS image onto the system disk, plus our Ignition config file, so that when the computer boots up, it processes that Ignition config, to provision the system.
The problem is getting the Ignition file to the installer. The pre-installation environment is minimal, so VMware Tools and open-vm-tools are not there, so we can't use VMware's shared folders. And even if we could, the installer takes a URL, and the file:// protocol doesn't work.
The easiest way is to prepare the config files on another machine, and then run python -m http.server in that directory, which runs a little web server that serves files from that directory. Then, we can provide a URL to the Ignition config file[3]Where 10.2.2.10 is the IP address of my host machine.:
sudo coreos-installer install \
/dev/sda \
--insecure-ignition \
--ignition-url http://10.2.2.10:8000/config.ign
The installer will load the base image on the specified device, and when it's done, type reboot to boot the server. Our Ignition config will be processed during this first boot, and when you are presented with the login prompt, you should be able to login in as the core user, using the password you specified earlier.
Automatically generating the Ignition config file
Having to run the butane command each time you change the Butane config file gets very old very fast, so I wrote a script that monitors this file for changes, and automatically re-generates the Ignition file:
cd $( dirname "$0" )
prev_md5=
while true; do
md5=$( md5sum config.bu files/* )
if [ "$md5" = "$prev_md5" ]; then
sleep 1
else
if butane --pretty --strict --files-dir ./files/ config.bu >config.ign; then
echo "Updated: `date`"
fi
prev_md5=$md5
fi
done
Note that it also watches other files in a files/ sub-directory, that we will be creating later in this tutorial.
Configuring the server
To set the server's hostname, we configure Ignition to set up a file at /etc/hostname:
storage:
files:
- path: /etc/hostname
mode: 0644
contents:
inline: vm-k3s
We also do something similar to configure the NIC with a static IP address:
storage:
files:
- path: /etc/NetworkManager/system-connections/ens33.nmconnection
mode: 0400
overwrite: true
contents:
local: nic.nmconnection
where nic.nmconnection looks like this[4]Make sure that the interface name matches what is on your machine.:
[connection] interface-name = ens33 type = ethernet [ipv4] method = manual address1 = 10.2.2.33/24,10.2.2.1 dns = 10.2.2.1
Note that while this file content can be specified inline in the Butane config file, the file will get very big very quickly[5]And much less readable., so I've moved it out into an external file. In this case, we need to have a --files-dir parameter when converting to Ignition format, that specifies the base directory of these external files e.g.
butane --pretty --strict --files-dir ./files/ config.bu >config.ign
Finally, I like to disable auto-updates[6]I update systems on my schedule, after ensuring that everything's backed up safely, and checking that everything works properly afterwards.:
storage:
files:
- path: /etc/zincati/config.d/90-disable-auto-updates.toml
mode: 0644
contents:
inline: |
[updates]
enabled = false
Go back to your clean VM snapshot, run coreos-installer install again, with the updated Butane config, to re-provision the machine, and you should see all these changes have been applied to the new installation.
References
| ↑1 | You would normally use SSH keys for login, but my server is for internal use only, so I just use a password. |
|---|---|
| ↑2 | You will need to install the butane package. |
| ↑3 | Where 10.2.2.10 is the IP address of my host machine. |
| ↑4 | Make sure that the interface name matches what is on your machine. |
| ↑5 | And much less readable. |
| ↑6 | I update systems on my schedule, after ensuring that everything's backed up safely, and checking that everything works properly afterwards. |










I am a 
