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.
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
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.
Linux Ops Smart Journey
The operations journey never stops—pursuing excellence endlessly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.