Migrating from cloud-config to Container Linux Config
Flatcar Container Linux started as a fork of CoreOS Container Linux. Historically, the recommended way to provision a CoreOS Container Linux machine was with a cloud-config. This was a YAML file specifying things like systemd units to run, users that should exist, and files that should be written. This file would be given to a CoreOS Container Linux machine, and saved on disk. Then a utility called coreos-cloudinit running in a systemd unit would read this file, look at the system state, and make necessary changes on every boot.
The current recommended method is provisioning with Container Linux Configs.
This document details how to convert an existing cloud-config into a Container Linux Config. Once a Container Linux Config has been written, it is given to the Config Transpiler to be converted into an Ignition Config. This Ignition Config can then be provided to a booting machine. For more information on this process, take a look at the provisioning guide .
The etcd and flannel examples shown in this document will use dynamic data in the Container Linux Config (anything looking like this: {PRIVATE_IPV4}
). Not all types of dynamic data are supported on all cloud providers, and if the machine is not on a cloud provider this feature cannot be used. Please see
here
for more information.
To see all supported options available in a Container Linux Config, please look at the Container Linux Config schema .
etcd2
In a cloud-config, etcd version 2 can be enabled and configured by using the coreos.etcd2.*
section. As an example of this:
#cloud-config
coreos:
etcd2:
discovery: "https://discovery.etcd.io/<token>"
advertise-client-urls: "http://$public_ipv4:2379"
initial-advertise-peer-urls: "http://$private_ipv4:2380"
listen-client-urls: "http://0.0.0.0:2379,http://0.0.0.0:4001"
listen-peer-urls: "http://$private_ipv4:2380,http://$private_ipv4:7001"
etcd can be configured in a more general way with a Container Linux Config. This CL Config will use the etcd-member.service systemd unit rather than the etcd2 service understood by cloud-config and coreos-cloudinit. The etcd-member service will download a version of etcd of the user’s choosing and run it. This means that in a Container Linux Config both etcd v2 and v3 can be configured.
This is done under the etcd section:
etcd:
version: 3.1.6
Omitting the version specification declares that the unit file should use the version of etcd matching the running version of Flatcar Container Linux.
Configuration options in this section can be provided the same way as they were in a cloud-config, with the exception of dashes (-
) being replaced with underscores (_
) in key names.
etcd:
name: "{HOSTNAME}"
advertise_client_urls: "{PRIVATE_IPV4}:2379"
initial_advertise_peer_urls: "{PRIVATE_IPV4}:2380"
listen_client_urls: "http://0.0.0.0:2379"
listen_peer_urls: "http://{PRIVATE_IPV4}:2380"
initial_cluster: "%m=http://{PRIVATE_IPV4}:2380"
flannel
Flannel is easily configurable in a cloud-config the same way etcd is, by using the coreos.flannel.*
section.
#cloud-config
coreos:
flannel:
etcd_prefix: "/coreos.com/network2"
The flannel section in a Container Linux Config is used the same way, and a version can optionally be specified for flannel as well.
flannel:
version: 0.7.0
etcd_prefix: "/coreos.com/network2"
locksmith
The coreos.locksmith.*
section in a cloud-config can be used to configure the locksmith daemon via environment variables.
#cloud-config
coreos:
locksmith:
endpoint: "http://example.com:2379"
Locksmith can be configured in the same way under the locksmith section of a Container Linux Config, but some of the accepted options are slightly different. Also the reboot strategy is set in the locksmith section, instead of the update section. Check out the Container Linux Config schema to see what options are available.
locksmith:
reboot_strategy: "reboot"
etcd_endpoints: "http://example.com:2379"
update
The coreos.update.*
section can be used to configure the reboot strategy, update group, and update server in a cloud-config.
#cloud-config
coreos:
update:
reboot-strategy: "etcd-lock"
group: "stable"
server: "https://public.update.flatcar-linux.net/v1/update/"
In the update section in a Container Linux Config the group and server can be configured, but the reboot-strategy option has been moved under the locksmith section.
update:
group: "stable"
server: "https://public.update.flatcar-linux.net/v1/update/"
units
The coreos.units.*
section in a cloud-config can define arbitrary systemd units that should be started after booting.
#cloud-config
coreos:
units:
- name: "docker-redis.service"
command: "start"
content: |
[Unit]
Description=Redis container
Author=Me
After=docker.service
[Service]
Restart=always
ExecStart=/usr/bin/docker start -a redis_server
ExecStop=/usr/bin/docker stop -t 2 redis_server
This section could also be used to define systemd drop-in files for existing units.
#cloud-config
coreos:
units:
- name: "docker.service"
drop-ins:
- name: "50-insecure-registry.conf"
content: |
[Service]
Environment=DOCKER_OPTS='--insecure-registry="10.0.1.0/24"'
And existing units could also be started without any further configuration.
#cloud-config
coreos:
units:
- name: "etcd2.service"
command: "start"
One big difference in Container Linux Config compared to cloud-configs is that the configuration is applied via Ignition before the machine has fully booted, as opposed to coreos-cloudinit that runs after the machine has fully booted. As a result units cannot be directly started in a Container Linux Config, the unit is instead enabled so that systemd will begin the unit once systemd starts.
Note: in this example an [Install]
section has been added so that the unit can be enabled.
systemd:
units:
- name: "docker-redis.service"
enable: true
contents: |
[Unit]
Description=Redis container
Author=Me
After=docker.service
[Service]
Restart=always
ExecStart=/usr/bin/docker start -a redis_server
ExecStop=/usr/bin/docker stop -t 2 redis_server
[Install]
WantedBy=multi-user.target
Drop-in files can be provided for units in a Container Linux Config just like in a cloud-config.
systemd:
units:
- name: "docker.service"
dropins:
- name: "50-insecure-registry.conf"
contents: |
[Service]
Environment=DOCKER_OPTS='--insecure-registry="10.0.1.0/24"'
Existing units can also be enabled without configuration.
systemd:
units:
- name: "etcd-member.service"
enable: true
ssh_authorized_keys
In a cloud-config the ssh_authorized_keys
section can be used to add ssh public keys to the core
user.
#cloud-config
ssh_authorized_keys:
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0g+ZTxC7weoIJLUafOgrm+h..."
In a Container Linux Config there is no analogous section to ssh_authorized_keys
, but ssh keys for the core user can be set just as easily using the passwd.users.*
section:
passwd:
users:
- name: core
ssh_authorized_keys:
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0g+ZTxC7weoIJLUafOgrm+h..."
hostname
In a cloud-config the hostname
section can be used to set a machine’s hostname.
#cloud-config
hostname: "coreos1"
The Container Linux Config is intentionally more generalized than a cloud-config, and there is no equivalent hostname section understood in a CL Config. Instead, set the hostname by writing it to /etc/hostname
in a CL Config storage.files.*
section.
storage:
files:
- filesystem: "root"
path: "/etc/hostname"
mode: 0644
contents:
inline: coreos1
users
The users
section in a cloud-config can be used to add users and specify many properties about them, from groups the user should be in to what the user’s shell should be.
#cloud-config
users:
- name: "elroy"
passwd: "$6$5s2u6/jR$un0AvWnqilcgaNB3Mkxd5yYv6mTlWfOoCYHZmfi3LDKVltj.E8XNKEcwWm..."
groups:
- "sudo"
- "docker"
ssh-authorized-keys:
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0g+ZTxC7weoIJLUafOgrm+h..."
This same information can be added to the Container Linux Config in the passwd.users.*
section.
passwd:
users:
- name: "elroy"
password_hash: "$6$5s2u6/jR$un0AvWnqilcgaNB3Mkxd5yYv6mTlWfOoCYHZmfi3LDKVltj.E8XNKEcwWm..."
ssh_authorized_keys:
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0g+ZTxC7weoIJLUafOgrm+h..."
groups:
- "sudo"
- "docker"
write_files
The write_files
section in a cloud-config can be used to specify files and their contents that should be written to disk on the machine.
#cloud-config
write_files:
- path: "/etc/resolv.conf"
permissions: "0644"
owner: "root"
content: |
nameserver 8.8.8.8
This can be done in a Container Linux Config with the storage.files.*
section.
storage:
files:
- filesystem: "root"
path: "/etc/resolv.conf"
mode: 0644
contents:
inline: |
nameserver 8.8.8.8
File specifications in this section of a CL Config must define the target filesystem and the file’s path relative to the root of that filesystem. This allows files to be written to filesystems other than the root filesystem.
Under the contents
section, the file contents are under a sub-section called inline
. This is because a file’s contents can be remote by replacing the inline
section with a remote
section. To see what options are available under the remote
section, look at the
Container Linux Config schema
.
manage_etc_hosts
The manage_etcd_hosts
section in a cloud-config can be used to configure the contents of the /etc/hosts
file. Currently only one value is supported, "localhost"
, which will cause your system’s hostname to resolve to 127.0.0.1
.
#cloud-config
manage_etc_hosts: "localhost"
There is no analogous section in a Container Linux Config, however the /etc/hosts
file can be written in the storage.files.*
section.
storage:
files:
- filesystem: "root"
path: "/etc/hosts"
mode: 0644
contents:
inline: |
127.0.0.1 localhost
::1 localhost
127.0.0.1 example.com