Docker Swarm Registry Service
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:
- Install Virtualbox
- Install vagrant
- Download this Vagrantfile to your local folder and modify this line:
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.