Follow these instructions to install Harbor on a TKG cluster provisioned with a TKr for vSphere 7.x.

Prerequisites

See Workflow for Installing Standard Packages on TKr for vSphere 7.x.

Harbor requires HTTP/S ingress. Harbor services are exposed via an Envoy service in the Contour package. As a prerequisite, deploy the Contour package. See Install Contour on TKr for vSphere 7.x.
  • If you are using NSX networking for Supervisor, create an Envoy service of type LoadBalancer.
  • If you are using vSphere vDS networking for Supervisor, create an Envoy service of type LoadBalancer or NodePort, depending on your environment and requirements.
The Harbor extension requires DNS. For testing and verification purposes, add the Harbor and Notary FQDNs to your local /etc/hosts file. The instructions below describe how to do this.

In production Harbor requires a DNS Zone on either a local DNS Server, such as BIND, or on a public cloud, such as AWS Route53 or Azure DNS. Once you have set up DNS, to automatically register the Harbor FQDNs with a DNS Server, install the ExternalDNS extension. See Install ExternalDNS on TKr for vSphere 7.x.

Install Harbor

To install the Harbor Registry using the standard package, complete the following steps.

  1. List the available Harbor versions in the repository.
    kubectl get packages -n tkg-system | grep harbor
  2. Create the Harbor Registry namespace.

    kubectl create ns tanzu-system-registry
  3. Create the harbor.yaml specification.

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: harbor-sa
      namespace: tkg-system
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: habor-role-binding
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: cluster-admin
    subjects:
      - kind: ServiceAccount
        name: harbor-sa
        namespace: tkg-system
    ---
    apiVersion: packaging.carvel.dev/v1alpha1
    kind: PackageInstall
    metadata:
      name: harbor
      namespace: tkg-system
    spec:
      serviceAccountName: harbor-sa
      packageRef:
        refName: harbor.tanzu.vmware.com
        versionSelection:
          constraints: 2.7.1+vmware.1-tkg.1 #PKG-VERSION
      values:
      - secretRef:
          name: harbor-data-values
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: harbor-data-values
      namespace: harbor-registry
    stringData:
      values.yml: |
        namespace: tanzu-system-registry
        hostname: <ENTER-HARBOR-FQDN>
        port:
          https: 443
        logLevel: info
        tlsCertificate:
          tls.crt: ""
          tls.key: ""
          ca.crt:
        tlsCertificateSecretName:
        enableContourHttpProxy: true
        harborAdminPassword: <ENTER-STRONG-PASSWORD-HERE>
        secretKey: <ENTER-SECRET-KEY>
        database:
          password: <ENTER-STRONG-PASSWORD-HERE>
          shmSizeLimit:
          maxIdleConns:
          maxOpenConns:
        exporter:
          cacheDuration:
        core:
          replicas: 1
          secret: <ENTER-SECRET>
          xsrfKey: <ENTER-XSRF-KEY-WHICH-IS-AN-ALPHANUMERIC-STRING-WITH-32-CHARS>
        jobservice:
          replicas: 1
          secret: <ENTER-SECRET>
        registry:
          replicas: 1
          secret: <ENTER-SECRET>
        trivy:
          enabled: true
          replicas: 1
          gitHubToken: ""
          skipUpdate: false
        persistence:
          persistentVolumeClaim:
            registry:
              existingClaim: ""
              storageClass: "<ENTER-STORAGE-CLASS>"
              subPath: ""
              accessMode: ReadWriteOnce
              size: 50Gi
            jobservice:
              existingClaim: ""
              storageClass: "<ENTER-STORAGE-CLASS>"
              subPath: ""
              accessMode: ReadWriteOnce
              size: 10Gi
            database:
              existingClaim: ""
              storageClass: "<ENTER-STORAGE-CLASS>"
              subPath: ""
              accessMode: ReadWriteOnce
              size: 10Gi
            redis:
              existingClaim: ""
              storageClass: "<ENTER-STORAGE-CLASS>"
              subPath: ""
              accessMode: ReadWriteOnce
              size: 10Gi
            trivy:
              existingClaim: ""
              storageClass: "<ENTER-STORAGE-CLASS>"
              subPath: ""
              accessMode: ReadWriteOnce
              size: 10Gi
        proxy:
          httpProxy:
          httpsProxy:
          noProxy: 127.0.0.1,localhost,.local,.internal
        pspNames: vmware-system-restricted
        network:
          ipFamilies: ["IPv4", "IPv6"]
  4. Customize the harbor-data-values secret in the harbor.yaml specification with appropriate values for your environment, including hostname, passwords, secrets, and storage class.

    Refer to Harbor Package Reference for guidance.

  5. Install Harbor.
    kubectl apply -f harbor.yaml
  6. Verify Harbor installation.
    kubectl get all -n tanzu-system-registry

Configure DNS for Harbor Using an Envoy LoadBalancer (NSX Networking)

If the prerequisite Envoy service is exposed via a LoadBalancer, obtain the external IP address of the load balancer and create DNS records for the Harbor FQDNs.
  1. Get the External-IP address for the Envoy service of type LoadBalancer.
    kubectl get service envoy -n tanzu-system-ingress
    You should see the External-IP address returned, for example:
    NAME    TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                      AGE
    envoy   LoadBalancer   10.99.25.220   10.195.141.17   80:30437/TCP,443:30589/TCP   3h27m
    Alternatively you can get the External-IP address using the following command.
    kubectl get svc envoy -n tanzu-system-ingress -o jsonpath='{.status.loadBalancer.ingress[0]}'
  2. To verify the installation of the Harbor extension, update your local /etc/hosts file with the Harbor and Notary FQDNs mapped to the External-IP address of the load balancer, for example:
    127.0.0.1 localhost
    127.0.1.1 ubuntu
    #TKG Harbor with Envoy Load Balancer IP
    10.195.141.17 core.harbor.domain
    10.195.141.17 core.notary.harbor.domain
    
  3. To verify the installation of the Harbor extension, log in to Harbor.
  4. Create two CNAME records on a DNS server that map the Envoy service Load Balancer External-IP address to the Harbor FQDN and the Notary FQDN.
  5. Install the External DNS extension.

Configure DNS for Harbor Using an Envoy NodePort (vDS Networking)

If the prerequisite Envoy service is exposed via a NodePort, obtain the virtual machine IP address of a worker node and create DNS records for the Harbor FQDNs.
Note: To use NodePort, you must have specified the correct port.https value in the harbor-data-values.yaml file.
  1. Switch context to the vSphere Namespace where the cluster is provisioned.
    kubectl config use-context VSPHERE-NAMESPACE
  2. List the nodes in the cluster.
    kubectl get virtualmachines
  3. Pick one of the worker nodes and describe it using the following command.
    kubectl describe virtualmachines tkg2-cluster-X-workers-9twdr-59bc54dc97-kt4cm
  4. Locate the IP address of the virtual machine, for example Vm Ip: 10.115.22.43.
  5. To verify the installation of the Harbor extension, update your local /etc/hosts file with the Harbor and Notary FQDNs mapped to the worker node IP address, for example:
    127.0.0.1 localhost
    127.0.1.1 ubuntu
    #TKG Harbor with Envoy NodePort
    10.115.22.43 core.harbor.domain
    10.115.22.43 core.notary.harbor.domain
    
  6. To verify the installation of the Harbor extension, log in to Harbor.
  7. Create two CNAME records on a DNS server that map the worker node IP address to the Harbor FQDN and the Notary FQDN.
  8. Install the External DNS extension.

Log In to the Harbor Web Interface

Once Harbor is installed and configured, log in and start using it.
  1. Access the Harbor Registry web interface at https://core.harbor.domain, or the hostname you used.

    The Harbor Registry web interface.

  2. Log in to Harbor with the username admin and the generated password that you put in the harbor-data-values.yaml file.

    The Harbor login page with the username admin and generated password.

  3. Verify that you can access the Harbor user interface.

    The Projects tab of the Harbor user interface appears after you log in.

  4. Obtain the Harbor CA certificate.

    In the Harbor interface, select Projects > library, or create a New Project.

    Click Registry Certificate and download the Harbor CA certificate (ca.crt).

  5. Add the Harbor CA certificate into the trust store of Docker client so you can push and pull container images to and from the Harbor Registry. See Using Private Registries with TKG Service Clusters.
  6. Refer to the Harbor documentation for details on using Harbor.