Harbor with Portworx on Kubernetes
This reference architecture document shows how you can deploy Harbor, an open-source container image registry, and its dependencies with Portworx on Kubernetes. Under this architecture, Portworx provides reliable and persistent storage to ensure Harbor runs with HA.
Create a StorageClass
All of the components will use a StorageClass
with 3 replicas, so create and apply the following spec:
kubectl apply -f - <<EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: portworx-sc-repl3
provisioner: kubernetes.io/portworx-volume
parameters:
repl: "3"
priority_io: "high"
EOF
For details about the Portworx-specific parameters, refer to the Portworx Volume section.
provisioner
parameter to pxd.portworx.com
.
Setup Harbor
Prequisites
By default, the instructions in this document deploy everything in the
harbor
namespace, but you can change this by specifying your own namespace:kubectl apply -f - <<EOF apiVersion: v1 kind: Namespace metadata: name: harbor EOF
Harbor is deployed using Helm, so it will need to be installed and have permissions on the
harbor
namespace. You can find instructions here.
Deploy dependencies
Harbor requires a PostgreSQL and Redis database.
Apply the following spec to deploy PostgreSQL, making sure to change the password and username to your preferred values:
kubectl apply -f - <<EOF apiVersion: v1 kind: PersistentVolumeClaim metadata: name: postgres-pvc namespace: harbor annotations: volume.beta.kubernetes.io/storage-class: portworx-sc-repl3 spec: accessModes: - ReadWriteOnce resources: requests: storage: 2Gi --- apiVersion: v1 kind: Service metadata: name: postgres namespace: harbor labels: app: postgres spec: ports: - port: 5432 selector: app: postgres clusterIP: None --- apiVersion: apps/v1 kind: Deployment metadata: name: postgres namespace: harbor labels: app: postgres spec: strategy: type: Recreate replicas: 1 selector: matchLabels: app: postgres template: metadata: labels: app: postgres spec: schedulerName: stork containers: - name: postgres image: postgres:9.5 ports: - containerPort: 5432 name: postgres env: - name: POSTGRES_USER value: postgres - name: POSTGRES_PASSWORD value: password - name: PGDATA value: /var/lib/postgresql/data/pgdata volumeMounts: - name: postgres-persistent-storage mountPath: /var/lib/postgresql/data volumes: - name: postgres-persistent-storage persistentVolumeClaim: claimName: postgres-pvc EOF
Apply the following spec to deploy Redis:
kubectl apply -f - <<EOF apiVersion: v1 kind: PersistentVolumeClaim metadata: name: redis-pvc namespace: harbor annotations: volume.beta.kubernetes.io/storage-class: portworx-sc-repl3 spec: accessModes: - ReadWriteOnce resources: requests: storage: 2Gi --- apiVersion: v1 kind: Service metadata: name: redis namespace: harbor spec: ports: - port: 6379 name: redis clusterIP: None selector: app: redis --- apiVersion: apps/v1 kind: Deployment metadata: name: redis namespace: harbor labels: app: redis spec: selector: matchLabels: app: redis template: metadata: labels: app: redis spec: schedulerName: stork containers: - name: redis image: redis:3.2-alpine imagePullPolicy: Always args: ["--requirepass", "password"] ports: - containerPort: 6379 name: redis volumeMounts: - name: redis-vol mountPath: /data volumes: - name: redis-vol persistentVolumeClaim: claimName: redis-pvc EOF
Enter the following command to create the four PostgreSQL databases Harbor requires:
DB_POD=$(kubectl get pods -n harbor -l app=postgres | awk '/postgres/{print$1}') kubectl exec $DB_POD -n harbor -- createdb -Upostgres registry kubectl exec $DB_POD -n harbor -- createdb -Upostgres clair kubectl exec $DB_POD -n harbor -- createdb -Upostgres notary_server kubectl exec $DB_POD -n harbor -- createdb -Upostgres notary_signer
Deploy Harbor
Enter the following commands to add the Harbor repository and deploy Harbor. Replace myharbor
with a name of your choosing:
helm repo add harbor https://helm.goharbor.io
NAMESPACE=harbor
helm install harbor/harbor \
--set redis.type=external \
--set redis.external.host=redis.$NAMESPACE \
--set redis.external.password=password \
--set database.type=external \
--set database.external.host=postgres.$NAMESPACE \
--set database.external.username=postgres \
--set database.external.password=password \
--set persistence.persistentVolumeClaim.registry.storageClass=portworx-sc-repl3 \
--set persistence.persistentVolumeClaim.chartmuseum.storageClass=portworx-sc-repl3 \
--set persistence.persistentVolumeClaim.jobservice.storageClass=portworx-sc-repl3 \
--namespace $NAMESPACE --name myharbor
Clean up Harbor
To clean up the environment created above, run the following:
helm delete --purge myharbor
kubectl delete -n harbor \
deploy/redis \
svc/redis \
pvc/redis-pvc \
deploy/postgres \
svc/postgres \
pvc/postgres-pvc \
pvc/myharbor-harbor-chartmuseum \
pvc/myharbor-harbor-jobservice \
pvc/myharbor-harbor-registry
kubectl delete sc/portworx-sc-repl3
Configuring snapshots
Scheduled snapshots can be configured. PostgreSQL does not require any special Pre or Post rules to be added; Redis is only used for cache and temporary storage, so it does not need a Pre rule to ensure it is flushed to disk. See the Create and use snapshots page for more details about snapsots.