Kubernetes doesn’t have an image registry out of the box. So, the option is either to use the docker hub or install your own private image registry. Harbor is one of the CNCF Graduated projects that can be used as your private image registry for the Kubernetes cluster.
Harbor can be installed on Kubernetes Cluster directly, but I recommend you to install it outside the Kubernetes cluster.
Let’s see more detail on how to install and use it.
- Ubuntu server with a minimum spec of 2 CPU, 4GB RAM, and 40GB Disk Storage.
- Root Privileges, we need this privilege to install and configure Harbor on the server. Before starting, make sure to execute
sudo suso we don’t have a permission issue.
- SSL certificate & Key.
Install Docker Engine
First, update our repository & Install docker dependencies
apt update && apt install ca-certificates curl gnupg lsb-release
Add Docker’s GPG Key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
Add Docker’s repository
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
Install Docker Engine using the package manager
apt update && apt install docker-ce docker-ce-cli containerd.io
Docker will be installed in a few seconds. After the installation is done, check the Docker status
service docker status
Test your Docker Engine Installation by running docker hello world
docker run hello-world
If the Docker is installed correctly, it should be returning this kind of text
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
For more examples and ideas, visit:
Install Docker Compose
Docker Compose is another package that is mandatory to run Harbor.
Download the current latest stable docker-compose binary
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
Give executable permission to the
chmod +x /usr/local/bin/docker-compose
Test the docker-compose installation
Install and Configure Harbor
Before installing the Harbor, go to the Harbor release page and find the version you want to download.
Right now, the latest release is
v2.4.2, so I will download it here in this tutorial
Extract the installer package
tar xzvf harbor-online-installer-v2.4.2.tgz
Go to the extracted folder
Create a configuration file by Copy the template
cp harbor.yml.tmpl harbor.yml
Open the configuration file
You need to edit some parameters inside the configuration file, find these parameters, and change them to suit your need.
hostname parameter. Change the hostname value to match your domain name, in my case i will use
Next, find the
https parameter. Upload your SSL certificate & Key, and then change the value of
private_key value to match your SSL certificate & Key exact location on the server. In my case, both is in the
https: # https port for harbor, default is 443 port: 443 # The path of cert and key files for nginx certificate: /etc/ssl/facsiaginsa.com.crt private_key: /etc/ssl/facsiaginsa.com.key
Next, find the
external_url parameter. Uncomment the parameter and change the url matching your domain name, in my case I will use
Lastly, check out the
harbor_admin_password parameter. You don’t have to change the value, but remember this value because later we will use it when doing a first-time login to the Harbor GUI dashboard.
Save and exit, and then install the Harbor
The command above will check the prerequisite and download all the required images to run Harbor. After a few seconds (depending on your network), you will get a success message like this
Creating harbor-log ... done Creating redis ... done Creating registry ... done Creating harbor-portal ... done Creating harbor-db ... done Creating registryctl ... done Creating harbor-core ... done Creating harbor-jobservice ... done Creating nginx ... done ✔ ----Harbor has been installed and started successfully.----
Now, you should be able to access the Harbor GUI dashboard on your defined
external_url, in my case it is
registry.facsiaginsa.com. Open your browser and go to the Harbor GUI dashboard.
Log in using the username
admin and the password matching the
harbor_admin_password value on the Harbor configuration.
Security first, let’s change the
admin password. Click the profile menu on the top right, and then click change password.
After that, change the password.
After changing the password, let’s make a project. A project is needed to store the image that will be pushed to the Harbor. Go to the
Projects menu, and then click the
+ NEW PROJECT button.
Give the project a name, in my case,
superweb project, and set the project storage quota that suits your project need.
After that, you will see the project is added to the dashboard
The Harbor Installation & Configuration is done! Now you should be able to use the Harbor as your private image registry. To demonstrate how it works, we will show you how to push and pull images from the Harbor.
Push Image to Harbor
To push an image to the registry, first, you must log in to your registry via docker command line
docker login registry.facsiaginsa.com
registry.facsiaginsa.com is my domain name, change it to your registry domain name. Type the username and password the same as we use on the Harbor GUI dashboard.
You will see the success message
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
After that, you must build an image with this format
In my case, I will create an image named
custom-nginx, here is how I build the image
docker build -t registry.facsiaginsa.com/superweb/custom-nginx .
registry.facsiaginsa.com is my registry domain name.
superweb is the project name we set earlier on the Harbor GUI dashboard.
custom-nginx is the image name
If the format is correct, you can push the image using this command.
Pull Image from Harbor
To Pull the image from the private registry, first, we need the create a secret containing the private registry credential.
Create a secret object with
kubectl create secret docker-registry myprivateregistry --docker-server=registry.facsiaginsa.com --docker-username=admin --docker-password=XXXXXXXXX
You can change the secret name by changing the
myprivateregistry value. Also, change the other marked parameter value to match your registry domain, username, and password.
This is a pod definition file example if you want to pull an image from the private registry.
apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: my-pod image: registry.facsiaginsa.com/superweb/custom-nginx imagePullSecrets: - name: myprivateregistry
Change the secret name, matching the secret you created earlier.
That’s it! Now you have your own private image registry for your Kubernetes Cluster.