Cloud Native 10 min read

How to Deploy a Highly Available Harbor Registry on Kubernetes with Helm

Learn step‑by‑step how to set up a production‑grade, highly available Harbor container registry on a Kubernetes cluster using Helm, covering prerequisites, architecture, chart installation, TLS certificate creation, secret management, PostgreSQL setup, and verification procedures.

Linux Ops Smart Journey
Linux Ops Smart Journey
Linux Ops Smart Journey
How to Deploy a Highly Available Harbor Registry on Kubernetes with Helm

In today’s fast‑evolving cloud computing and containerization landscape, securing and stabilizing container images is crucial. Harbor, a leading container image registry, requires a highly available deployment to ensure enterprise‑grade application safety. This guide walks through using Helm to deploy a production‑level HA Harbor environment.

Prerequisites and Architecture

Kubernetes cluster 1.10+

Helm 2.8.0+

Highly available ingress controller (Harbor does not manage external endpoints)

Highly available PostgreSQL (Harbor does not handle DB HA deployment)

Highly available Redis (Harbor does not handle Redis HA deployment)

PVC that can be shared across nodes or external object storage

Harbor diagram
Harbor diagram
Harbor architecture diagram
Harbor architecture diagram

Deploy Harbor

Download the Helm chart:

<code>$ helm repo add harbor https://helm.goharbor.io
$ helm fetch harbor/harbor --untar
$ sudo mv harbor /etc/kubernetes/addons/</code>

Create the Harbor configuration file (harbor-value.yml):

<code>cat <<EOF | sudo tee /etc/kubernetes/addons/harbor-value.yml > /dev/null
# Exposure method
expose:
  type: ingress
  tls:
    enabled: true
    secret:
      secretName: "harbor-tls"
  ingress:
    hosts:
      core: core.jiaxzeng.com

# Access URL
externalURL: https://core.jiaxzeng.com

# PVC settings
persistence:
  enabled: true
  persistentVolumeClaim:
    registry:
      storageClass: "nfs-storage"
      accessMode: ReadWriteMany
      size: 100Gi
    jobservice:
      jobLog:
        storageClass: "nfs-storage"
        accessMode: ReadWriteMany
        size: 5Gi
    redis:
      storageClass: "nfs-storage"
      accessMode: ReadWriteMany
      size: 2Gi
    trivy:
      storageClass: "nfs-storage"
      accessMode: ReadWriteMany
      size: 5Gi

harborAdminPassword: "Harbor12345"

metrics:
  enabled: true

nginx:
  replicas: 2
  image:
    repository: 172.139.20.170:5000/library/nginx-photon
    tag: v2.11.0
portal:
  replicas: 2
  image:
    repository: 172.139.20.170:5000/library/harbor-portal
    tag: v2.11.0
core:
  replicas: 2
  image:
    repository: 172.139.20.170:5000/library/harbor-core
    tag: v2.11.0
jobservice:
  replicas: 2
  image:
    repository: 172.139.20.170:5000/library/harbor-jobservice
    tag: v2.11.0
registry:
  replicas: 2
  image:
    repository: 172.139.20.170:5000/library/registry-photon
    tag: v2.11.0
  controller:
    image:
      repository: 172.139.20.170:5000/library/harbor-registryctl
      tag: v2.11.0
database:
  type: external
  external:
    host: "172.139.20.188"
    port: "9999"
    username: "postgres"
    password: "123456"
    coreDatabase: "registry"
redis:
  type: internal
  internal:
    image:
      repository: 172.139.20.170:5000/library/redis-photon
      tag: v2.11.0
exporter:
  replicas: 2
  image:
    repository: 172.139.20.170:5000/library/harbor-exporter
    tag: v2.11.0
EOF</code>

Generate TLS certificates:

<code># CA certificate
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -sha512 -days 3650 \
  -subj "/C=CN/ST=ShangDong/L=GuangZhou/O=Personal/OU=Personal/CN=jiaxzeng.com" \
  -key ca.key \
  -out ca.crt

# Service certificate
openssl genrsa -out jiaxzeng.com.key 4096
openssl req -sha512 -new \
  -subj "/C=CN/ST=ShangDong/L=GuangZhou/O=Personal/OU=Personal/CN=jiaxzeng.com" \
  -key jiaxzeng.com.key \
  -out jiaxzeng.com.csr

cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1=core.jiaxzeng.com
DNS.2=jiaxzeng.com
EOF

openssl x509 -req -sha512 -days 3650 \
  -extfile v3.ext \
  -CA ca.crt -CAkey ca.key -CAcreateserial \
  -in jiaxzeng.com.csr \
  -out jiaxzeng.com.crt</code>

Create a Kubernetes secret for the Harbor TLS certificates:

<code>$ kubectl create namespace harbor
namespace/harbor created

$ kubectl -n harbor create secret tls harbor-tls --cert jiaxzeng.com.crt --key jiaxzeng.com.key
secret/harbor-tls created</code>

Create the PostgreSQL database for Harbor:

<code>$ psql -h 172.139.20.188 -p 9999
postgres=# CREATE DATABASE registry;
CREATE DATABASE</code>

Install Harbor with Helm:

<code>$ helm install harbor -n harbor -f /etc/kubernetes/addons/harbor-value.yml /etc/kubernetes/addons/harbor
NAME: harbor
LAST DEPLOYED: Thu Aug 22 18:17:10 2024
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://core.jiaxzeng.com
For more details, please visit https://github.com/goharbor/harbor</code>

Verification

Check the status of Harbor pods:

<code>$ kubectl -n harbor get pod
NAME                                 READY   STATUS    RESTARTS   AGE
harbor-core-6c9c79469b-6khzb        1/1     Running   0          3m33s
harbor-core-6c9c79469b-hlvsg        1/1     Running   0          3m54s
harbor-exporter-5c599f54d4-sjdxt    1/1     Running   0          12m
harbor-exporter-5c599f54d4-t5vfc    1/1     Running   0          12m
harbor-jobservice-74cb96479-cv26t   1/1     Running   0          3m33s
harbor-jobservice-74cb96479-rgkgc   1/1     Running   0          3m54s
harbor-portal-f7f7956cd-h6f5f       1/1     Running   0          12m
harbor-portal-f7f7956cd-t6jcn       1/1     Running   0          12m
harbor-redis-0                      1/1     Running   0          12m
harbor-registry-7bdfd8f5c-g474c    2/2     Running   0          3m52s
harbor-registry-7bdfd8f5c-sll4z    2/2     Running   0          3m54s</code>

Open a browser and navigate to the Harbor URL to confirm access:

Reference Articles

https://goharbor.io/docs/2.11.0/install-config/configure-https/

https://goharbor.io/docs/2.11.0/install-config/harbor-ha-helm/

Conclusion

Amid the global wave of digital transformation, container technology has become the preferred choice for modern application deployment due to its lightweight, flexible, and portable nature. However, the security management of container images also becomes more prominent. This article explored how to leverage Helm to deploy a highly available Harbor environment, ensuring the safety and stability of container images.

cloud nativeHigh AvailabilityKubernetesHarborHelmContainer Registry
Linux Ops Smart Journey
Written by

Linux Ops Smart Journey

The operations journey never stops—pursuing excellence endlessly.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.