How do Docker containers work?
Fabian Hinz
Team Lead Data & AI
Containers have been high on the agenda of digitalisation strategies with a focus on IT architectures for several years now. Containers have become increasingly popular and important, particularly since the release of the Docker Container Engine as open source in 2013. This has gone hand in hand with a development in programming away from monolithic applications towards so-called microservices.
Similar to VMs, containers are a kind of container for applications that allow them to run independently of the platform. However, while VMs represent an entire computer environment including the operating system, containers only contain the dependencies required to run the application. This enables a more lightweight form of virtualisation. The best-known container technology is probably Docker, which is why the term "Docker container" is on everyone's lips.
What are Docker containers?
Docker containers are encapsulated units that can be executed independently of each other, no matter where they are located. As the name suggests, docker containers have a lot in common with freight containers. Like these, Docker containers are also in a standardised format and very portable. Each container contains one or sometimes several applications, packaged together with all the necessary dependencies. Now the container always looks identical on the inside and the contained application works, regardless of the environment. Just like the freight container, which in its standardised form fits on every ship and in every port.
What is the difference between virtual machines and Docker containers?
Containers are often described as a more lightweight form of virtualisation compared to virtual machines. Unlike VMs, containers do not emulate the hardware, but rather the operating system. This means that a single container requires significantly fewer resources than a VM.
In detail, VMs run directly on a physical server, which is virtualised with the help of a so-called hypervisor such as VMware ESXi. A separate operating system with associated background processes must be started on the virtual hardware for each VM. Virtualisation with containers takes place at a higher level, without a hypervisor. Here, the installed operating system with the container engine takes care of virtualisation. This means that many containers can be operated on the same server without major resource overheads.
What are the advantages of Docker containers?
Containers are very popular both in the development and productive operation of applications and offer many advantages.
Firstly, Docker containers are significantly more efficient and resource-saving compared to VMs: they require less CPU and memory. This is an advantage for developers, who can quickly and easily run and test an application locally in the container. Productive operation also benefits from reduced resource utilisation and the company benefits from cost savings.
Another advantage is their portability. As closed application packages, they can be executed on a wide variety of systems. This means they can not only be used for offline development, but also work just as easily on productive servers, regardless of the infrastructure or cloud platform selected. This results in greater speed and consistency in development, debugging and testing, as well as in final productive operation. No more discussions between development and operations along the lines of "but it still worked for me locally".
Containers are highly scalable. If additional instances of an application are required, e.g. because the traffic on a website increases due to a good marketing campaign, additional instances can simply be started and stopped again. Hundreds of containers can be started up or shut down within a very short space of time. Of course, the application in the container must support this scalability. The management of this large number of containers can be facilitated by orchestration solutions.
What is container orchestration with Kubernetes?
A container orchestration solution is required to efficiently manage a large number of containers. Kubernetes is probably the best-known and most popular software.
With Kubernetes, hundreds of containers can be operated in a coordinated manner on several parallel servers. Kubernetes solutions provide network and storage functionality and coordinate the various containers. Among other things, they take care of starting and stopping, optimising placement on available servers (so-called worker nodes) and, if necessary, the automated scaling of both containers and worker nodes.
At Claranet, we also use Kubernetes for container management and support Kubernetes both in our own data centre and with the major cloud providers with GKE (Google Kubernetes Engine), AKS (Azure Kubernetes Service) and Amazon EKS (Elastic Kubernetes Service). If you would like to take a closer look at the topic, you can find information on opportunities and risks as well as example scenarios in our white paper "Kubernetes in the enterprise".
Whitepaper "Kubernetes in the enterprise"
What are container images?
Now that the advantages of container technology are clear, the question arises as to how containers are built and run. So-called images form the basis for the operation of containers. To a certain extent, these are templates for the containers, with all the dependencies required for operation. They are "immutable", which means that once an image has been created, it can no longer be changed. This guarantees that it is deployed consistently and in the same way in every environment. If a container image is executed by a container engine such as Docker, you have a running container.
Inside, an image is made up of layers that build on each other. The first layer is the "base image", e.g. a specific container-optimised image of the Ubuntu operating system. Building on this, further layers are then added with each change, for example by adding required dependencies and finally the binary, an application to be executed later in the container.
This architecture has the advantage that several images on a server can share one and the same layer in the memory as long as they are based on the same "base image". This saves storage space and speeds up the download of new images.
Images are made available via a registry that stores, manages and provides them. One of the first and best-known public registries is Docker Hub, but there are now many alternatives. If you want to use official images from a software provider, you should find out where their images are made available.
If your company works a lot with containers, it is a good idea to host your own registry or have one hosted. Well-known open source registries are Harbor or Gitlab, for example.
What is a Dockerfile?
As mentioned above, images are static. But how do you customise an image, create a new one and finally execute it?
The easiest way to create a new Docker image is by using a so-called "Dockerfile". This is a file that functions as a construction manual for an image. Instructions are given line by line, which then form a new layer in the future image.
The start of a Dockerfile is usually a reference to a base image as the basis for the new image to be built. Further instructions could then be used to add files, set up network functionality such as available ports and install applications and libraries. The last step in the Dockerfile is usually the definition of a command, the so-called entrypoint, which is to be executed by default when the image is started. The `docker build` command is then used to build a new image based on this Dockerfile, which is saved locally and can be used directly or uploaded to a registry.
A fictitious Dockerfile for a self-programmed microservice in NodeJS could, for example, initially define an Ubuntu variant as the base image. In the next step, the installation of NodeJS and other required dependencies would be defined. The Javascript files for the programme would then be added and the required port released. Finally, the start command for the microservice would be defined as the entry point of the image. With just a few lines, you have successfully containerised your own application.
What needs to be considered?
Last but not least, here are a few tips and tricks:
- Ideally, only one service or process should be implemented per container. Exceptions to this rule make sense if applications are closely interwoven or interdependent. For example, with PHP it can make sense to have nginx and php-fpm in the same container.
- No user data, i.e. data to be persisted, should be stored in the container or container image. Due to the aforementioned immutability of container images, all data that was generated during runtime also disappears when containers are terminated or redeployed. External volumes can be integrated for usage data, both to provide a container with the required data at startup and to obtain new data beyond the runtime of the container. The same volume can also be integrated again for new deployments of the container (e.g. with an updated image).
- You will benefit most from operating applications with Docker if you design them specifically for operation with containers and container orchestration. A microservice architecture is often recommended.
- The development and operation of applications with Docker works excellently in combination with the implementation of DevOps principles and the use of cloud-native tooling. The use of CI (Continuous Integration) and CD (Continuous Deployment) through Gitlab Pipelines and ArgoCD, for example, is a recommended approach. With the aforementioned tools in place and taking a few do's and don'ts into account, you get a very modern, dynamic and highly scalable environment.
Claranet's Managed Container Services offer customised solutions for the management and operation of containerised applications.
