posted

2 Comments

By Patrick Daigle, Sr. Technical Marketing Architect, Cloud-Native Apps

Introduction

In version 1.2, vSphere Integrated Containers (VIC) introduced the concept of the native Docker Container Host (DCH). This is a built-in Docker image containing a full-fledged Docker engine that runs using VIC. DCH is packaged as a container and can be instantiated on VIC like any regular container.

The DCH image is distributed through Docker Hub and, as part of the VIC product distribution, in the registry. As of this writing, we offer three versions of the Docker engine: 1.12, 1.13 and 17.06. All of the official DCH images maintained by VMware are based on Photon OS. The source, Dockerfiles and documentation are available at github.com/vmware/vic-product.

DCH is well-suited for development use cases. Here are some examples:

  • As part of a CI/CD pipeline, VIC can be used to enhance end-to-end dev-build-push-deploy workflows. VIC with DCH can be used as a (self-service) private cloud for CI/CD by enabling the easy deployment and tear down of Docker hosts.
  • VIC and DCH allow you to treat Docker Hosts as ephemeral compute. This has the benefit of eliminating snowflakes (individually managed Docker Hosts), which reduces Operating System OpEx costs. For example, as part of a CI pipeline, you could instantiate ephemeral Docker Hosts that exist only for the purpose of building and pushing images, and only for the time it takes to complete that task.
  • An example of how VIC can be used to deploy Jenkins is given here.

In this article, I will demonstrate how flexible this DCH abstraction is. I will walk you through how a developer can leverage VIC and DCH to easily instantiate a Docker swarm using only well-known native Docker commands. I’ll also show how easy it is to create a complete cluster of ephemeral compute using DCH.

To illustrate this, we’ll look at the following script. This is a simple shell script that deploys a Docker swarm manager node and then creates and joins a user-defined number of worker nodes to the swarm.

#!/bin/bash

 

## USER-DEFINED VARIABLES

# Number of swarm workers desired

NUM_WORKERS=3

# name of routable (external) network

# this needs to be defined on your VCH using the ‘--container-network’ option

# use ‘docker network ls’ to list available external networks

CONTAINER_NET=routable

# Docker Container Host (DCH) image to use

# see https://hub.docker.com/r/vmware/dch-photon/tags/ for list of available Docker Engine versions

DCH_IMAGE=”vmware/dch-photon:17.06″

 

## NO NEED TO MODIFY BEYOND THIS POINT

# pull the image

docker pull $DCH_IMAGE

 

# create a docker volume for the master image cache

docker volume create --opt Capacity=10GB --name registrycache

# create and run the master instance

docker run -d -v registrycache:/var/lib/docker \

--net $CONTAINER_NET \

-name manager1 -hostname=manager1 \

$DCH_IMAGE

# get the master IP

SWARM_MASTER=$(docker inspect -f ‘{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}’ manager1)

# create the new swarm on the master

docker -H $SWARM_MASTER swarm init

 

# get the join token

SWARM_TOKEN=$(docker -H $SWARM_MASTER swarm join-token -q worker)

sleep 10

 

# run $NUM_WORKERS workers and use $SWARM_TOKEN to join the swarm

for i in $(seq “${NUM_WORKERS}”); do

 

# create docker volumes for each worker to be used as image cache

docker volume create  --opt Capacity=10GB --name worker-vol${i}

# run new worker container

docker run -d -v worker-vol${i}:/var/lib/docker \

--net $CONTAINER_NET \

--name worker${i} --hostname=worker${i}  \

$DCH_IMAGE

# wait for daemon to start

sleep 10

 

# join worker to the swarm

for w in $(docker inspect -f ‘{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}’ worker${i}); do

docker -H $w:2375 swarm join --token ${SWARM_TOKEN} ${SWARM_MASTER}:2377

done

 

done

 

# display swarm cluster information

printf “\nLocal Swarm Cluster\n=========================\n”

 

docker -H $SWARM_MASTER node ls

 

printf “=========================\nMaster available at DOCKER_HOST=$SWARM_MASTER:2375\n\n”

Let’s break this down to better understand what this script does.

 

User-defined variables

## USER-DEFINED VARIABLES

# Number of swarm workers desired

NUM_WORKERS=3

# name of routable (external) network

# this needs to be defined on your VCH using the ‘--container-network’ option

# use ‘docker network ls’ to list available external networks

CONTAINER_NET=routable

# Docker Container Host (DCH) image to use

# see https://hub.docker.com/r/vmware/dch-photon/tags/ for list of available Docker Engine versions

DCH_IMAGE=”vmware/dch-photon:17.06″

As a user of the script, this is the only section you need to modify.

  • NUM_WORKERS – this is the number of worker nodes that will be added to the swarm, in addition to the manager node.
  • CONTAINER_NET – this is the network to be used by our Docker Container Hosts. Here we leverage the ability of vSphere Integrated Containers to connect containers directly to vSphere Port Groups rather than through the Container Host. This will allow for easier interaction with our swarm.
  • DCH_IMAGE – here you can specify a different version of the Docker engine by modifying the tag (e.g. vmware/dch-photon:1.13′). You can see the list of available tags/versions here.

The script will use these parameters to pull the images, instantiate the swarm manager, initiate the swarm and instantiate and join the user-defined number of worker nodes.

 

Creating the master, initiating the swarm and getting the join token

# create a docker volume for the master image cache

docker volume create --opt Capacity=10GB --name registrycache

# create and run the master instance

docker run -d -v registrycache:/var/lib/docker \

--net $CONTAINER_NET \

--name manager1 --hostname=manager1 \

$DCH_IMAGE

# get the master IP

SWARM_MASTER=$(docker inspect -f ‘{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}’ manager1)

# create the new swarm on the master

docker -H $SWARM_MASTER swarm init

This is where we begin to see the DCH magic in action. Specifically, look at the following command:
> docker run -d -v registrycache:/var/lib/docker \

--net $CONTAINER_NET \

--name manager1 --hostname=manager1 \

$DCH_IMAGE

This starts up a full-fledged docker engine (running version 17.06) instantiated as a containerVM, using only a simple ‘docker run’ command. As you can see, DCH makes it very easy for developers to start up docker engines on-demand, thus creating new self-service possibilities.

Once the manager is created, we initialize the swarm (‘docker -H $SWARM_MASTER swarm init’), and then we grab the join token (‘docker -H $SWARM_MASTER swarm join-token -q worker’) that will allow us to join the worker nodes to the swarm in the next step.

 

Creating the workers and adding them to the swarm

# run $NUM_WORKERS workers and use $SWARM_TOKEN to join the swarm

for i in $(seq “${NUM_WORKERS}”); do

 

# create docker volumes for each worker to be used as image cache

docker volume create  --opt Capacity=10GB --name worker-vol${i}

# run new worker container

docker run -d -v worker-vol${i}:/var/lib/docker \

--net $CONTAINER_NET \

--name worker${i} --hostname=worker${i}  \

$DCH_IMAGE

# wait for daemon to start

sleep 10

 

# join worker to the swarm

for w in $(docker inspect -f ‘{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}’ worker${i}); do

docker -H $w:2375 swarm join &ndash&ndashtoken ${SWARM_TOKEN} ${SWARM_MASTER}:2377

done

 

done

This simple ‘for’ loop repeats NUM_WORKERS times. For each iteration, it:

  1. creates a volume to be used as the image cache for the worker
  2. instantiates a worker using the ‘vmware/dch-photon:17.06’ image
  3. joins the worker to the swarm using the join token (‘SWARM_TOKEN’) we fetched in the previous step

Once again, because we are using DCH with VIC, we see that it requires only a very simple ‘docker run’ command to create and run our Docker Hosts that will be used as the swarm worker nodes.

 

Running the script and result

Before running the script, you need to point your Docker client to a VIC Virtual Container Host endpoint. This is done by setting ‘DOCKER_HOST=<endpoint-ip>:<port>’. This script requires a Virtual Container Host endpoint — a requirement to run the DCH image, which enables all of the above automation. You can find this information in the vSphere Client portlet:

automating swarm creation

You can use the following commands (replace with your own endpoint IP address and make sure the script is in the current directory):

> export DOCKER_HOST=192.168.100.144:2375

      > ./dch-swarm.sh

Upon completion, the script prints information about the newly created swarm:

automating swarm creation

We can also see our newly created containerVMs hosting the swarm manager and the swarm workers in vSphere Client:

automating swarm creation

Finally, we can test the swarm by running the Docker Example Voting App. We deploy the app against our swarm by using the ‘docker stack deploy’ command:

automating swarm creation

We can see above that all of the required services were started. Testing the application in the browser, we can see it is indeed running and functional:

automating swarm creation

 

Conclusion

You should now have a better understanding of how the newly introduced VIC DCH feature helps address developer use cases. We have shown how easy it is to automate the deployment of Docker hosts using DCH. VIC provides end-users and developers with a Docker dial tone and a very flexible consumption model on top of vSphere, while DCH enables a new level of self-service.

If you’re interested in getting more hands-on knowledge around VIC, check out our tutorials on GitHub: https://github.com/vmware/vic-product/tree/master/tutorials

 

Acknowledgements

Thanks to Nathan Ness for contributing to the creation and testing of the script featured here (https://github.com/nvpnathan/vic). Special thanks to Ben Corrie for his review and sound advice.