Terry : CoreOS on Vagrant

What is CoreOS?

CoreOS is a new Linux distribution that has been re-designed to provide features needed to run modern infrastructure stacks. The strategies and architectures that influence CoreOS allow companies like Google, Facebook and Twitter to run their services at scale with high resilience.

CoreOS is designed to be a modern, minimal base to build your platform. Consumes 40% less RAM on boot than an average Linux installation.

Allows for very quick PXE/iPXE booting.

CoreOS core components


  • Linux kernel
  • Btrfs
  • LXC
  • Docker

Running CoreOS on Vagrant

Running CoreOS with Vagrant is the easiest way to bring up a single machine or virtualize an entire cluster on your laptop. Since the true power of CoreOS can be seen with a cluster, we're going to concentrate on that. Instructions for a single machine can be found towards the end of the guide.

Install VirtualBox and Vagrant

VirtualBox 4.3.14 or above

Vagrant 1.6.3 or above

Clone the Vagrant Repository

Clone the Vagrant repository that contains the CoreOS Vagrantfile. This file tells Vagrant where it can find the latest disk image of CoreOS. Vagrant will download the image the first time you attempt to start the VM.

git clone https://github.com/coreos/coreos-vagrant.git
cd coreos-vagrant
Edit Configuration files

In this case, we use single machine.

cp config.rb.sample config.rb
cp user-data.sample

Edit config.rb

# Size of the CoreOS cluster created by Vagrant

# Official CoreOS channel from which updates should be downloaded

# Log the serial consoles of CoreOS VMs to log/
# Enable by setting value to true, disable with false
# WARNING: Serial logging is known to result in extremely high CPU usage with
# VirtualBox, so should only be used in debugging situations

# Enable port forwarding of Docker TCP socket
# Set to the TCP port you want exposed on the *host* machine, default is 2375
# If 2375 is used, Vagrant will auto-increment (e.g. in the case of $num_instances > 1)
# You can then use the docker tool locally by setting the following env var:
#   export DOCKER_HOST='tcp://'

# Setting for VirtualBox VMs
$vb_gui = false
$vb_memory = 1024
$vb_cpus = 2

user-data can be left untouched.

Start the Virtual Machine

Start Machine using Vagrant's default VirtualBox provider

vagrant up
# Connect to the machine
vagrant ssh core-01 -- -A
Shared Folder

Optionally, you can share a folder from your laptop into the virtual machine. This is useful for easily getting code and Dockerfiles into CoreOS.

config.vm.synced_folder ".", "/home/core/share", id: "core", :nfs => true, :mount_options => ['nolock,vers=3,udp']
New Box Versions

CoreOS is a rolling release distribution and versions that are out of date will automatically update. If you want to start from the most up to date version you will need to make sure that you have the latest box file of CoreOS. You can do this using vagrant box update - or, simply remove the old box file and Vagrant will download the latest one the next time you vagrant up.

vagrant box remove coreos-alpha virtualbox

If you'd like to download the box separately, you can download the URL contained in the Vagrantfile and add it manually:

vagrant box add coreos-alpha /path/to/file

Using Docker CLI

Launching a container

Launching a container is simple as docker run + the image name you would like to run + the command to run within the container. If the image doesn't exist on your local machine, docker will attempt to fetch it from the public image registry.

It's important to note that containers are designed to stop once the command executed within them has exited. For example, if you ran /bin/echo hello world as your command, the container will start, print hello world and then stop

docker run ubuntu /bin/echo hello world

Let's launch an Ubuntu container and install Apache inside of it using the bash prompt

docker run -t -i ubuntu /bin/bash

The -t and -i flags allocate a pseudo-tty and keep stdin open even if not attached. This will allow you to use the container like a traditional VM as long as the bash prompt is running. Install Apache with apt-get install apache2.

Port forwarding is required. For example, allowing port 8080 into a container

docker run -t -i -p 8080:80 ubuntu /bin/bash

Network traffic entering the CoreOS host on port 8080 will be allowed into the container. Inside of the container the traffic will appear to enter over port 80. For example, this allows a web server to always listen on 80 no matter how many times it is running in the cluster.

Commiting a Container

After that completes, we need to commit these changes to the container with the container ID and the image name. Otherwise once it is stopped the changes are gone.

To find the container ID, open another shell (so the container is still running) and read the ID using

docker ps
$ docker ps
CONTAINER ID        IMAGE                     COMMAND             CREATED             STATUS              PORTS               NAMES
746018ff7cbc        terrywang/ubuntu:latest   /bin/bash           16 hours ago        Up 16 hours                             ecstatic_kowalevski

The image name is in the format of username/name. We're going to use coreos as our username in this example but you should sign up for a Docker.IO user account and use that instead.

It's important to note that you can commit using any username and image name locally, but to push an image to the public registry, the username must be a valid Docker.IO user account.

Commit the container with the container ID, your username, and the name apache

docker commit 746018ff7cbc coreos/apache

The overlay filesystem works similar to git: our image now builds off of the ubuntu base and adds another layer with Apache on top. These layers get cached separately so that you won't have to pull down the ubuntu base more than once.

Keeping the Apache Container Running

Now we have our Ubuntu container with Apache running in one shell and an image of that container sitting on disk. Let's launch a new container based on that image but set it up to keep running indefinitely. The basic syntax looks like this, but we need to configure a few additional options that we'll fill in as we go

docker run [options] [image] [process]

The first step is to tell docker that we want to run our coreos/apache image

docker run [options] coreos/apache [process]

Run container detached

The most important option is to run the container in detached mode with the -d flag. This will output the container ID to show that the command was successful, but nothing else. At any time you can run docker ps in the other shell to view a list of the running containers. Our command now looks like:

docker run -d coreos/apache [process]

Run Apache in Foreground

We need to run the apache process in the foreground, since our container will stop when the process specified in the docker run command stops. We can do this with a flag -D when starting the apache2 process

/usr/sbin/apache2ctl -D FOREGROUND

Let's add that to our command

docker run -d coreos/apache /usr/sbin/apache2ctl -D FOREGROUND

Network Access to 80

The default apache install will be running on port 80. To give our container access to traffic over port 80, we use the -p flag and specify the port on the host that maps to the port inside the container. In our case we want 80 for each, so we include -p 80:80 in our command

docker run -d -p 80:80 coreos/apache /usr/sbin/apache2ctl -D FOREGROUND

You can now run this command on your CoreOS host to create the container. You should see the default apache web page when you load either localhost:80 or the IP of your remote server. Be sure that any firewall or EC2 Security Group allows traffic to port 80.