Installing and Managing Kubernetes Registries
Kubernetes does many things: It schedules applications on nodes, monitors node health, attempts to resolve application issues automatically and much more.
But one thing Kubernetes doesn’t do natively is provide a registry for hosting container images (which contain the applications you want to deploy on Kubernetes). Instead, Kubernetes expects you to use an external solution for storing and sharing container images.
There are a variety of Kubernetes registry options out there, each with different pros and cons. To help you decide which registry to use with Kubernetes, this article examines several of the most popular Kubernetes-compatible container registries and explains how to integrate each one with Kubernetes.
What is a Kubernetes registry?
Before diving into examples of registries you can use with Kubernetes, let’s make clear what the term “Kubernetes registry” means, and that is a container registry that can be used with Kubernetes.
A container registry is an application or service that stores container images and makes them available upon request. Most container registries are not designed for use with Kubernetes specifically; they simply store container images for any system that wants them.
Again, Kubernetes itself has no built-in registry functionality (although some Kubernetes distributions, like Red Hat OpenShift, ship with integrated registries that are hosted inside Kubernetes clusters). In most cases, it’s up to users to decide which registry (or registries) to use to host container images for the applications they want to deploy using Kubernetes, then connect those registries to Kubernetes.
Pulling images with Kubernetes
When you set up a registry for Kubernetes, Kubernetes will download container images from it when you want to run an application. If you are a developer, you can also upload images to your registry, in order to make them available to Kubernetes, although you would not use Kubernetes to perform the uploads; you would use a separate tool, such as Docker.
Unlike some other container tools, Kubernetes doesn’t require users to “pull” container images to local systems before they can be used. In Kubernetes, you download images and run applications from them by creating a deployment, which is a YAML file that tells Kubernetes which container image or images to use. (The YAML file can also specify some additional configuration data, such as which network port to expose for the containers.)
For instance, if you wanted to run an application based on the Apache HTTPD Web Server container image, you’d first create a deployment file that looks like this:
apiVersion: apps/v1
kind: Deployment
metadata:
name: apache-deployment
labels:
role: webserver
spec:
replicas: 4
selector:
matchLabels:
role: webserver
template:
metadata:
labels:
role: webserver
spec:
containers:
- name: frontend
image: httpd
ports:
- containerPort: 80
You’d then deploy the file using a kubectl apply command, such as:
kubectl apply -f your_deployment_file.yml
Three types of Kubernetes registries
There are three main ways to use a container registry with Kubernetes:
- External public registries: An external public registry is a publicly available registry, such as Docker Hub, that is hosted outside your Kubernetes cluster.
- External private registry: An external private registry is not available to the public at large, and is not hosted inside your Kubernetes installation. You might choose to make it available only on your local network, or possibly set up a Docker Registry instance that you deploy in its own container, independent from your Kubernetes cluster, or you might set up a private repository as part of a public registry service, like Docker Hub.
- Private internal registry: A private internal registry is a registry that you set up and host inside your Kubernetes cluster. This means that the registry software runs alongside other applications that you deploy in Kubernetes.
External public registries are the simplest way to make a registry available to Kubernetes. You don’t need to worry about configuring secrets (which are the access information required to pull images from a private registry) or setting up the registry yourself.
On the other hand, private registries are necessary in situations where you don’t want your container images to be available to the public at large, but instead to select users, for deployment on their own Kubernetes clusters. As noted above, you can set up a private registry outside Kubernetes, which is advantageous because problems with the registry won’t impact your Kubernetes environment, but you can also host a registry inside Kubernetes itself.
The default Kubernetes registry
When people talk about the “default Kubernetes registry,” what they usually mean is Docker Hub. That is because, by default, Kubernetes assumes your images are hosted in Docker Hub, unless you specify otherwise when creating your deployment.
For example, consider this deployment file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
It tells Kubernetes to run NGINX using an image named nginx:1.14.2. Because there is no other information specified about the registry name or where to find the image, Kubernetes will assume this image is hosted publicly on Docker Hub.
So, although Docker Hub is not part of Kubernetes, the fact that Kubernetes can connect to it by default without any additional information makes it the “default” Kubernetes registry, so to speak.
4 popular Kubernetes registries
Now that we know how Kubernetes registries work, let’s take a look at a few popular container registries you can use with Kubernetes.
1. Docker Hub
Kubernetes is configured to use by default. That means you don’t have to do anything to use Docker Hub as a Kubernetes registry – provided the images you want to download and run are stored in public Docker Hub repositories, at least (meaning the repositories are available to the public at large and don’t require any logins).
To use private Docker Hub repositories with Kubernetes, you must configure a secret in your Kubernetes cluster. The secret contains your Docker Hub login data, which Kubernetes needs to connect to your private Docker Hub repository.
You can use kubectl to create the secret (be sure to specify your Docker Hub login credentials as required):
kubectl create secret docker-registry privatecred --docker-server=<your-registry-server> --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>
In this example, we named our secret privatecred.
Then, to deploy an application in Kubernetes using images from this private repository, create a deployment file that specifies the name of your credentials secret in the imagePullSecrets section:
apiVersion: v1
kind: Pod
metadata:
name: private-reg
spec:
containers:
- name: private-reg-container
image: <your-private-image>
imagePullSecrets:
- name: privatecred
Finally, deploy the file with kubectl apply.
2. Docker Registry
Docker Registry is an open-source container registry developed by Docker. It should not be confused with Docker Hub, which is a hosted registry; in contrast, Docker Registry is software that you can download and install on your own server.
The simplest way to run Docker Registry is simply to deploy it as a standalone container. You can do this with a single command:
docker run -d -p 5000:5000 --name registry registry:2
You can push and pull images to the registry using the docker CLI utility.
If you want to use images from this local registry to deploy applications inside your Kubernetes cluster, you’ll need to set up a secret for a private registry, similar to what we did in the Docker Hub example above.
First, create a secret in Kubernetes:
kubectl create secret docker-registry privatecred --docker-server=localhost:5000 --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>
Notice that we specified the registry server as localhost:5000, which matches the port that we used when we started the Docker Registry container.
After generating the secret, you can create a deployment file that points Kubernetes to it:
apiVersion: v1
kind: Pod
metadata:
name: private-reg
spec:
imagePullSecrets:
- name: privatecred
containers:
- name: private-reg-container
image: <your-private-image>
And then deploy the file with kubectl apply.
3. Quay
Quay is a registry that was originally created by CoreOS (which is now part of Red Hat) as an alternative to Docker Hub and Docker Registry. A hosted version of Quay is available, but you can also deploy Quay yourself as a private, self-hosted registry.
The easiest way to do this is to run Quay inside your Kubernetes cluster. You can automate the setup process using an operator .
To begin, create a CatalogSource in your cluster for Quay:
kubectl create -n openshift-marketplace -f ./bundle/quay-operator.catalogsource.yaml
Then, deploy Quay with:
kubectl create -n <your-namespace> -f ./config/samples/managed.quayregistry.yaml
Quay provides a Web-based dashboard, which you can use to manage access to your Quay repository. To pull images from Quay into Kubernetes, you’ll need to create a secret and download it as a YAML file through the UI:
Source: https://docs.projectquay.io/use_quay.html
4. JFrog Artifactory
JFrog Artifactory can function as a container registry, as well as an automated management tool for binaries and artifacts of all types. That means you can use Artifactory not just as a Kubernetes registry, but also to manage all objects and resources associated with application development and deployment.
Artifactory can be installed on Kubernetes with just a few commands using Helm charts:
helm repo add jfrog https://charts.jfrog.io
helm repo update
helm upgrade --install artifactory --namespace artifactory jfrog/artifactory
To create the secret that Kubernetes will need to connect to Artifactory, run a command such as:
kubectl create secret docker-registry privatecred \
--docker-server=my-artifactory.jfrog.io \
--docker-username=read-only \
--docker-password=my-super-secret-pass \
--docker-email=johndoe@example.com \
-n my-app-ns
Then, simply add the secret directive to your deployment file:
apiVersion: apps/v1
kind: Deployment
...
spec:
...
template:
spec:
containers:
- image: my-artifactory.jfrog.io/default-docker-virtual/my-app:1.0.1
imagePullSecrets:
- name: privatecred
Now, you can use your Artifactory instance hosted inside Kubernetes to manage images and any other data of your choosing.
In addition to the flexibility that Artifactory offers through its ability to manage artifacts of all types (a feature that other major Kubernetes registries lack), Artifactory provides a user-friendly interface for creating repositories and managing images in them:
Source: https://jfrog.com/help/r/jfrog-artifactory-documentation/docker-registry
Using Artifactory with AWS EKS
Many organizations choose to adopt Kubernetes via services offered by their cloud provider such as Amazon EKS. The JFrog Platform is available on AWS, making it super simple to deploy applications reliably and predictably with JFrog and EKS. Further, JFrog’s seamless integration with AWS AssumeRole allows JFrog Artifactory to serve container images and other files to EKS in the most secure manner by:
- bypassing the need to push user long term credentials into each EKS namespace
- automatically rotating the Artifactory token it is provisioning
- automatically provisioning the Artifactory token on each relevant namespace
Getting the most from your Kubernetes registry
Although Kubernetes is configured by default to use public Docker Hub repositories as its source for images, this is not always desirable. If you need some or all of your Kubernetes applications to be private, you’ll want to configure a private registry solution by either using a private Docker Hub repository, or running your own private registry with a platform like Artifactory.