Harbor is an open-source cloud native registry that stores, signs, and scans container images for vulnerabilities. This guide will walk you through the installation of Harbor Image Registry on Kubernetes / OpenShift with Helm Chart. Some of the cool features of Harbor image registry are:

Features of Harbor Registry

  • Multi-tenant support
  • Security and vulnerability analysis support
  • Extensible API and web UI
  • Content signing and validation
  • ​Image replication across multiple Harbor instances
  • ​Identity integration and role-based access control

Helm is a command-line interface (CLI) tool that was created to simplify deployment of applications and services to Kubernetes / OpenShift Container Platform clusters. Helm uses a packaging format called charts. A Helm chart is a collection of files that describes Kubernetes resources.

Step 1: Install Helm 3 on Linux / macOS

Helm is distributed a binary application which means no dependency is required to install it on your Linux / macOS machine:

--- Linux ---
sudo curl -L https://mirror.openshift.com/pub/openshift-v4/clients/helm/latest/helm-linux-amd64 -o /usr/local/bin/helm
sudo chmod  x /usr/local/bin/helm

--- macOS ---
sudo curl -L https://mirror.openshift.com/pub/openshift-v4/clients/helm/latest/helm-darwin-amd64 -o /usr/local/bin/helm
sudo chmod  x /usr/local/bin/helm

Check the installed version:

$ helm version
version.BuildInfo{Version:"v3.1 unreleased", GitCommit:"7ebdbb86fca32c77f2fce166f7f9e58ebf7e9946", GitTreeState:"clean", GoVersion:"go1.13.4"}

Step 2: Install Harbor Helm Chart on Kubernetes / OpenShift Cluster

A Chart is a Helm package. It contains all of the resource definitions necessary to run an application, tool, or service inside of a Kubernetes cluster.

Add Harbor Helm repository:

$ helm repo add harbor https://helm.goharbor.io
"harbor" has been added to your repositories

Update the repository:

$ helm repo update

Configure the chart

The configuration items can be set via –set flag during installation or configured by editing the values.yaml directly.

See Harbor Helm configuration page

You can download default values.yaml file.

wget https://raw.githubusercontent.com/goharbor/harbor-helm/master/values.yaml
vim values.yaml

Install Harbor helm chart with custom configurations once done modifying.

$ helm install harbor harbor/harbor -f values.yaml -n harbor
NAME: harbor
LAST DEPLOYED: Wed Apr  1 19:20:07 2020
NAMESPACE: harbor
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Please wait for several minutes for Harbor deployment to complete.
Then you should be able to visit the Harbor portal at https://hbr.apps.hqocp.safaricom.net.
For more details, please visit https://github.com/goharbor/harbor.

Check status to confirm it is deployed:

$ helm status harbor

Fixing Init:CrashLoopBackOff on harbor-harbor-database-0 on OpenShift

Some container images such as postgres and redis require root access and have certain expectations about how volumes are owned. We need relax the security in the cluster so that images are not forced to run as a pre-allocated UID, without granting everyone access to the privileged SCC:

Grant all authenticated users access to the anyuid SCC:

$ oc adm policy add-scc-to-group anyuid system:authenticated

Check your deployments status:

$ kubectl get deployments
NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
harbor-harbor-chartmuseum     1/1     1            1           24m
harbor-harbor-clair           1/1     1            1           24m
harbor-harbor-core            1/1     1            1           24m
harbor-harbor-jobservice      1/1     1            1           24m
harbor-harbor-notary-server   1/1     1            1           24m
harbor-harbor-notary-signer   1/1     1            1           24m
harbor-harbor-portal          1/1     1            1           24m
harbor-harbor-registry        1/1     1            1           24m

Check pod status:

$ kubectl get pods
NAME                                           READY   STATUS    RESTARTS   AGE
harbor-harbor-chartmuseum-58f8647f95-mtmmf     1/1     Running   0          5m16s
harbor-harbor-clair-654dcfd8bf-77qs6           2/2     Running   0          5m16s
harbor-harbor-core-5cb85989d6-r7s84            1/1     Running   0          5m16s
harbor-harbor-database-0                       1/1     Running   0          5m33s
harbor-harbor-jobservice-fc54cf784-lv864       1/1     Running   0          5m16s
harbor-harbor-notary-server-65d8fb7c77-xgxvg   1/1     Running   0          5m16s
harbor-harbor-notary-signer-66c9db4cf4-5bwvh   1/1     Running   0          5m16s
harbor-harbor-portal-5cbc6d5897-r5wzh          1/1     Running   0          25m
harbor-harbor-redis-0                          1/1     Running   0          5m16s
harbor-harbor-registry-7ff65976f4-sgnnd        2/2     Running   0          5m16s

Lastly confirm Services and ingress are created.

$ kubectl get svc
NAME                          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
harbor-harbor-chartmuseum     ClusterIP   172.30.161.108           80/TCP              26m
harbor-harbor-clair           ClusterIP   172.30.133.154           8080/TCP            26m
harbor-harbor-core            ClusterIP   172.30.29.180            80/TCP              26m
harbor-harbor-database        ClusterIP   172.30.199.219           5432/TCP            26m
harbor-harbor-jobservice      ClusterIP   172.30.86.18             80/TCP              26m
harbor-harbor-notary-server   ClusterIP   172.30.188.135           4443/TCP            26m
harbor-harbor-notary-signer   ClusterIP   172.30.165.7             7899/TCP            26m
harbor-harbor-portal          ClusterIP   172.30.41.233            80/TCP              26m
harbor-harbor-redis           ClusterIP   172.30.101.107           6379/TCP            26m
harbor-harbor-registry        ClusterIP   172.30.112.213           5000/TCP,8080/TCP   26m

$ kubectl get ing
NAME                    HOSTS                                     ADDRESS   PORTS     AGE
harbor-harbor-ingress   core.harbor.domain,notary.harbor.domain             80, 443   26m

Since I’m actually doing this deployment on OpenShift, I’ll have routes created.

$ kubectl get route
NAME                          HOST/PORT              PATH          SERVICES                      PORT   TERMINATION     WILDCARD
harbor-harbor-ingress-7f9vg   notary.harbor.domain   /             harbor-harbor-notary-server   4443   edge/Redirect   None
harbor-harbor-ingress-9pvvz   core.harbor.domain     /             harbor-harbor-portal          8080   edge/Redirect   None
harbor-harbor-ingress-d7mcn   core.harbor.domain     /c/           harbor-harbor-core            8080   edge/Redirect   None
harbor-harbor-ingress-gn5w6   core.harbor.domain     /chartrepo/   harbor-harbor-core            8080   edge/Redirect   None
harbor-harbor-ingress-jf48l   core.harbor.domain     /service/     harbor-harbor-core            8080   edge/Redirect   None
harbor-harbor-ingress-lhbx4   core.harbor.domain     /api/         harbor-harbor-core            8080   edge/Redirect   None
harbor-harbor-ingress-vtt8v   core.harbor.domain     /v2/          harbor-harbor-core            8080   edge/Redirect   None

A number of persistent volume claims are created as well. Matching the values of size you specified.

$ kubectl  get pvc
NAME                                     STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS                AGE
data-harbor-harbor-redis-0               Bound    pvc-1de4a5b2-d55a-48cc-b8b6-1b258214260c   1Gi        RWO            ocs-storagecluster-cephfs   29m
database-data-harbor-harbor-database-0   Bound    pvc-9754adde-e2bd-40ee-b18b-d72eacfdfc12   1Gi        RWO            ocs-storagecluster-cephfs   29m
harbor-harbor-chartmuseum                Bound    pvc-3944fce8-ecee-4bec-b0f6-cc5da3b30572   5Gi        RWO            ocs-storagecluster-cephfs   29m
harbor-harbor-jobservice                 Bound    pvc-5ecf0be4-002c-4628-8dcc-283e996175bc   1Gi        RWO            ocs-storagecluster-cephfs   29m
harbor-harbor-registry                   Bound    pvc-072358e9-06f2-4384-b7d6-88e97eb29499   5Gi        RWO            ocs-storagecluster-cephfs   29m

Step 3: Access Harbor Administration dashboard

Use the external Domain configured during installation to access the Harbor container registry dashboard.

<img alt="" data-ezsrc="https://kirelos.com/wp-content/uploads/2020/04/echo/install-harbor-registry-02.png" data-ez ezimgfmt="rs rscb8 src ng ngcb8 srcset" src="data:image/svg xml,”>

Default logins if you didn’t change password are:

Username: admin
Password: Harbor12345

Don’t forget to change your password after first login.

Similar guides:

Install Project Quay Registry on OpenShift With Operator