One thing that was never clear to me when I started learning CoreOS were techniques for rapidly testing out different CoreOS features. I will spend some time walking folks through a few of tips and tricks that I have learned so far along the way learning about CoreOS.
The folks at CoreOS have an awesome repo for testing out features locally, called coreos-vagrant. If you haven’t heard of it or used it, go check it out. Another great resource for getting started with the CoreOS Vagrant project are the docs on the CoreOS website, you should be able to find most of the use cases there.
So in this post I will be going over some of what is already detailed in the docs and README but will additionally fill readers in with a few extra tips and tricks I have discovered so far along the way. I am surprised by all of the hidden secrets I frequently discover buried in CoreOS and its documentation. It is always fun to find new features and capabilities of the OS that you didn’t know existed.
So to get started we need to briefly cover Vagrant. Vagrant has made things soooo much easier to test. If you haven’t heard of Vagrant, definitely go check it out and get familiar with it. It is basically an interface for controlling VM’s and their various components locally.
When I first starting testing things out with CoreOS I would spin boxes up in either Digital Ocean or AWS with a cloud-config that I would agonize over because I was afraid of screwing up small details or provisioning the server incorrectly. It is also more of a hassle to provision a cloud server because it involves some additional authentication keys for command line tools or manually creating instances via GUI tools. However, when testing VM’s you often destroy and recreate instances and so that additional overhead can become tedious.
Using Vagrant I can quickly and easily make changes to a configuration or even test out entirely different CoreOS versions in minutes and not care about getting small details wrong since a) it doesn’t cost me anything extra to run the instance locally and b) I can blow out and reprovision in a few seconds.
I think this local Vagrant approach also makes you a better CoreOS citizen because it forces you to look at what you’re doing and fix issues more often because you are iterating more frequently and therefore testing more features and options of CoreOS out (at least this has been my experience so far).
Cloud-config was initially a painful part of the learning process for me but I have grown to love it. I like to test out new cloud-configs quite a bit and at first it was frustrating to screw up configs because that meant I had to redo the entire server bootstrap process in DO or AWS. Terraform makes the provisioning process less painful but it is still a little bit of a hassle, especially when you are smoke testing configs to make sure they work.
Luckily it is dead simple to set up cloud-configs using Vagrant locally. The repo comes with a “user-data.sample” file that you can copy to “user-data” and away you go, make any modifications you may need or config changes you want to test out. The local testing via cloud-config discovery alone was a game changer for me.
To fix a problem with your cloud-config you can simply edit the user-data file that was copied in to place on the server and then rerun cloud-init to fix the provisioning. Below is an example of how to do this cloud-init provisioning.
Before you provision any of you cloud configs though, I recommend testing them out by running them through the CoreOS cloud-config validator tool to help identify any potential problems your config might have before you even run it. There is an experimental validation flag option in the cloud-init binary shipped with the OS if you want to try it out as well. Most of the time I find it just as easy to copy the config in to the online checker but there are definitely scenario’s and use cases where it might be a good idea to test locally, I just haven’t needed to yet.
Next, if you have an existing config on your server and would like to modify the existing content and reprovision the server with the updated cloud-config, without destroying and recereating the server, use the following.
sudo /usr/bin/coreos-cloudinit --from-file /path/to/user-data
Then you can watch the logs to make sure they are doing what you expect.
journalctl -b _EXE=/usr/bin/coreos-cloudinit
If you don’t want to muck around with the cloud-config stuff on the server you can easily blow up the server, modify the user-data file on the host and just reprovision the Vagrant machine. Obviously this method will take a little bit longer but it isn’t a significant penalty and is also is easier to keep track of since you know exactly what user-data values are being passed in the Vagrant machine from the host and can more easily stay on top of the changes you are making.
The config section in Vagrant gives you a great deal of flexibility when testing CoreOS out locally. For example, you can control most options that CoreOS gets provisioned with, including the version release with this,
$image_version = "723.1.0"
You can specify any version inside the quotes to bootstrap the CoreOS instance. This is handy for testing out new alpha features or things are broken in one release. Quickly changing versions gives you and easy way to check if they are fixed yet by either rolling back or forward easily.
In the config.rb file you can also specify server level details for things like the hostname,
How many instances to provision,
Custom memory or cpu’s for the instance,
$vm_memory = 1024 $vm_cpus = 1
Shared folders, forwarded ports etc. Granted these are Vagrant level configurations, it still makes working with CoreOS much easier in my opinion.
Additionally, there is an option to provision the instance with an etcd/2 discovery token to bootstrap etcd when the server gets created. If you have ever dealt with testing out etcd, this is an option way for quickly bringing servers up and down without ever having to worry about reissuing the discovery tokens, etc.
Tips and Tricks
I have found a few other tips and tricks along the way that can be used when testing CoreOS locally or after it has been deployed.
The first tip is getting the OS version to update manually (without reprovisioning via Vagrant). For most testing puproses I usually turn off automatic reboots using the following key in my cloud configs.
coreos: update: group: alpha reboot-strategy: off
This will tell CoreOS to try to use the latest alpha (if a version is not specified in your config.rb) and tell CoreOS to not reboot.
Sometimes it is easier to just manually updated the OS than destroy the VM and specify a new version. To update manually you can run the following commnads.
update_engine_client -check_for_update journalctl -f (this will follow the update progress) sudo reboot (after the updated version is downloaded)
After you see that the newest release has been downloaded you can reboot the server and it should boot up with the newest updates.
Another cool trick is to customize the toolbox on CoreOS. I’ve written about this before but figured I might as well mention it again since it is a useful trick.
By default the toolbox runs Fedora, but we are mainly an Ubuntu/Debian shop so are much more comfortable using the tools bundled with those distros. It is pretty simple to configure the toolbox to automatically use Debian when the instance is provisioned using the following key in your cloud-config.
-write_files: - path: /home/core/.toolboxrc owner: core content: | TOOLBOX_DOCKER_IMAGE=ubuntu TOOLBOX_DOCKER_TAG=14.04
When you run the “toolbox” command it will look for Ubuntu instead of the default Fedora image.
Another trick I have used a few times is overriding the update strategy on a server that has already been provisioned using environment variables.
As I have discovered, much of the configuration that takes place happens via environment variables. So to update the reboot strategy you can modify the /etc/coreos/update.conf file. The contents should look something like this:
If you’d like to have the server use alpha images change the key to GROUP=alpha, etc. for the keys inside the configuration. After making your changes, you will need to restart the update-engine service.
sudo systemctl restart update-engine
The system should pick up the changes you made and you should be good to go.
The last trick I will highlight in this post is how to get “drop in” services working. This is a core part of how systemd (especially on CoreOS) works, but so few realize how it works. By creating a drop in you are simply extending a service to read in extra bits of configuration. For example, the following unit file extends the system etcd2 service.
Create the following file,
The etcd2 service will look in this location for its extra configuration.
[Service] # General settings Environment=ETCD_NAME=etcd-config Environment=ETCD_VERBOSE=1
Inside the unit file we are just setting some extra environment variables that etcd2 can then use as flags to instruct it how to run.
There are obviously a lot more CoreOS tricks. I have just highlighted a few of my favorites here. I suggest looking at the CoreOS docs, there is a lot of good information over there. Feel free to comment with your own tricks and I will be sure to try them out and get them added here.