Orchestrating Docker

Compose vs. Ansible

Agenda

  1. Docker
    • Compose
    • Docker command line
  2. Ansible
    • Docker module
    • Shell module

The Easy Way

version: '2'
services:
   db:
     image: "mysql:5.7"
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: wordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress
   wordpress:
     depends_on:
       - db
     image: "wordpress:latest"
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: "db:3306"
       WORDPRESS_DB_PASSWORD: wordpress
volumes:
    db_data:
docker-compose.yml

Compose Automation

  • Several Containers in one file
  • Automatic Network Creation
  • Automatic Network Aliases
  • Easy Volume Creation

The Hard Way

#!/bin/sh
docker network create "wordpress_net"
docker volume create -d local --name "db_data"

docker run -d \
  -v db_data:/var/lib/mysql:rw \
  --network="wordpress_net" \
  --network-alias "db" \
  --restart=always \
  -e MYSQL_ROOT_PASSWORD="wordpress" \
  -e MYSQL_PASSWORD="wordpress" \
  -e MYSQL_USER="wordpress" \
  -e MYSQL_DATABASE="wordpress" \
  --name db \
  mysql:5.7

docker run -d \
  --network="wordpress_net" \
  --network-alias "wordpress" \
  -p "8080:80" \
  --restart=always \
  -e WORDPRESS_DB_HOST="db:3306" \
  -e WORDPRESS_DB_PASSWORD="wordpress" \
  --name "wordpress" \
  wordpress:latest
docker_run.sh

Docker CLI Configuration

  • Manually Create Network
  • Manually Create Volumes
  • Manually Create Each Container

The Hard Way

Steps

  1. Create Network
  2. Create Volume
  3. Create DB Container
  4. Create Wordpress Container
---
- hosts: localhost
  gather_facts: no
  vars:
    docker_volume: "db_data"
    docker_network: "ansible_net"
    db_name: "db"
    wp_name: "wordpress"
    wp_host_port: 8000
    wp_container_port: 80
  tasks:
    - name: "Create a Volume"
      command: docker volume create -d local --name "{{ docker_volume }}"
    - name: "Create a network"
      docker_network:
        name: "{{ docker_network }}"
docker_play.yml
    - name: "Launch database container"
      docker_container:
        name: "{{ db_name }}"
        image: "mysql:5.7"
        volumes:
          - "{{ docker_volume }}:/var/lib/mysql:rw"
        restart: true
        networks:
          - name: "{{ docker_network }}"
            alias: ["{{ db_name }}"]
        env:
          MYSQL_ROOT_PASSWORD: "wordpress"
          MYSQL_DATABASE: "wordpress"
          MYSQL_USER: "wordpress"
          MYSQL_PASSWORD: "wordpress"
    - name: "Launch wordpress container"
      docker_container:
        name: "{{ wp_name }}"
        image: "wordpress:latest"
        ports:
          - "{{ wp_host_port }}:{{ wp_container_port }}"
        restart: true
        networks:
          - name: "{{ docker_network }}"
            alias: ["{{ wp_name }}"]
        env:
          WORDPRESS_DB_HOST: "{{ db_name }}:3306"
          WORDPRESS_DB_PASSWORD: "wordpress"
docker_play.yml

Notes on Docker Module

  • numerous bugs
  • requires docker-py (now docker)
    • docker-py version needs explicit docker-engine
    • violates no-agent principal?
  • far from feature complete
    • docker-network added in Ansible 2.2
    • docker-volumes not available yet
  • numerous bugs
  • no docker exec planned
    • use connection

Easy Way

---
- hosts: localhost
  gather_facts: no
  vars:
    docker_volume: "db_data"
    docker_network: "ansible_net"
    db_name: "db"
    wp_name: "wordpress"
    wp_host_port: 8000
    wp_container_port: 80
  tasks:
    - name: "Create a Volume"
      shell: docker volume create -d local --name "{{ docker_volume }}"
    - name: "Create a network"
      shell: docker network create "{{ docker_network }}"
shell_play.yml
    - name: "Launch database container"
      shell: >
        docker run -d
        -v "{{ docker_volume }}:/var/lib/mysql:rw"
        --network={{ docker_network }}
        --network-alias {{ db_name }}
        --restart=always
        -e MYSQL_ROOT_PASSWORD=wordpress
        -e MYSQL_PASSWORD=wordpress
        -e MYSQL_USER=wordpress
        -e MYSQL_DATABASE=wordpress
        --name {{ db_name }}
        "mysql:5.7"

    - name: "Launch wordpress container"
      shell: >
        docker run -d
        --network={{ docker_network }}
        --network-alias {{ wp_name }}
        -p "{{ wp_host_port }}:{{ wp_container_port }}"
        --restart=always
        -e WORDPRESS_DB_HOST="{{ db_name }}:3306"
        -e WORDPRESS_DB_PASSWORD=wordpress
        --name {{ wp_name }}
        "wordpress:latest"
shell_play.yml

Conclusion

  • Compose
    • local dev systems
    • continuous integration
  • Ansible
    • shared devtest
    • qa, uat, prod
  • Docker Module
    • potential (PoC, theorycrafting)
    • feature incomplete
    • not well supported (bugs)
    • finicky (python lib)
Made with Slides.com