Skip to content

Install HA MSR#

  1. Get the Harbor values.yaml file:

    helm show values oci://registry.mirantis.com/harbor/helm/harbor > harbor-values.yaml
    
  2. Helm automatically creates certificates. To manually create your own, follow these steps:

    1. Create a directory for certificates named certs:

      mkdir certs
      
    2. Create a harbor.conf text file in the certs directory:

      [req]
      distinguished_name = req_distinguished_name
      x509_extensions = v3_req
      prompt = no
      
      [req_distinguished_name]
      C = US
      ST = State
      L = City
      O = Organization
      OU = Organizational Unit
      CN = msr
      
      [v3_req]
      keyUsage = digitalSignature, keyEncipherment, dataEncipherment
      extendedKeyUsage = serverAuth
      subjectAltName = @alt_names
      
      [alt_names]
      IP.1 = <IP-ADDRESS-OF-WORKERNODE>  # Replace with your actual IP address
      
    3. Generate the certificate and the key using the harbor.conf file you just created:

      openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -config harbor.conf
      
  3. If you are using the Helm certificates skip this step. If you manually created your own certificates, create the Kubernetes secret. Run the following command from outside of the certs folder:

    kubectl create secret tls <NAME-OF-YOUR-SECRET> \
    --cert=certs/tls.crt \
    --key=certs/tls.key
    
  4. Modify the harbor-values.yaml file to configure MSR:

    • Set the expose type:
    expose:
       # Set how to expose the service. Set the type as "ingress", "clusterIP", "nodePort" or "loadBalancer"
       # and fill the information in the corresponding section
       type: nodePort
    
    • Set the cert source to TLS and the secret name:
    certSource: secret
    secret:
       # The name of secret which contains keys named:
       # "tls.crt" - the certificate
       # "tls.key" - the private key
       secretName: "<NAME-OF-YOUR-SECRET>"
    
    • Set the nodePort ports to allow nodePort ingress. You can use any ephemeral port. Some Kubernetes distributions restrict the range. Generally accepted range is 32768-35535.
    nodePort:
       # The name of NodePort service
       name: harbor
       ports:
          http:
             # The service port Harbor listens on when serving HTTP
             port: 80
             # The node port Harbor listens on when serving HTTP
             nodePort: 32769
          https:
             # The service port Harbor listens on when serving HTTPS
             port: 443
             # The node port Harbor listens on when serving HTTPS
             nodePort: 32770
    
    • Set the external URL, if using nodePort use a worker node IP address (the same one that you used in generating the cert):
    externalURL: <A-WORKER-NODE-EXTERNAL-IP:httpsnodePort>
    
    • Enable data persistence:
    persistence:
     enabled: true
    

    If you are using a named StorageClass (as opposed to the default StorageClass) you need to specify it as shown in the following sample:

    persistence:
      enabled: true
      resourcePolicy: "keep"
      persistentVolumeClaim:
        registry:
          existingClaim: ""
          storageClass: "<nameofstorageclass>"
          subPath: ""
          accessMode: ReadWriteOnce
          size: 5Gi
          annotations: {}
    
    • Set the default admin password (reset after initial setup from UI, can also be set by secret):
    harborAdminPassword: "HarborPassword"
    
    • Set the replica number to at least 2 under portal, registry, core, trivy and jobservice:
    jobservice:
      image:
        repository: harbor-jobservice
      replicas: 2
    
    • Set PostgreSQL as an external database:
    database:
      # if external database is used, set "type" to "external"
      # and fill the connection information in "external" section
      type: external
    
    • Update external database section to reflect PostgreSQL configuration:
    external:
      host: "<POOLSERVICENAME>"
      port: "<PORT>"
      username: "postgres"
      password: "<PASSWORD>"
    
    • Set Redis as an external database:
    redis:
      # if external Redis is used, set "type" to "external"
      # and fill the connection information in "external" section
      type: external
    
    • Update the external Redis configuration:
    external:
      # support redis, redis+sentinel
      # addr for redis: <HOST_REDIS>:<PORT_REDIS>
      # addr for redis+sentinel: <HOST_SENTINEL_1>:<PORT_SENTINEL_1>,<HOST_SENTINEL_2>:<PORT_SENTINEL_2>,<HOST_SENTINEL_3>:<PORT_SENTINEL_3>
      addr: "<SERVICE_NAME:PORT>"
      sentinelMasterSet: ""
      coreDatabaseIndex: "0"
      jobserviceDatabaseIndex: "1"
      registryDatabaseIndex: "2"
      trivyAdapterIndex: "5"
      username: ""
      password: "<PASSWORD>"
    
    • Check your settings against a full example of MSR configuration:
    expose:
      type: loadBalancer
    persistence:
      enabled: true
      resourcePolicy: "keep"
      persistentVolumeClaim:
        registry:
          storageClass: "<nameofstorageclass>"
          accessMode: ReadWriteOnce
          size: 5Gi
        jobservice:
          jobLog:
            storageClass: "<nameofstorageclass>"
            accessMode: ReadWriteOnce
            size: 5Gi
        trivy:
          storageClass: "<nameofstorageclass>"
          accessMode: ReadWriteOnce
          size: 5Gi
    portal:
      replicas: 2
    core:
      replicas: 2
    jobservice:
      replicas: 2
    registry:
      replicas: 2
    trivy:
      replicas: 2
    database:
      type: external
      external:
        host: "postgresql-postgresql-ha-pgpool.<YOUR-NAMESPACE>.svc.cluster.local"
        port: "5432"
        coreDatabase: "harbor_core"
        username: "postgres"
        password: "${postgres password here}"
    redis:
      type: external
      external:
        addr: "redis-master.<YOUR-NAMESPACE>.svc.cluster.local:6379"
        sentinelMasterSet: ""
        coreDatabaseIndex: "0"
        jobserviceDatabaseIndex: "1"
        registryDatabaseIndex: "2"
        trivyAdapterIndex: "5"
        username: ""
        password: "${redis password here}"
    
  5. Install MSR using Helm:

helm install my-release oci://registry.mirantis.com/harbor/helm/harbor -f <PATH-TO/harbor-values.yaml>
  1. Configure Docker to trust the self-signed certificate. On the system logged into MSR:

    1. Create a directory:

      /etc/docker/certs.d/<IPADDRESS:NODEPORT>
      
    2. Move and rename the certificate:

      mv tls.crt /etc/docker/certs.d/<IPADDRESS:NODEPORT>/ca.crt
      
    3. Access the MSR UI at https://<WORKER-NODE-EXTERNAL-IP>:32767 provided the same NodePort numbers were used as specified in this guide. You can also log in using:

      docker login <WORKER-NODE-EXTERNAL-IP>:32767