Reader small image

You're reading from  Modern DevOps Practices

Product typeBook
Published inSep 2021
PublisherPackt
ISBN-139781800562387
Edition1st Edition
Right arrow
Author (1)
Gaurav Agarwal
Gaurav Agarwal
author image
Gaurav Agarwal

Gaurav Agarwal is a Senior Cloud Engineer at ThoughtSpot with over a decade of experience as a seasoned Cloud and DevOps Engineer. Previously, Gaurav served as a Cloud Solutions Architect at Capgemini and Software Developer at TCS. With a distinguished list of certifications, including HashiCorp Certified Terraform Associate, Google Cloud Certified Professional Cloud Architect, Certified Kubernetes Administrator, and Security Specialist, he possesses an impressive technical profile. Gaurav's extensive background encompasses roles where he played pivotal roles in infrastructure setup, cloud management, and the implementation of CI/CD pipelines. His technical prowess extends to numerous technical blog posts and a published book, underscoring his commitment to advancing the field.
Read more about Gaurav Agarwal

Right arrow

Chapter 3: Creating and Managing Container Images

In the previous chapter, we covered containerization with Docker, where we installed Docker and ran our first container. We also covered some core fundamentals, including Docker volumes, mounts, storage drivers, and logging drivers. We also covered Docker Compose as a declarative method of managing containers.

Now, we will discuss the core building blocks of containers; that is, container images. Container images also fulfill a core principle of modern DevOps practices – Config as Code. Therefore, understanding container images, how they work, and how to build an image effectively is very important for a modern DevOps engineer.

In this chapter, we're going to cover the following main topics:

  • Docker architecture
  • Understanding Docker images
  • Understanding Dockerfiles, components, and directives
  • Building and managing Docker images
  • Flattening Docker images
  • Optimizing containers with distroless...

Technical requirements

For this chapter, we are assuming that you have Docker installed and running on a Linux machine running Ubuntu 16.04 Xenial LTS or later, with sudo access. You can follow Chapter 2, Containerization with Docker, for more details on how to do that.

You will also need to clone the following GitHub repository for some of the exercises in this chapter: https://github.com/PacktPublishing/Modern-DevOps-Practices. Also, you need a Docker Hub account for most of the exercises. To create one go to https://hub.docker.com/

Docker architecture

As we already know, Docker uses the build once, run anywhere concept. Docker packages applications into images. Docker images form the blueprint of containers, so a container is an instance of an image.

A container image packages applications and their dependencies, so they are a single mutable unit you can run in any machine that runs Docker. You can also visualize them as a snapshot of the container.

We can build and store Docker images in a Docker Registry such as Docker Hub, and then download and use those images in the system where we want to deploy them. Images comprise several layers, so it helps to break images into multiple parts. The layers tend to be reusable stages that other images can build upon. This also means that we don't have to transmit the entire image over a network when we change images and just transmit the delta, which saves a lot of network I/O. We will talk about the layered filesystem in detail later in this chapter.

The...

Understanding Docker images

Docker images form the blueprint of Docker containers. Just like you need a blueprint for a shipping container, such as its size and what goods it will contain, a Docker image specifies what packages, source code, dependencies, and libraries it needs to use. It also determines what it needs to do for the source code to run effectively.

Technically, it consists of a series of steps you would perform on a base OS image to get your application up and running. This may include installing packages and dependencies, copying the source code to the correct folder, building your code to generate a binary, and so on.

You can store Docker images in a container registry, a centralized location where your Docker machines can pull images from to create containers.

Docker images uses a layered filesystem. Instead of a huge monolithic block on the filesystem that comprises the template to run containers, we have many layers, one on top of the other. But what does...

Understanding Dockerfiles, components, and directives

A Dockerfile is a simple file that constitutes a series of steps needed to build a Docker image. Each step is known as a directive, and there are different kinds of directives. Let's look at a simple example to understand how it works.

We will create a simple NGINX container, but this time by building the image from scratch and not using the one available on Docker Hub.

So, start by creating a Dockerfile, as follows:

$ vim Dockerfile
FROM ubuntu:xenial
RUN apt update && apt install -y curl
RUN apt update && apt install -y nginx
CMD ["nginx", "-g", "daemon off;"]

Let's look at each line and directive one by one to understand how this Dockerfile works:

  • The FROM directive specifies what the base image for this container should be. This means we are using another image as the base and will be building layers on top of it. We start by using the ubuntu:xenial...

Building and managing Docker images

We built some Docker images in the previous section, so by now, you should have some idea about how to write Dockerfiles and create Docker images from them. We've also covered a few best practices regarding it, which, in summary, are as follows:

  • Always add the layers that do not change frequently first, followed by the layers that may change often. For example, install your packages and dependencies first and copy the source code later. Docker builds the Dockerfile from the part that you change until the end, so if you change a line that comes at a later stage, Docker takes all the existing layers from the cache. Adding more frequently changing parts later in the build helps reduce the build time and will result in a faster CI/CD experience.
  • Combine multiple commands to create as few layers as possible. Avoid multiple consecutive RUN directives. Instead, try to combine them into a single RUN directive by using the && clauses...

Optimizing containers with distroless images

Distroless containers are one of the latest trends in the container world. They are promising in that they consider all the aspects of optimizing containers for the Enterprise environment. There are three important things you should consider while optimizing containers – performance, security, and cost.

Performance

You don't spin containers out of thin air. You must download images from your container registry and then run the container out of the image. Each step uses network and disk I/O. The bigger the image, the more resources it consumes, and the less performance you get out of it. Therefore, a smaller Docker image naturally performs better.

Security

Security is one of the most important aspects of the current IT landscape. Companies usually focus a lot on this aspect and invest a lot of money and time in it. Since containers are a relatively new technology, they are generally prone to hacking, so appropriately...

Understanding Docker registries

A Docker Registry is a stateless, highly scalable server-side application that stores and lets you distribute Docker images. The registry is open source under the permissive Apache license. It is a storage and distribution system where all your Docker servers can connect and upload and download images as and when needed. It acts as a distribution site for your images.

A Docker Registry contains several Docker repositories. A Docker repository holds several versions of a specific image. For example, all the versions of the nginx image are stored within a single repository within Docker Hub called nginx.

By default, Docker interacts with its public Docker Registry instance, called Docker Hub, which helps you distribute your images to the broader open source community.

Not all images can be public and open source, and many proprietary activities are going on. Docker provides an option to use a private Docker Registry for such a scenario that you...

Summary

In this chapter, we have covered a lot of ground. At this point, you should understand Docker from a hands-on perspective. We started with Docker images, how to use a Dockerfile to build Docker images, the components and directives of the Dockerfile, and how to create efficient images by following some best practices. We also discussed flattening Docker images and how to improve container security by using distroless images. Finally, we discussed Docker registries, how to run a private Docker Registry on a Docker server, and how to use other turnkey solutions such as Sonatype Nexus and JFrog Artifactory.

In the next chapter, we will delve into container orchestration using Kubernetes.

Questions

  1. Docker images use a layered model – true or false?
  2. You can delete an image from a server if a container using that image is already running – true or false?
  3. How do you remove a running container from a server? (Multiple answers are possible)

    a. docker rm <container_id>

    b. docker rm -f <container_id>

    c. docker stop <container_id> && docker rm <container_id>

    d. docker stop -f <container_id>

  4. Which of the following options are container build best practices? (Multiple answers are possible)

    a. Always add layers that don't frequently change at the beginning of the Dockerfile

    b. Combine multiple steps into a single directive to reduce layers

    c. Only use the required files in the container to keep it lightweight and reduce the attack surface

    d. Use semantic versioning in your Docker tags and avoid the latest version

    e. It is a best practice to include package managers and a shell within the container as it helps...

Answers

  1. True
  2. False – You cannot delete an image that is being used by a running container
  3. a. False

    b. True

    c. True

    d. False

  4. a. True

    b. True

    c. True

    d. True

    e. False

    f. False

  5. False – Only flatten Docker images if you benefit from better performance
  6. False – Distroless containers do not contain a shell
  7. a. True

    b. True

    c. True

    d. True

    e. False

  8. a. True
  9. False – If you're using Kubernetes or Docker Compose, use the liveness probes or define health checks with a YAML file instead
lock icon
The rest of the chapter is locked
You have been reading a chapter from
Modern DevOps Practices
Published in: Sep 2021Publisher: PacktISBN-13: 9781800562387
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.
undefined
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 $15.99/month. Cancel anytime

Author (1)

author image
Gaurav Agarwal

Gaurav Agarwal is a Senior Cloud Engineer at ThoughtSpot with over a decade of experience as a seasoned Cloud and DevOps Engineer. Previously, Gaurav served as a Cloud Solutions Architect at Capgemini and Software Developer at TCS. With a distinguished list of certifications, including HashiCorp Certified Terraform Associate, Google Cloud Certified Professional Cloud Architect, Certified Kubernetes Administrator, and Security Specialist, he possesses an impressive technical profile. Gaurav's extensive background encompasses roles where he played pivotal roles in infrastructure setup, cloud management, and the implementation of CI/CD pipelines. His technical prowess extends to numerous technical blog posts and a published book, underscoring his commitment to advancing the field.
Read more about Gaurav Agarwal