Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
The DevOps 2.1 Toolkit: Docker Swarm

You're reading from   The DevOps 2.1 Toolkit: Docker Swarm The next level of building reliable and scalable software unleashed

Arrow left icon
Product type Paperback
Published in May 2017
Publisher
ISBN-13 9781787289703
Length 436 pages
Edition 1st Edition
Tools
Concepts
Arrow right icon
Author (1):
Arrow left icon
Viktor Farcic Viktor Farcic
Author Profile Icon Viktor Farcic
Viktor Farcic
Arrow right icon
View More author details
Toc

Table of Contents (17) Chapters Close

Preface 1. Continuous Integration with Docker Containers FREE CHAPTER 2. Setting Up and Operating a Swarm Cluster 3. Docker Swarm Networking and Reverse Proxy 4. Service Discovery inside a Swarm Cluster 5. Continuous Delivery and Deployment with Docker Containers 6. Automating Continuous Deployment Flow with Jenkins 7. Exploring Docker Remote API 8. Using Docker Stack and Compose YAML Files to Deploy Swarm Services 9. Defining Logging Strategy 10. Collecting Metrics and Monitoring the Cluster 11. Embracing Destruction: Pets versus Cattle 12. Creating and Managing a Docker Swarm Cluster in Amazon Web Services 13. Creating and Managing a Docker Swarm Cluster in DigitalOcean 14. Creating and Managing Stateful Services in a Swarm Cluster 15. Managing Secrets in Docker Swarm Clusters 16. Monitor Your GitHub Repos with Docker and Prometheus

Building service images

Docker images are built through a definition stored in a Dockerfile. With few exceptions, it takes a similar approach as if we would define a simple script. We will not explore all the options we can use when defining a Dockerfile, but only those used for the go-demo service. Please consult the Dockerfile reference (https://docs.docker.com/engine/reference/builder/) page for more info.
The go-demo Dockerfile is as follows:

FROM alpine:3.4
MAINTAINER Viktor Farcic <viktor@farcic.com>

RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2

EXPOSE 8080
ENV DB db
CMD ["go-demo"]
HEALTHCHECK --interval=10s CMD wget -qO- localhost:8080/demo/hello

COPY go-demo /usr/local/bin/go-demo
RUN chmod +x /usr/local/bin/go-demo

Each of the statements will be built as a separate image. A container is a collection of images stacked one on top of the other.

Every Dockerfile starts with the FROM statement. It defines the base image that should be used. In most cases, my preference is to use alpine Linux. With its size being around 2MB it is probably the smallest distribution we can use. That is aligned with the idea that containers should have only things that are needed and avoid any extra overhead.

MAINTAINER is for informational purposes only.

The RUN statement executes any command set as its argument. I won't explain this one since it is very specific to the service we're building.

The EXPOSE statement defines the port the service will be listening to. It is followed by the definition of the environment variable DB that tells the service the address of the database. The default value is db and, as you'll see soon, it can be changed at runtime. The CMD statement represents the command that will be run when containers start.

The HEALTHCHECK instruction tells Docker how to test a container to check that it is still working. This can detect cases such as a web server that is stuck in an infinite loop and unable to handle new connections, even though the server process is still running. When a container has a healthcheck specified, it has a health status in addition to its normal status. This status is initially starting. Whenever a health check passes, it becomes healthy (from whatever state it was previously in). After a certain number of consecutive failures, it becomes unhealthy.
In our case, the healthcheck will be executed every ten seconds. The command sends a simple request to one of the API endpoints. If the service responds with status 200, the wget command will return 0 and Docker will consider the service healthy. Any other response will be considered as unhealthy and Docker Engine will perform certain actions to fix the situation.

Finally, we copy the go-demo binary from the host to the /usr/local/bin/ directory inside the image and give it executable permissions with the chmod command.

To some, the order of the statements might not look logical. However, there is a good reason behind such declarations and their order. Those that are less likely to change are defined before those that are prone to changes. Since go-demo will be a new binary every time we build the images, it is defined last.

The reasons behind such order lie in the way Docker Engine creates images. It starts from the top-most definition and checks whether it changed since the last time the build was run. If it didn't, it moves to the next statement. As soon as it finds a statement that would produce a new image, it, and all the statements following it are built into Docker images. By placing those that are less likely to change closer to the top, we can reduce the build time, disk usage, and bandwidth.

Now that we understand the Dockerfile behind the go-demo service, we can build the images.

The command is very straightforward and is as follows:

docker build -t go-demo .

As an alternative, we can define build arguments inside a Docker Compose file. The service defined in docker-compose-test-local.yml (https://github.com/vfarcic/go-demo/blob/master/docker-compose-test-local.yml) file is as follows:

  app:
build: .
image: go-demo

In both cases, we specified that the current directory should be used for the build process . and that the name of the image is go-demo.

We can run the build through Docker compose with the command that is as follows:

docker-compose \ 
-f docker-compose-test-local.yml \
build app

We'll use the latter method throughout the rest of the book.

We can confirm that the image was indeed built, by executing the docker images command as follows:

docker images

The output is as follows:

REPOSITORY TAG    IMAGE ID     CREATED        SIZE
go-demo latest 5e90126bebf1 49 seconds ago 23.61 MB
golang 1.6 08a89f0a4ee5 11 hours ago 744.2 MB
alpine latest 4e38e38c8ce0 9 weeks ago 4.799 MB

As you can see, go-demo is one of the images we have inside the server.

Now that the images are built, we can run staging tests that depend on the service and its dependencies to be deployed on a server.

You have been reading a chapter from
The DevOps 2.1 Toolkit: Docker Swarm
Published in: May 2017
Publisher:
ISBN-13: 9781787289703
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €18.99/month. Cancel anytime