How to setup private registry in Kubernetes cluster using cri-o as CRI


3 min read

How to setup  private registry in Kubernetes cluster using cri-o as CRI

Before we begin, there are a few conditions that must be met. We need to have the following in place.

  1. Private container registry setup.

  2. The images are pushed to the registry.

  3. Have a functioning Kubernetes environment up and running.

  4. Authentication credentials such as username, password, or tokens are needed to access the private registry.

  5. If the private registry uses HTTPS, you may need to manage SSL/TLS certificates. To create a secure connection, Kubernetes must trust the registry's certificate.

With the above in place, we are ready to proceed with this exercise. Let's walk through the process.

In this example, we use a self-hosted docker registry with the URL '' listening on port '5000'. Log in to the image registry via the command line. If you do not have the docker tool installed, check below for an optional method to create the secret.

docker login

Provide the credential you want to use to authenticate to the registry when prompted, this could be an access token or the password for the docker ID.

The login process creates or updates a config.json file that holds an authorization token usually in the home directory.

cat $HOME/.docker/config.json

To use the token within Kubernetes, we create a secret based on the credentials above. Kubernetes cluster authenticates with the registry to retrieve images using the secret of type.

kubectl create secret generic regcredname  --from-file=.dockerconfigjson=<path/to/.docker/config.json>

Optional method to create the secret

If you don't have docker installed, do this instead. Use kubectl to create the secret and store the registry login credentials providing them via the command line. But if you prefer the docker login method then skip this step.

kubectl create secret docker-registry regcredname --docker-server <your-registry-server> --docker-username=<your-docker-username> --docker-password=<your-docker-password> --docker-email=<your-email>

Note that secrets typed on the command line may be stored unprotected in your shell history, and those secrets may be available to other users on that host while Kubectl is running.

Use the secret in a Kubernetes manifest file

The following is a manifest for a pod that requires access to the credentials we created in regcredname, to pull the image specified from the private registry.

vi my-private-reg-pod.yaml

apiVersion: v1
kind: Pod
  name: my-app-priv-reg
  - name: my-private-reg-image
  - name: regcredname

Replace with the actual image.

Update the location of the registry to the Kubernetes registries config file

In the Kubernetes cluster, edit the container registry configuration file and specify the registry URL and SSL/TLS option.

The default location is /etc/containers/registries.conf, If you wish to modify it for a single user, you may create a new file at $HOME/.config/containers/registries.conf

Update the [[registry]] section with the URL or IP of the container registry. To skip TLS verification, that is, using HTTP rather than HTTPS to connect to the registry, add insecure=true.


If there are numerous registries, the [[registry]] double brackets indicate that we can specify a list or a table of [registry] objects. In this example, there is only one registry

After updating the file, restart the CRI-O service to apply the changes

systemctl restart crio.service

Finally, deploy the pod to the Kubernetes cluster using kubectl and verify it is running.

kubectl apply -f my-private-reg-pod.yaml
kubectl get pod my-app-priv-reg

Now, your Kubernetes pods should be able to pull images from your private container registry with the appropriate authentication credentials. Make sure to replace placeholders with your actual registry and credentials information.