2 thoughts on “Building a Docker Swarm on a Single Ubuntu VM

  1. whistl Post author

    Came up with a new version of the build_docker_swarm.sh script, that uses ubuntu-minimal images instead of the normal ubuntu server based images. Much lighter weight. Also, the script is a little smarter, as it no longer simply waits for 10 seconds after launching the containers, it actually verifies that each of the containers has an ipv4 address assigned before starting the software installation.


    #!/bin/bash
    # number of docker nodes to create, must be an odd number
    count=5
    # lxd image to use - we're using 16.04, aka xenial, because docker-ce hasn't been released for bionic yet
    release=xenial
    image=ubuntu-minimal:$release
    lxc remote list | grep ubuntu-minimal >/dev/null
    if [ $? -ne 0 ]; then
    echo "adding ubuntu-minimal image repository"
    lxc remote add --protocol simplestreams ubuntu-minimal https://cloud-images.ubuntu.com/minimal/releases/
    fi
    # get image fingerprint from repo
    fingerprint=$(lxc image list $image --format csv --columns f)
    # check if we already have that image locally
    lxc image list local:$fingerprint | grep ubuntu >/dev/null
    if [ $? -ne 0 ]
    then
    echo "downloading image $image"
    lxc image copy $image local:
    fi
    echo "create the $count containers"
    for i in $(seq 1 $count)
    do
    lxc launch $image docker$i -c security.nesting=true &
    sleep 0.5
    done
    wait
    echo "waiting until all $count containers are ready"
    sync
    ready=0
    while [ $ready -lt $count ]
    do
    sleep 2
    sync
    ready=0
    for i in $(seq 1 $count)
    do
    lxc list docker$i --format csv --columns 4 | grep -E '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*' >/dev/null
    if [ $? -eq 0 ]
    then
    ready=$(( $ready + 1 ))
    fi
    done
    done
    sleep 5
    echo "installing docker-ce from docker.com"
    for i in $(seq 1 $count)
    do
    (
    lxc exec docker$i -- apt-get update
    lxc exec docker$i -- apt-get install -y software-properties-common apt-transport-https
    lxc exec docker$i -- "curl -fsSL https://download.docker.com/linux/ubuntu/gpg || apt-key add -"
    lxc exec docker$i -- add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $release stable"
    lxc exec docker$i -- apt-get update
    lxc exec docker$i -- apt-get install -y docker-ce --allow-unauthenticated
    echo "$(date) docker$i ready"
    ) &
    done
    wait
    sync
    sync
    echo "waiting for docker-ce to initialize on all $count containers"
    ready=0
    while [ $ready -lt $count ]
    do
    sleep 10
    sync
    ready=0
    for i in $(seq 1 $count)
    do
    lxc list docker$i --format csv --columns 4 | grep '172.17.' >/dev/null
    if [ $? -eq 0 ]
    then
    ready=$(( $ready + 1 ))
    fi
    done
    done
    sleep 10
    echo "initializing the swarm, making docker1 the master node"
    lxc exec docker1 -- docker swarm init
    token=$(lxc exec docker1 -- docker swarm join-token --quiet worker)
    # get the ip of docker1, but the one on lxdbr0 the, not the one on it's internal docker0 bridge
    ipaddr=$(lxc list docker1 | grep "(eth0)" | egrep -o "[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*" | grep -v 172.17)
    echo "joining the remaining nodes to the swarm as slaves"
    for i in $(seq 2 $count)
    do
    lxc exec docker$i -- docker swarm join --token $token $ipaddr:2377
    done
    echo "$(date) done"
    echo "May I recommand: alias docker='lxc exec docker1 -- docker'"
    sync
    sync
    exit 0

    1. whistl Post author

      Here is a companion script – destroy_swarm.sh

      #!/bin/bash
      for i in $(seq 1 5)
      do
      lxc list | grep docker$i >/dev/null
      if [ $? -eq 0 ]; then
      echo "removing docker$i"
      lxc stop docker$i && lxc delete docker$i &
      fi
      done
      wait
      echo "done"
      exit 0

Comments are closed.