patg.net

home

Docker: Containers for the Masses -- Using Ansible to build Docker images

20 Jun 2014

Happy summer solstice! For the longest day of the year, welcome to a short blog post on using Ansible to automate the building of Docker images. This post is part of the blog series of posts, "Docker: Containers for the Masses".

For the reader just joining, the previous posts in this series are:

Now that the basics of using Ansible to manage Docker have been introduced, particularly the Ansible docker module, the next module to cover is the docker_image module. The docker_image module is an Ansible module that uses the Docker python client to connect to the Docker daemon (via a RESTful API) to build an images. This module, like any other module, can be creatively used in any playbook to build a Docker image that can be then run as a container.

Building Docker Images with Ansible

Refering to the post in this blog series on using Docker, examples showing how to build Docker images were given as well as covering the Dockerfile. As the reader could see, there was a manual process to do this. A way of automating this is to use the Ansible docker_image module.

Using this module is painfully simply. Well, not painful, but certainly simple!

A simple playbook:

- hosts: local
  tasks:
    - name: build Apache image
      local_action:
          module: docker_image
          path: ../docker-image-source/ssh/
          name: CaptTofu/apache
          state: present


In the above example, as the YAML makes obvious, specifies using a local_action (since this is not something you typically run across multiple hosts), the name of the docker_image module, the path to where the docker file is, the name of the image and even more obvious the state, in this case present which means "yes, please build this!".

When the playbook is run, the following output would be expected:

$ ansible-playbook -i hosts images.yml

PLAY [local] ******************************************************************

GATHERING FACTS ***************************************************************
ok: [localhost]

TASK: [build Apache image] ****************************************************
changed: [localhost]

PLAY RECAP ********************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0


And the build can be verified:

$ docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
CaptTofu/apache           latest              3be6decea409        9 minutes ago       297.5 MB


A more interesting example

The above example was obviously very simple. A more interesting example can be found in the author's git repository at https://github.com/CaptTofu/ansible-docker-presentation. This repository was used for recent attendence at AnsibleFest NYC 2014 to provide a practical example of using Ansible to do a number of things including building four different Docker images and then running those images as Docker containers across 45 HP Moonshot cartridges.

The repository contains several roles including an image_builder role that has the following tasks:

---
- name: check or build ssh image
  docker_image: path="/ssh/" name="/ssh" state=present
- name: check or build apache image
  docker_image: path="/apache/" name="/apache" state=present
- name: check or build haproxy image
  docker_image: path="/haproxy/" name="/haproxy" state=present
- name: check or build percona XtraDB Cluster image
  docker_image: path="/pxc/" name="/pxc" state=present


The variables seen in this playbook task are set in the vars/main.yml file:

---
images_source_path: /home/username/ansible_work/docker-image-source
repository_name: capttofu


NOTE: one can overwrite these variables using -e EXTRA_VARS or long form --extra-vars=EXTRA_VARS`.

The location of the Docker image source files is also available in a repo, . As is shown, https://github.com:CaptTofu/docker-image-source. The image source repo is checked out one directory up relative to where the playbook repository is located.

The playbook that is run that utilizes this role is very simple:

---
- hosts: localhost
  roles:
  - image_builder


And when run:

$ ansible-playbook -i hosts images.yml

PLAY [localhost] **************************************************************

GATHERING FACTS ***************************************************************
ok: [localhost]

TASK: [image_builder | check or build ssh image] ******************************
changed: [localhost]

TASK: [image_builder | check or build apache image] ***************************
changed: [localhost]

TASK: [image_builder | check or build haproxy image] **************************
changed: [localhost]

TASK: [image_builder | check or build percona XtraDB Cluster image] ***********
changed: [localhost]

PLAY RECAP ********************************************************************
localhost                  : ok=5    changed=4    unreachable=0    failed=0


One still will need to manually push built images to a private or the public Docker image registry. The previous blog posts cover how to do this.

Summary

This blog post demonstrated to the reader how to use Ansible to automate the building of Docker images using the Ansible docker_image module. Starting with a simple example, and moving on to one more complex, the reader can gain a sense of how this can be used in an overall Ansible-based system to automate ensuring images that need to be run as containers will be available and if not, built for use.

Stay tuned for the next blog post on how to use the docker_facts for gathering information and (other tricks) from a running fleet of containers.

comments powered by Disqus