Red Green Repeat Adventures of a Spec Driven Junkie

Docker Swarm Registry Service

Karl Friedrich Thiel - Design For The Magic Flute The Hall Of Stars In The Palace Of The Queen Of The Night Act1 Scene6

From my previous post, Docker Swarm Offline, working with Docker Swarm offline was a bit tricky because it meant manually pushing images around from node to node.

The solution: run a registry service within the swarm! All images available on the registry would be available to swarm nodes in this configuration. It’s like having a private docker hub!

  • Setting up the registry service
  • Push images to registry service
  • Deploy service to nodes
  • Verify service locations

Requirements

If you would like to follow along, please:

WORKER_COUNT = 0

to be:

WORKER_COUNT = 1
  • From the local folder where the Vagrantfile is, run: $ vagrant up to create virtual computers: manager and worker1.

Working on Multiple Nodes

Through this article, there will be connections between systems, manager and worker1 to verify. To connect to different systems using the Vagrantfile configuration, run: $ vagrant ssh <system>.

For example, to connect to the manager node, from the host, run: $ vagrant ssh manager. Similarly for worker1: $ vagrant ssh worker1.

Ensure Clean Slate

Let’s start with no images on any of the nodes connected to the swarm, run $ docker rmi <image name> to get rid of any images. You may need the -f option.

On manager node, use $ docker images and $ docker ps to check there are no images or containers running:

vagrant@manager:~$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
vagrant@manager:~$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

Similarly on worker1 node:

vagrant@worker1:~$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
vagrant@worker1:~$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

Just to double check, use $ docker service list to ensure no services running on the swarm:

vagrant@manager:~$ sudo docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS

Get Images

With a clean slate, get two images: nginx and registry. We use the nginx image as a simple application image and the registry as the registry service:

vagrant@manager:~$ sudo docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
...
Digest: sha256:5d32f60db294b5deb55d078cd4feb410ad88e6fe77500c87d3970eca97f54dba
Status: Image is up to date for registry:latest
vagrant@manager:~$ sudo docker pull repository
Using default tag: latest
latest: Pulling from library/registry
...
Status: Image is up to date for registry:latest
vagrant@manager:~$ sudo docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
nginx                      latest              62f816a209e6        2 weeks ago         109MB
registry                   latest              2e2f252f3c88        2 months ago        33.3MB

With these two images, you can disconnect your host computer from the network and the rest of the article will be more impressive.

Create Registry Service

On the manager node, use the: $ docker service create to start the registry service:

vagrant@manager:~$ sudo docker service create  --name registry --publish 5000:5000 registry:latest
image registry:latest could not be accessed on a registry to record
its digest. Each node will access registry:latest independently,
possibly leading to different nodes running different
versions of the image.

t11sfzhwg3if31dbpml8qmqhh
overall progress: 1 out of 1 tasks
1/1: running   [==================================================>]
verify: Service converged

Note the message:

image registry:latest could not be accessed on a registry to record its digest. Each node will access registry:latest independently, possibly leading to different nodes running different versions of the image.

Appears because the host system is offline. This does not appear if the host system is online.

With the registry service running in the Swarm, let’s test it out.

Check Registry Service

With the registry service running, let’s check it’s status using the $ docker service ls and $ curl command from the manager node and worker1 node:

vagrant@manager:~$ sudo docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
t11sfzhwg3if        registry            replicated          1/1                 registry:latest     *:5000->5000/tcp
vagrant@manager:~$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
f8ead854815d        registry:latest     "/entrypoint.sh /etc…"   44 seconds ago      Up 42 seconds       5000/tcp            registry.1.4efrmjz58hqjdtmhdqhpg4q0z
vagrant@manager:~$ curl localhost:5000/v2/_catalog
{"repositories":[]}

vagrant@worker1:~$ curl localhost:5000/v2/_catalog
{"repositories":[]}

Perfect, looks like the registry service is running and available to manager and worker1 nodes. Wasn’t that simple?

Populating Registry Service

An empty registry is not useful, so let’s take the nginx image on the manager node and push to the local registry so we can make a service using it.

Tag image

First step in pushing the image: re-tag the nginx image using the docker tag <image name> <host/new image name> command.

vagrant@manager:~$ sudo docker tag nginx localhost:5000/nginx-v1
vagrant@manager:~$ sudo docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
localhost:5000/nginx-v1    latest              62f816a209e6        2 weeks ago         109MB
nginx                      latest              62f816a209e6        2 weeks ago         109MB
registry                   latest              2e2f252f3c88        2 months ago        33.3MB

Push Image

With the image tagged: localhost:5000, let’s push it using the $ docker push command:

vagrant@manager:~$ sudo docker push localhost:5000/nginx-v1
The push refers to repository [localhost:5000/nginx-v1]
ad9ac0e6043b: Pushed
6ccbee34dd10: Pushed
237472299760: Pushed
latest: digest: sha256:427498d66ad8a3437939bb7ef613fe76458b550f6c43b915d8d4471c7d34a544 size: 948

Ok, with that setup complete, let’s create a service!

Create Service from Local Registry

Using the local registry and command: $ docker service create command, let’s get the nginx service on the Swarm:

vagrant@manager:~$ sudo docker service create localhost:5000/nginx-v1
woyokkpgfcitoznpj86mhgn1h
overall progress: 1 out of 1 tasks
1/1: running   [==================================================>]
verify: Service converged

Looks normal, where is it running? Let’s check using $ docker service ls and $ docker service ps:

vagrant@manager:~$ sudo docker service ls
ID                  NAME                  MODE                REPLICAS            IMAGE                            PORTS
t11sfzhwg3if        registry              replicated          1/1                 registry:latest                  *:5000->5000/tcp
woyokkpgfcit        youthful_heisenberg   replicated          1/1                 localhost:5000/nginx-v1:latest
vagrant@manager:~$ sudo docker service ps youthful_heisenberg
ID                  NAME                    IMAGE                            NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
1dcdrm8treda        youthful_heisenberg.1   localhost:5000/nginx-v1:latest   worker1             Running             Running 31 seconds ago

Oh wow, the worker1 node is already running the application? There was no need to copy the image over, Docker Swarm automagically copied the image over via the local registry, let’s check on worker1 using the $ docker images command:

vagrant@worker1:~$ sudo docker images
REPOSITORY                TAG                 IMAGE ID            CREATED                    SIZE
localhost:5000/nginx-v1   <none>              62f816a209e6        About a minute ago         109MB

Without any work on our part. The image showed up on there, like magic!

Conclusion

Running the Docker registry as a service in a Swarm enables a private registry, which allows services to be easily started on any node within the Swarm only requiring the image to be on the registry. Docker Swarm will copy over the image to the node auto-magically.