Notes: The master branch is in heavy development, please use the other stable versions instead. A high available solution for Harbor based on chart can be find here. And refer to the guide to upgrade the existing deployment.
This repository, including the issues, focus on deploying Harbor chart via helm. So for the functionality issues or questions of Harbor, please open issues on goharbor/harbor
This Helm chart installs Harbor in a Kubernetes cluster. Welcome to contribute to Helm Chart for Harbor.
- Kubernetes cluster 1.10+
- Helm 2.8.0+
helm repo add harbor https://helm.goharbor.io
The following items can be set via --set
flag during installation or configured by editing the values.yaml
directly(need to download the chart first).
- Ingress: The ingress controller must be installed in the Kubernetes cluster. Notes: if the TLS is disabled, the port must be included in the command when pulling/pushing images. Refer to issue #5291 for the detail.
- ClusterIP: Exposes the service on a cluster-internal IP. Choosing this value makes the service only reachable from within the cluster.
- NodePort: Exposes the service on each Node’s IP at a static port (the NodePort). You’ll be able to contact the NodePort service, from outside the cluster, by requesting
NodeIP:NodePort
. - LoadBalancer: Exposes the service externally using a cloud provider’s load balancer.
The external URL for Harbor core service is used to:
- populate the docker/helm commands showed on portal
- populate the token service URL returned to docker/notary client
Format: protocol://domain[:port]
. Usually:
- if expose the service via
Ingress
, thedomain
should be the value ofexpose.ingress.hosts.core
- if expose the service via
ClusterIP
, thedomain
should be the value ofexpose.clusterIP.name
- if expose the service via
NodePort
, thedomain
should be the IP address of one Kubernetes node - if expose the service via
LoadBalancer
, set thedomain
as your own domain name and add a CNAME record to map the domain name to the one you got from the cloud provider
If Harbor is deployed behind the proxy, set it as the URL of proxy.
- Disable: The data does not survive the termination of a pod.
- Persistent Volume Claim(default): A default
StorageClass
is needed in the Kubernetes cluster to dynamic provision the volumes. Specify another StorageClass in thestorageClass
or setexistingClaim
if you have already existing persistent volumes to use. - External Storage(only for images and charts): For images and charts, the external storages are supported:
azure
,gcs
,s3
swift
andoss
.
- Secret keys: Secret keys are used for secure communication between components. Fill
core.secret
,jobservice.secret
andregistry.secret
to configure. - Certificates:
- notary: Used for authentication during communications. Fill
notary.secretName
to configure. Notary server certificate must be issued with notary service name as subject alternative name. - core: Used for token encryption/decryption. Fill
core.secretName
to configure.
- notary: Used for authentication during communications. Fill
Secrets and certificates must be setup to avoid changes on every Helm upgrade (see: #107).
Configure the other items listed in configuration section
Install the Harbor helm chart with a release name my-release
:
helm 2:
helm install --name my-release harbor/harbor
helm 3:
helm install my-release harbor/harbor
To uninstall/delete the my-release
deployment:
helm 2:
helm delete --purge my-release
helm 3:
helm uninstall my-release
The following table lists the configurable parameters of the Harbor chart and the default values.
Parameter | Description | Default |
---|---|---|
Expose | ||
expose.type |
The way how to expose the service: ingress , clusterIP , nodePort or loadBalancer , other values will be ignored and the creation of service will be skipped. |
ingress |
expose.tls.enabled |
Enable the tls or not | true |
expose.ingress.controller |
The ingress controller type. Currently supports default , gce and ncp |
default |
expose.tls.secretName |
Fill the name of secret if you want to use your own TLS certificate. The secret contains keys named: tls.crt - the certificate (required), tls.key - the private key (required), ca.crt - the certificate of CA (optional), this enables the download link on portal to download the certificate of CA. These files will be generated automatically if the secretName is not set |
|
expose.tls.notarySecretName |
By default, the Notary service will use the same cert and key as described above. Fill the name of secret if you want to use a separated one. Only needed when the expose.type is ingress . |
|
expose.tls.commonName |
The common name used to generate the certificate, it's necessary when the expose.type is clusterIP or nodePort and expose.tls.secretName is null |
|
expose.ingress.hosts.core |
The host of Harbor core service in ingress rule | core.harbor.domain |
expose.ingress.hosts.notary |
The host of Harbor Notary service in ingress rule | notary.harbor.domain |
expose.ingress.annotations |
The annotations used in ingress | |
expose.clusterIP.name |
The name of ClusterIP service | harbor |
expose.clusterIP.ports.httpPort |
The service port Harbor listens on when serving with HTTP | 80 |
expose.clusterIP.ports.httpsPort |
The service port Harbor listens on when serving with HTTPS | 443 |
expose.clusterIP.ports.notaryPort |
The service port Notary listens on. Only needed when notary.enabled is set to true |
4443 |
expose.nodePort.name |
The name of NodePort service | harbor |
expose.nodePort.ports.http.port |
The service port Harbor listens on when serving with HTTP | 80 |
expose.nodePort.ports.http.nodePort |
The node port Harbor listens on when serving with HTTP | 30002 |
expose.nodePort.ports.https.port |
The service port Harbor listens on when serving with HTTPS | 443 |
expose.nodePort.ports.https.nodePort |
The node port Harbor listens on when serving with HTTPS | 30003 |
expose.nodePort.ports.notary.port |
The service port Notary listens on. Only needed when notary.enabled is set to true |
4443 |
expose.nodePort.ports.notary.nodePort |
The node port Notary listens on. Only needed when notary.enabled is set to true |
30004 |
expose.loadBalancer.name |
The name of service | harbor |
expose.loadBalancer.IP |
The IP of the loadBalancer. It works only when loadBalancer support assigning IP | "" |
expose.loadBalancer.ports.httpPort |
The service port Harbor listens on when serving with HTTP | 80 |
expose.loadBalancer.ports.httpsPort |
The service port Harbor listens on when serving with HTTP | 30002 |
expose.loadBalancer.ports.notaryPort |
The service port Notary listens on. Only needed when notary.enabled is set to true |
|
expose.loadBalancer.annotations |
The annotations attached to the loadBalancer service | {} |
expose.loadBalancer.sourceRanges |
List of IP address ranges to assign to loadBalancerSourceRanges | [] |
Persistence | ||
persistence.enabled |
Enable the data persistence or not | true |
persistence.resourcePolicy |
Setting it to keep to avoid removing PVCs during a helm delete operation. Leaving it empty will delete PVCs after the chart deleted |
keep |
persistence.persistentVolumeClaim.registry.existingClaim |
Use the existing PVC which must be created manually before bound, and specify the subPath if the PVC is shared with other components |
|
persistence.persistentVolumeClaim.registry.storageClass |
Specify the storageClass used to provision the volume. Or the default StorageClass will be used(the default). Set it to - to disable dynamic provisioning |
|
persistence.persistentVolumeClaim.registry.subPath |
The sub path used in the volume | |
persistence.persistentVolumeClaim.registry.accessMode |
The access mode of the volume | ReadWriteOnce |
persistence.persistentVolumeClaim.registry.size |
The size of the volume | 5Gi |
persistence.persistentVolumeClaim.chartmuseum.existingClaim |
Use the existing PVC which must be created manually before bound, and specify the subPath if the PVC is shared with other components |
|
persistence.persistentVolumeClaim.chartmuseum.storageClass |
Specify the storageClass used to provision the volume. Or the default StorageClass will be used(the default). Set it to - to disable dynamic provisioning |
|
persistence.persistentVolumeClaim.chartmuseum.subPath |
The sub path used in the volume | |
persistence.persistentVolumeClaim.chartmuseum.accessMode |
The access mode of the volume | ReadWriteOnce |
persistence.persistentVolumeClaim.chartmuseum.size |
The size of the volume | 5Gi |
persistence.persistentVolumeClaim.jobservice.existingClaim |
Use the existing PVC which must be created manually before bound, and specify the subPath if the PVC is shared with other components |
|
persistence.persistentVolumeClaim.jobservice.storageClass |
Specify the storageClass used to provision the volume. Or the default StorageClass will be used(the default). Set it to - to disable dynamic provisioning |
|
persistence.persistentVolumeClaim.jobservice.subPath |
The sub path used in the volume | |
persistence.persistentVolumeClaim.jobservice.accessMode |
The access mode of the volume | ReadWriteOnce |
persistence.persistentVolumeClaim.jobservice.size |
The size of the volume | 1Gi |
persistence.persistentVolumeClaim.database.existingClaim |
Use the existing PVC which must be created manually before bound, and specify the subPath if the PVC is shared with other components. If external database is used, the setting will be ignored |
|
persistence.persistentVolumeClaim.database.storageClass |
Specify the storageClass used to provision the volume. Or the default StorageClass will be used(the default). Set it to - to disable dynamic provisioning. If external database is used, the setting will be ignored |
|
persistence.persistentVolumeClaim.database.subPath |
The sub path used in the volume. If external database is used, the setting will be ignored | |
persistence.persistentVolumeClaim.database.accessMode |
The access mode of the volume. If external database is used, the setting will be ignored | ReadWriteOnce |
persistence.persistentVolumeClaim.database.size |
The size of the volume. If external database is used, the setting will be ignored | 1Gi |
persistence.persistentVolumeClaim.redis.existingClaim |
Use the existing PVC which must be created manually before bound, and specify the subPath if the PVC is shared with other components. If external Redis is used, the setting will be ignored |
|
persistence.persistentVolumeClaim.redis.storageClass |
Specify the storageClass used to provision the volume. Or the default StorageClass will be used(the default). Set it to - to disable dynamic provisioning. If external Redis is used, the setting will be ignored |
|
persistence.persistentVolumeClaim.redis.subPath |
The sub path used in the volume. If external Redis is used, the setting will be ignored | |
persistence.persistentVolumeClaim.redis.accessMode |
The access mode of the volume. If external Redis is used, the setting will be ignored | ReadWriteOnce |
persistence.persistentVolumeClaim.redis.size |
The size of the volume. If external Redis is used, the setting will be ignored | 1Gi |
persistence.imageChartStorage.disableredirect |
The configuration for managing redirects from content backends. For backends which not supported it (such as using minio for s3 storage type), please set it to true to disable redirects. Refer to the guide for more information about the detail |
false |
persistence.imageChartStorage.caBundleSecretName |
Specify the caBundleSecretName if the storage service uses a self-signed certificate. The secret must contain keys named ca.crt which will be injected into the trust store of registry's and chartmuseum's containers. |
|
persistence.imageChartStorage.type |
The type of storage for images and charts: filesystem , azure , gcs , s3 , swift or oss . The type must be filesystem if you want to use persistent volumes for registry and chartmuseum. Refer to the guide for more information about the detail |
filesystem |
General | ||
externalURL |
The external URL for Harbor core service | https://core.harbor.domain |
uaaSecretName |
If using external UAA auth which has a self signed cert, you can provide a pre-created secret containing it under the key ca.crt . |
`` |
imagePullPolicy |
The image pull policy | |
imagePullSecrets |
The imagePullSecrets names for all deployments | |
updateStrategy.type |
The update strategy for deployments with persistent volumes(jobservice, registry and chartmuseum): RollingUpdate or Recreate . Set it as Recreate when RWM for volumes isn't supported |
RollingUpdate |
logLevel |
The log level: debug , info , warning , error or fatal |
info |
harborAdminPassword |
The initial password of Harbor admin. Change it from portal after launching Harbor | Harbor12345 |
secretkey |
The key used for encryption. Must be a string of 16 chars | not-a-secure-key |
proxy.httpProxy |
The URL of the HTTP proxy server | |
proxy.httpsProxy |
The URL of the HTTPS proxy server | |
proxy.noProxy |
The URLs that the proxy settings not apply to | 127.0.0.1,localhost,.local,.internal |
proxy.components |
The component list that the proxy settings apply to | core, jobservice, clair |
Nginx (if expose the service via ingress , the Nginx will not be used) |
||
nginx.image.repository |
Image repository | goharbor/nginx-photon |
nginx.image.tag |
Image tag | dev |
nginx.replicas |
The replica count | 1 |
nginx.resources |
The resources to allocate for container | undefined |
nginx.nodeSelector |
Node labels for pod assignment | {} |
nginx.tolerations |
Tolerations for pod assignment | [] |
nginx.affinity |
Node/Pod affinities | {} |
nginx.podAnnotations |
Annotations to add to the nginx pod | {} |
Portal | ||
portal.image.repository |
Repository for portal image | goharbor/harbor-portal |
portal.image.tag |
Tag for portal image | dev |
portal.replicas |
The replica count | 1 |
portal.resources |
The resources to allocate for container | undefined |
portal.nodeSelector |
Node labels for pod assignment | {} |
portal.tolerations |
Tolerations for pod assignment | [] |
portal.affinity |
Node/Pod affinities | {} |
portal.podAnnotations |
Annotations to add to the portal pod | {} |
Core | ||
core.image.repository |
Repository for Harbor core image | goharbor/harbor-core |
core.image.tag |
Tag for Harbor core image | dev |
core.replicas |
The replica count | 1 |
core.livenessProbe.initialDelaySeconds |
The initial delay in seconds for the liveness probe | 300 |
core.resources |
The resources to allocate for container | undefined |
core.nodeSelector |
Node labels for pod assignment | {} |
core.tolerations |
Tolerations for pod assignment | [] |
core.affinity |
Node/Pod affinities | {} |
core.podAnnotations |
Annotations to add to the core pod | {} |
core.secret |
Secret is used when core server communicates with other components. If a secret key is not specified, Helm will generate one. Must be a string of 16 chars. | |
core.secretName |
Fill the name of a kubernetes secret if you want to use your own TLS certificate and private key for token encryption/decryption. The secret must contain keys named: tls.crt - the certificate and tls.key - the private key. The default key pair will be used if it isn't set |
|
core.xsrfKey |
The XSRF key. Will be generated automatically if it isn't specified | |
Jobservice | ||
jobservice.image.repository |
Repository for jobservice image | goharbor/harbor-jobservice |
jobservice.image.tag |
Tag for jobservice image | dev |
jobservice.replicas |
The replica count | 1 |
jobservice.maxJobWorkers |
The max job workers | 10 |
jobservice.jobLogger |
The logger for jobs: file , database or stdout |
file |
jobservice.resources |
The resources to allocate for container | undefined |
jobservice.nodeSelector |
Node labels for pod assignment | {} |
jobservice.tolerations |
Tolerations for pod assignment | [] |
jobservice.affinity |
Node/Pod affinities | {} |
jobservice.podAnnotations |
Annotations to add to the jobservice pod | {} |
jobservice.secret |
Secret is used when job service communicates with other components. If a secret key is not specified, Helm will generate one. Must be a string of 16 chars. | |
Registry | ||
registry.registry.image.repository |
Repository for registry image | goharbor/registry-photon |
registry.registry.image.tag |
Tag for registry image | |
registry.registry.resources |
The resources to allocate for container | undefined |
registry.controller.image.repository |
Repository for registry controller image | goharbor/harbor-registryctl |
registry.controller.image.tag |
Tag for registry controller image | |
registry.controller.resources |
The resources to allocate for container | undefined |
registry.replicas |
The replica count | 1 |
registry.nodeSelector |
Node labels for pod assignment | {} |
registry.tolerations |
Tolerations for pod assignment | [] |
registry.affinity |
Node/Pod affinities | {} |
registry.middleware |
Middleware is used to add support for a CDN between backend storage and docker pull recipient. See official docs. |
|
registry.podAnnotations |
Annotations to add to the registry pod | {} |
registry.secret |
Secret is used to secure the upload state from client and registry storage backend. See official docs. If a secret key is not specified, Helm will generate one. Must be a string of 16 chars. | |
registry.credentials.username |
The username for accessing the registry instance, which is hosted by htpasswd auth mode. More details see official docs. | harbor_registry_user |
registry.credentials.password |
The password for accessing the registry instance, which is hosted by htpasswd auth mode. More details see official docs. It is suggested you update this value before installation. | harbor_registry_password |
registry.credentials.htpasswd |
The content of htpasswd file based on the value of registry.credentials.username registry.credentials.password . Currently helm does not support bcrypt in the template script, if the credential is updated you need to manually generated by calling htpasswd: htpasswd -nbBC10 $username $password . More details see official_docs. |
harbor_registry_user:$2y$10$9L4Tc0DJbFFMB6RdSCunrOpTHdwhid4ktBJmLD00bYgqkkGOvll3m |
Chartmuseum | ||
chartmuseum.enabled |
Enable chartmusuem to store chart | true |
chartmuseum.absoluteUrl |
If true, ChartMuseum will return absolute URLs. The default behavior is to return relative URLs | false |
chartmuseum.image.repository |
Repository for chartmuseum image | goharbor/chartmuseum-photon |
chartmuseum.image.tag |
Tag for chartmuseum image | dev |
chartmuseum.replicas |
The replica count | 1 |
chartmuseum.resources |
The resources to allocate for container | undefined |
chartmuseum.nodeSelector |
Node labels for pod assignment | {} |
chartmuseum.tolerations |
Tolerations for pod assignment | [] |
chartmuseum.affinity |
Node/Pod affinities | {} |
chartmuseum.podAnnotations |
Annotations to add to the chart museum pod | {} |
Clair | ||
clair.enabled |
Enable Clair | true |
clair.clair.image.repository |
Repository for clair image | goharbor/clair-photon |
clair.clair.image.tag |
Tag for clair image | dev |
clair.clair.resources |
The resources to allocate for clair container | |
clair.adapter.image.repository |
Repository for clair adapter image | goharbor/clair-adapter-photon |
clair.adapter.image.tag |
Tag for clair adapter image | dev |
clair.adapter.resources |
The resources to allocate for clair adapter container | |
clair.replicas |
The replica count | 1 |
clair.updatersInterval |
The interval of clair updaters, the unit is hour, set to 0 to disable the updaters | 12 |
clair.nodeSelector |
Node labels for pod assignment | {} |
clair.tolerations |
Tolerations for pod assignment | [] |
clair.affinity |
Node/Pod affinities | {} |
clair.podAnnotations |
Annotations to add to the clair pod | {} |
Trivy | ||
trivy.enabled |
The flag to enable Trivy scanner | true |
trivy.image.repository |
Repository for Trivy adapter image | goharbor/trivy-adapter-photon |
trivy.image.tag |
Tag for Trivy adapter image | dev |
trivy.resources |
The resources to allocate for Trivy adapter container | |
trivy.replicas |
The number of Pod replicas | 1 |
trivy.debugMode |
The flag to enable Trivy debug mode | false |
trivy.vulnType |
Comma-separated list of vulnerability types. Possible values os and library . |
os,library |
trivy.severity |
Comma-separated list of severities to be checked | UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL |
trivy.ignoreUnfixed |
The flag to display only fixed vulnerabilities | false |
trivy.skipUpdate |
The flag to disable Trivy DB downloads from GitHub | false |
trivy.gitHubToken |
The GitHub access token to download Trivy DB (see GitHub rate limiting) | |
Notary | ||
notary.enabled |
Enable Notary? | true |
notary.server.image.repository |
Repository for notary server image | goharbor/notary-server-photon |
notary.server.image.tag |
Tag for notary server image | dev |
notary.server.replicas |
The replica count | |
notary.server.resources |
The resources to allocate for container | undefined |
notary.signer.image.repository |
Repository for notary signer image | goharbor/notary-signer-photon |
notary.signer.image.tag |
Tag for notary signer image | dev |
notary.signer.replicas |
The replica count | |
notary.signer.resources |
The resources to allocate for container | undefined |
notary.nodeSelector |
Node labels for pod assignment | {} |
notary.tolerations |
Tolerations for pod assignment | [] |
notary.affinity |
Node/Pod affinities | {} |
notary.podAnnotations |
Annotations to add to the notary pod | {} |
notary.secretName |
Fill the name of a kubernetes secret if you want to use your own TLS certificate authority, certificate and private key for notary communications. The secret must contain keys named tls.ca , tls.crt and tls.key that contain the CA, certificate and private key. They will be generated if not set. |
|
Database | ||
database.type |
If external database is used, set it to external |
internal |
database.internal.image.repository |
Repository for database image | goharbor/harbor-db |
database.internal.image.tag |
Tag for database image | dev |
database.internal.initContainerImage.repository |
Repository for the init container image | busybox |
database.internal.initContainerImage.tag |
Tag for the init container image | latest |
database.internal.password |
The password for database | changeit |
database.internal.resources |
The resources to allocate for container | undefined |
database.internal.nodeSelector |
Node labels for pod assignment | {} |
database.internal.tolerations |
Tolerations for pod assignment | [] |
database.internal.affinity |
Node/Pod affinities | {} |
database.external.host |
The hostname of external database | 192.168.0.1 |
database.external.port |
The port of external database | 5432 |
database.external.username |
The username of external database | user |
database.external.password |
The password of external database | password |
database.external.coreDatabase |
The database used by core service | registry |
database.external.clairDatabase |
The database used by clair | clair |
database.external.notaryServerDatabase |
The database used by Notary server | notary_server |
database.external.notarySignerDatabase |
The database used by Notary signer | notary_signer |
database.external.sslmode |
Connection method of external database (require, verify-full, verify-ca, disable) | disable |
database.maxIdleConns |
The maximum number of connections in the idle connection pool. If it <=0, no idle connections are retained. | 50 |
database.maxOpenConns |
The maximum number of open connections to the database. If it <= 0, then there is no limit on the number of open connections. | 100 |
database.podAnnotations |
Annotations to add to the database pod | {} |
Redis | ||
redis.type |
If external redis is used, set it to external |
internal |
redis.internal.image.repository |
Repository for redis image | goharbor/redis-photon |
redis.internal.image.tag |
Tag for redis image | dev |
redis.internal.resources |
The resources to allocate for container | undefined |
redis.internal.nodeSelector |
Node labels for pod assignment | {} |
redis.internal.tolerations |
Tolerations for pod assignment | [] |
redis.internal.affinity |
Node/Pod affinities | {} |
redis.external.host |
The hostname of external Redis | 192.168.0.2 |
redis.external.port |
The port of external Redis | 6379 |
redis.external.coreDatabaseIndex |
The database index for core | 0 |
redis.external.jobserviceDatabaseIndex |
The database index for jobservice | 1 |
redis.external.registryDatabaseIndex |
The database index for registry | 2 |
redis.external.chartmuseumDatabaseIndex |
The database index for chartmuseum | 3 |
redis.external.clairAdapterIndex |
The database index for clair adapter | 4 |
redis.external.password |
The password of external Redis | |
redis.podAnnotations |
Annotations to add to the redis pod | {} |