Install Harbor with DevStream

1 Prerequisites

  • An existing Kubernetes cluster, version > 1.10
  • StorageClass

If you are sure you already have a StorageClass configured for your K8s cluster, you can skip this section and move on to the next.

If you are uncertain about StorageClass, here’s a bit more explanation:

Depending on the installation method, your Kubernetes cluster may be deployed with an existing StorageClass marked as default. This default StorageClass is then used to dynamically provision storage for PersistentVolumeClaims that do not require any specific storage class. See PersistentVolumeClaim documentation for details.

Examples:

  • For local clusters created by minikube, there is already a default standard StorageClass using hostpath.
  • For local clusters created by kind, there is a default standard StorageClass using rancher.io/local-path.
  • For K8s-as-a-Service in public cloud providers, it’s highly likely that a default StorageClass is created. For example, for AWS EKS, the default is gp2, using AWS EBS. Note that the pre-installed default StorageClass may not fit well with your expected workload; for example, it might provision storage that is too expensive. If this is the case, you can either change the default StorageClass or disable it thoroughly to avoid the dynamic provisioning of storage. For more information on this topic, see the official doc here.

2 Harbor Architecture

Harbor Architecture

3 Using the Harbor Plugin with DevStream

3.1 Quickstart

For a local testing and developing purpose, we can deploy Harbor quickly using the minimal config as follows:

YAML

  1. tools:
  2. - name: helm-installer
  3. instanceID: harbor-001
  4. dependsOn: [ ]
  5. options:
  6. valuesYaml: |
  7. externalURL: http://127.0.0.1
  8. expose:
  9. type: nodePort
  10. tls:
  11. enabled: false
  12. chartmuseum:
  13. enabled: false
  14. notary:
  15. enabled: false
  16. trivy:
  17. enabled: false

After running dtm apply, we can see the following resources in the “harbor” namespace:

  • Deployment (kubectl get deployment -n harbor)

Most Harbor-related services run as Deployments:

Bash

  1. NAME READY UP-TO-DATE AVAILABLE AGE
  2. harbor-core 1/1 1 1 2m56s
  3. harbor-jobservice 1/1 1 1 2m56s
  4. harbor-nginx 1/1 1 1 2m56s
  5. harbor-portal 1/1 1 1 2m56s
  6. harbor-registry 1/1 1 1 2m56s
  • StatefulSet (kubectl get statefulset -n harbor)

Harbor depends on Postgres and Redis, which are deployed as StatefulSets. Notice that these dependencies are not deployed to a production-ready level with highly-availability and redundancy.

Bash

  1. NAME READY AGE
  2. harbor-database 1/1 3m40s
  3. harbor-redis 1/1 3m40s
  • Service (kubectl get service -n harbor)

By default, Harbor is exposed on port 30002 as type NodePort:

Bash

  1. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  2. harbor NodePort 10.99.177.6 <none> 80:30002/TCP 4m17s
  3. harbor-core ClusterIP 10.106.220.239 <none> 80/TCP 4m17s
  4. harbor-database ClusterIP 10.102.102.95 <none> 5432/TCP 4m17s
  5. harbor-jobservice ClusterIP 10.98.5.49 <none> 80/TCP 4m17s
  6. harbor-portal ClusterIP 10.105.115.5 <none> 80/TCP 4m17s
  7. harbor-redis ClusterIP 10.104.100.167 <none> 6379/TCP 4m17s
  8. harbor-registry ClusterIP 10.106.124.148 <none> 5000/TCP,8080/TCP 4m17s
  • PersistentVolumeClaim (kubectl get pvc -n harbor)

Harbor requires a few volumes, including volumes for Postgres and Redis:

Bash

  1. NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
  2. data-harbor-redis-0 Bound pvc-5b6b5eb4-c40d-4f46-8f19-ff3a8869e56f 1Gi RWO standard 5m12s
  3. database-data-harbor-database-0 Bound pvc-d7ccaf1f-c450-4a16-937a-f55ad0c7c18d 1Gi RWO standard 5m12s
  4. harbor-jobservice Bound pvc-9407ef73-eb65-4a56-8720-a9ddbcb76fef 1Gi RWO standard 5m13s
  5. harbor-registry Bound pvc-34a2b88d-9ff2-4af4-9faf-2b33e97b971f 5Gi RWO standard 5m13s
  • PersistentVolume (kubectl get pv)

For a quick start (for example, with a local kind/minikube cluster,) we don’t have to configure the StorageClass; so the resources are created with the default StorageClass:

Bash

  1. pvc-34a2b88d-9ff2-4af4-9faf-2b33e97b971f 5Gi RWO Delete Bound harbor/harbor-registry standard 5m22s
  2. pvc-5b6b5eb4-c40d-4f46-8f19-ff3a8869e56f 1Gi RWO Delete Bound harbor/data-harbor-redis-0 standard 5m22s
  3. pvc-9407ef73-eb65-4a56-8720-a9ddbcb76fef 1Gi RWO Delete Bound harbor/harbor-jobservice standard 5m22s
  4. pvc-d7ccaf1f-c450-4a16-937a-f55ad0c7c18d 1Gi RWO Delete Bound harbor/database-data-harbor-database-0 standard 5m22s

In this example, our default StorageClass is(kubectl get storageclass):

Bash

  1. NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
  2. standard (default) k8s.io/minikube-hostpath Delete Immediate false 20h

3.2 Using Harbor

We can forward the port of the Harbor service and log in:

Bash

  1. kubectl port-forward -n harbor service/harbor 8080:80

Harbor Login

And the default login user/pwd is: admin/Harbor12345. You will see the dashboard after a successful login:

Harbor Dashboard

3.3 Default Config

The harbor plugin provides default values for many options:

keydefault valuedescription
chart.chartPath“”local chart path
chart.chartNameharbor/harborhelm chart name
chart.version“”chart version
chart.timeout10mtimeout for helm install
chart.upgradeCRDstrueupdate CRDs or not (if any)
chart.releaseNameharborhelm release name
chart.namespaceharbornamespace
chart.waittruewait till deployment finishes
repo.urlhttps://helm.goharbor.iohelm repo URL
repo.nameharborhelm repo name