There are containers… containers everywhere. So, it is crucial to keep an eye on deploying yours from a central store. This central store is called a container registry. This article will introduce you to a container registry and its characteristics. We will also discuss what considerations to examine when choosing the right registry type.
So let's get it on!
What is a Container Registry?
A container registry is a place with a catalog of storage locations for your developed container images, where you can push and pull the images. Each image in the container registry will represent its own image version, so there is never the same image version to avoid version mismatches when selecting them to deploy on the target system.
The version definition will be done by tags, so each image will contain a tag-name to get a unique number. For example, let's assume you generate an image called "myawesomeimage" with version 1.0.1. Then the result will be "myawesomeimage:1.0.1".
Types of Container Registries
There are different types of container registries. The popular one is a public registry called Docker Hub. It's free to use. Every person can publish their containers, and other users can pull them anonymously. So, when you work in an open-source world, and you deploy your container and make it public, you can use this public repo.
However, when you work in a company on software for internal use, you cannot publish your containers into a public registry. For this, you can use a private registry. This registry is accessible only for specific users and may be from a specific location (if configured). Several software solutions allow you to host your own registry with or without enterprise features. There are also some SaaS solutions offered by the big cloud service providers.
Now that we know the types of container registries let's see how you can choose the right one for your software.
Selecting the Right Registry Type
When you select a container registry, you must consider the type of use. For example, if you need it for personal use and have nothing to hide, you can use a public registry.
On the other hand, when you use it in a corporate environment, you will need a core solution that contains security information. If you must have complete control over the security or the registry itself, a private registry is your choice.
If you have decided to use a private registry, you should consider a private/self-hosting solution or a managed SaaS solution. If you must have full control and want to be able to check internal logs or other things, you should host your registry on your own. If you decide to self-host, you must keep the registry up to date and look at the used storage. If you choose to use a SaaS solution, you will only need to pay the bill and not worry about keeping it up and running (and performant).
Setting Up a Container Registry
To keep the article simple, we will use a SaaS solution. For this example, we will use the Azure container registry. For this, you must install the Azure CLI to execute the next two commands in your Azure subscription (for testing it out, you can try the free version of their subscription). After you have logged into your Azure CLI, execute these two commands.
The first one will create a resource group in your subscription. It's called "acr-group". In this resource group, you will then create a container registry called "demoacr". Once it is created, you will be ready to go ahead and use it for your needs. Now, log into the registry using the following command:
After logging in, you can push your first image to the container registry. But first, you must create a tag to define the version. For example, to upload a container called "myfirstapp" with the version "v1", we must use the following docker command.
Please note that you can use a different name. When you tag the image, you can then upload the image with:
That's all. Now your image is available through the container registry. Now, all users with access to the registry can pull the image and use it in their environment. Alternatively, your CI/CD Pipeline can install it into the target environment.
For a local working example, just run:
Using Container Registries in Kubernetes
In a realistic scenario, one container alone will not be enough. You will need one container to host the web frontend, another to host the API-Server, and another for the background process. This will be vital for any considerations regarding scaling them up and down. You can use docker-compose for this. However, in an enterprise environment, you will be faced with Kubernetes.
Kubernetes can use a public container registry out of the box. But, for using a private container registry, you must do some configuration. Let's assume you will run the container image above in Kubernetes. For this, you can use:
This is a standard YAML definition to generate a pod by adding our uploaded image to our container registry. But please look at the section "imagePullSecrets". This tells Kubernetes that it must pull the image with a credential. I assume you have already created a managed identity. You can add these into Kubernetes as secret with the following two commands:
Now, the Kubernetes Server can use the secret called "acr-secret" to pull the given image "myfirstapp" from the container registry. This is ensured by role-based access security (RBAC). Here, we define the "acrpull" access to the service principal.
What about Security?
Security may sound like a pain, but it is necessary because we tend to use several third-party tools for our applications. So how can we get an overview of the security of our containers, especially their vulnerabilities? Instead of reading all the changelogs and consuming the CVE database daily, let's use a tool.
For now, let's use Armo Platform, which is a free tool for Kubernetes cluster security and scanning. It will run in our Kubernetes cluster and scan the images periodically against vulnerability databases and show the results on its user-friendly dashboard.
After you sign up for Armo Platform, you will get the commands to install and execute a scan. You will also see other options like image scan and config scan. But I will keep a focus on scanning my local repo. So let's install it and run a small check on the pod definition above.
First, install it with the following command:
This will install Armo Platform onto your server and give the following prompt.
After the installation, I start the scan with the scan command from Armo Platform. It will then go through each config file and gather the "problems" in them. For the pod definition, the result looks like this:
You see? In such a small definition, you have four critical security problems that you absolutely need to avoid. Then you can go on to the medium ones and maybe the lower ones. For example, I reconfigured my definition to add a resource limitation and a security context. Now, my YAML definition looks like this:
I rerun the scan, and my results look way better:
So you see? With minor optimizations, you can reduce the risk of encountering a security breach. Cool, eh? You can then implement this into your DevOps pipeline if you want. Note that we are not limited only to scanning one single file. We can use this for a complete repository too. For this, a console output will not be very helpful because the output can be a mess. Instead, you can use the Armo Platform web portal to view the results. For example, for one of my repos, the results looked like this:
It will also help you modify YAML definitions to meet security requirements. Just click on "Fix", and you will get a prompt with hints about where to set the config to meet predefined security requirements.
You see, it's a nice handy toolkit and all for free. Give it a try!
In this article, we learned about why you should use a container registry for your project—to share your containers when needed, for automated deployment, and so on. Then we discussed the merits of private and public registries. Your choice will depend on your needs and the requirements for your project. Finally, we look into securing containers and how a tool like Armo Platform can help you find errors made when writing the code.