Flatcar Linux in VMware Player — 5 minute command line deploy

So I needed to create a new Kubernetes Lab. Back in time, I’ve created a shell script to deploy a lot of CoreOS servers to my VMware Player, but I hadn’t touched that script since that time.

With the deprecation of CoreOS and the glorious rise of Flatcar Linux to save us, and while needing to test some stuffs in Calico, it came to my mind ‘why not write how to quick deploy a Flatcar Linux VM in VMware Player without scripts?’. So here we go.

You will need:

  • The OVA of Flatcar Linux
  • CoreOS Configuration Transpiler (or you can write your Ignition file by your own, but really, not recommended). BTW you will need to compile Configuration Transpiler (sorry about that), but I think in a near future they will provide binaries. Anyway, it’s a simple and single Go program compilation
  • VMware player / ovftool and both are included in the VMware player installer

Writing the Configuration File

So the first step is to generate a valid Container Linux Configuration containing at least a user with an SSH key and the hostname of the VM. You can configure the VM with whatever is supported by the Configuration.

Let’s create a file called config.yaml

 1passwd:
 2  users:
 3    - name: core
 4      ssh_authorized_keys:
 5        - ssh-rsa AAAAB3NzaC1y...... user@springfield
 6storage:
 7  files:
 8    - path: /etc/hostname
 9      filesystem: root
10      mode: 0644
11      contents: 
12        inline: homer
13      user:
14        id: 0
15      group:
16        id: 0

The above code will be used when bootstraping Flatcar Linux to create/change the user core to allow SSH authentication with the following SSH Public Key, and also write a file called /etc/hostname containing the hostname of the machine. This file will be used by Flatcar CL to configure its hostname.

Please be aware this is a YAML, you should not copy/paste to not be punished by some missing space/tab :D

You can now ‘transpile’ this configuration and transform it into a JSON that will be used by Ingition when the VM is booting for the first time.

Running the command ct --in-file config.yaml --pretty it shall output a prettified version of an ignition file:

 1{ 
 2  "ignition": { 
 3    "config": {}, 
 4    "security": { 
 5      "tls": {} 
 6    }, 
 7    "timeouts": {}, 
 8    "version": "2.2.0" 
 9  }, 
10  "networkd": {}, 
11  "passwd": { 
12    "users": [ 
13      { 
14        "name": "core", 
15        "sshAuthorizedKeys": [ 
16          "ssh-rsa AAAAB3NzaC1y...... user@springfield"
17        ] 
18      } 
19    ] 
20  }, 
21  "storage": { 
22    "files": [ 
23      { 
24        "filesystem": "root",
25        "group": { 
26          "id": 0 
27        }, 
28        "user": { 
29          "id": 0 
30        }, 
31        "path": "/etc/hostname", 
32        "contents": { 
33          "source": "data:,homer", 
34          "verification": {} 
35        }, 
36        "mode": 420 
37      } 
38    ] 
39  }, 
40  "systemd": {} 
41}

Now you can grab this JSON and convert to base64 that will be read by Flatcar when booting. This does not need to be converted to base64, but the chance to have some bad character in the middle messing with your configuration will be reduced.

The full command is ct --in-file config.yaml --pretty |base64 -w0 but please BE AWARE that in MacOS/Darwin the base64 command does not have a -w0 flag, so you’ll need to sed/replace all the ending lines, turning the base64 into a full line without breaks, as the following:

1ewogICJpZ25pdGlvbiI6IHsKICAgICJjb25maWciOiB7fSwKICAgICJzZWN1cml0eSI6IHsKICAgICAgInRscyI6IHt9CiAgICB9LAogICAgInRpbWVvdXRzIjoge30sCiAgICAidmVyc2lvbiI6ICIyLjIuMCIKICB9LAogICJuZXR3b3JrZCI6IHt9LAogICJwYXNzd2QiOiB7CiAgICAidXNlcnMiOiBbCiAgICAgIHsKICAgICAgICAibmFtZSI6ICJjb3JlIiwKICAgICAgICAic3NoQXV0aG9yaXplZEtleXMiOiBbCiAgICAgICAgICAic3NoLXJzYSBBQUFBQjNOemF[........]

Deploying to VMware Player

Well, assuming you’ve reached here with the correct base64 file created, containing the correct configuration for Flatcar Container Linux, now you just need to create the Virtual Machine using ovftool and it will be ready to be used.

1ovftool --allowExtraConfig --X:enableHiddenProperties \
2--X:injectOvfEnv --name=flatcar --memorySize:'*'=3072 \
3--extraConfig:guestinfo.coreos.config.data.encoding=base64 \
4--extraConfig:guestinfo.coreos.config.data=THE_GENERATED_BASE_64 \
5--net:"VM Network"="NAT" flatcar.ova newdir

Some points in this command:

  • As said, you don’t need to use a base64 config but will need also to remove the flag --extraConfig:guestinfo.coreos.config.data.encoding
  • You need to replace the value in guestinfo.coreos.config.data to the base64 generated in the previous step
  • You can use whatever network from VMware Player you want, if you want a bridge instead of a Nat just replace to --net:"VM Network"="Bridge"
  • If the newdir in the end of the command already exists it will just put the vmx from the machine inside that directory
  • The guestinfo.coreos.config.data and guestinfo.coreos.config.data.encoding are deprecated in favor of guestinfo.ignition.config.* but today this new key only works in Flatcar Alpha release.
  • ovftool cannot change the memory size. So even you’ve created your machine with the parameter --memorySize: you’ll have to manually change the amount of memory directly in the generated vmx file

After that, the VM can be turned on with:

vmplayer newdir/flatcar/flatcar.vmx

And voilá, you got a Flatcar Linux machine working.

Obviously you can grab the OVA and make the same deployment with Container Configuration in the VMPlayer GUI, but once automated this is much faster to create a farm of VMs for lab :)

Translations: