diff --git a/.github/workflows/integration.yaml b/.github/workflows/integration.yaml index 7a43e82b2..f37b2cd9c 100644 --- a/.github/workflows/integration.yaml +++ b/.github/workflows/integration.yaml @@ -43,7 +43,6 @@ jobs: - name: Set /etc/hosts run: | sudo -- sh -c "echo '127.0.0.1 harbor.local' >> /etc/hosts" - sudo -- sh -c "echo '127.0.0.1 notary.harbor.local' >> /etc/hosts" - name: Run integration tests working-directory: ./test @@ -56,7 +55,7 @@ jobs: df -h free -m mkdir -p /tmp/harbor - for name in core jobservice registry registryctl trivy notaryserver notarysigner portal redis database; do \ + for name in core jobservice registry registryctl trivy portal redis database; do \ kubectl -n default logs -l "component=$name" --all-containers > /tmp/harbor/$name.log ; \ done diff --git a/README.md b/README.md index ff353d564..00514900f 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ The following items can be set via `--set` flag during installation or configure The external URL for Harbor core service is used to: 1. populate the docker/helm commands showed on portal -2. populate the token service URL returned to docker/notary client +2. populate the token service URL returned to docker client Format: `protocol://domain[:port]`. Usually: @@ -83,33 +83,25 @@ The following table lists the configurable parameters of the Harbor chart and th | `expose.tls.certSource` | The source of the TLS certificate. Set as `auto`, `secret` or `none` and fill the information in the corresponding section: 1) auto: generate the TLS certificate automatically 2) secret: read the TLS certificate from the specified secret. The TLS certificate can be generated manually or by cert manager 3) none: configure no TLS certificate for the ingress. If the default TLS certificate is configured in the ingress controller, choose this option | `auto` | | `expose.tls.auto.commonName` | The common name used to generate the certificate, it's necessary when the type isn't `ingress` | | | `expose.tls.secret.secretName` | The name of secret which contains keys named: `tls.crt` - the certificate; `tls.key` - the private key | | -| `expose.tls.secret.notarySecretName` | The name of secret which contains keys named: `tls.crt` - the certificate; `tls.key` - the private key. Only needed when the `expose.type` is `ingress` | | | `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.controller` | The ingress controller type. Currently supports `default`, `gce`, `alb`, `f5-bigip` and `ncp` | `default` | | `expose.ingress.kubeVersionOverride` | Allows the ability to override the kubernetes version used while templating the ingress | | | `expose.ingress.annotations` | The annotations used commonly for ingresses | | | `expose.ingress.harbor.annotations` | The annotations specific to harbor ingress | {} | | `expose.ingress.harbor.labels` | The labels specific to harbor ingress | {} | -| `expose.ingress.notary.annotations` | The annotations specific to notary ingress | {} | -| `expose.ingress.notary.labels` | The labels specific to notary ingress | {} | | `expose.clusterIP.name` | The name of ClusterIP service | `harbor` | | `expose.clusterIP.annotations` | The annotations attached to the ClusterIP service | {} | | `expose.clusterIP.ports.httpPort` | The service port Harbor listens on when serving HTTP | `80` | | `expose.clusterIP.ports.httpsPort` | The service port Harbor listens on when serving 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 HTTP | `80` | | `expose.nodePort.ports.http.nodePort` | The node port Harbor listens on when serving HTTP | `30002` | | `expose.nodePort.ports.https.port` | The service port Harbor listens on when serving HTTPS | `443` | | `expose.nodePort.ports.https.nodePort` | The node port Harbor listens on when serving 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 only works when loadBalancer supports assigning IP | `""` | | `expose.loadBalancer.ports.httpPort` | The service port Harbor listens on when serving HTTP | `80` | | `expose.loadBalancer.ports.httpsPort` | The service port Harbor listens on when serving HTTPS | `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 | [] | | **Internal TLS** | | | @@ -201,6 +193,7 @@ The following table lists the configurable parameters of the Harbor chart and th | `nginx.nodeSelector` | Node labels for pod assignment | `{}` | | `nginx.tolerations` | Tolerations for pod assignment | `[]` | | `nginx.affinity` | Node/Pod affinities | `{}` | +| `nginx.topologySpreadConstraints` | Constraints that define how Pods are spread across failure-domains like regions or availability zones | `[]` | | `nginx.podAnnotations` | Annotations to add to the nginx pod | `{}` | | `nginx.priorityClassName` | The priority class to run the pod as | | | **Portal** | | | @@ -213,6 +206,7 @@ The following table lists the configurable parameters of the Harbor chart and th | `portal.nodeSelector` | Node labels for pod assignment | `{}` | | `portal.tolerations` | Tolerations for pod assignment | `[]` | | `portal.affinity` | Node/Pod affinities | `{}` | +| `portal.topologySpreadConstraints` | Constraints that define how Pods are spread across failure-domains like regions or availability zones | `[]` | | `portal.podAnnotations` | Annotations to add to the portal pod | `{}` | | `portal.priorityClassName` | The priority class to run the pod as | | | **Core** | | | @@ -226,8 +220,10 @@ The following table lists the configurable parameters of the Harbor chart and th | `core.nodeSelector` | Node labels for pod assignment | `{}` | | `core.tolerations` | Tolerations for pod assignment | `[]` | | `core.affinity` | Node/Pod affinities | `{}` | +| `core.topologySpreadConstraints` | Constraints that define how Pods are spread across failure-domains like regions or availability zones | `[]` | | `core.podAnnotations` | Annotations to add to the core pod | `{}` | | `core.serviceAnnotations` | Annotations to add to the core service | `{}` | +| `core.configureUserSettings` | A JSON string to set in the environment variable `CONFIG_OVERWRITE_JSON` to configure user settings. See the [official docs](https://goharbor.io/docs/latest/install-config/configure-user-settings-cli/#configure-users-settings-using-an-environment-variable). | | | `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.tokenKey` | PEM-formatted RSA private key used to sign service tokens. Only used if `core.secretName` is unset. If set, `core.tokenCert` MUST also be set. | | @@ -253,6 +249,7 @@ The following table lists the configurable parameters of the Harbor chart and th | `jobservice.nodeSelector` | Node labels for pod assignment | `{}` | | `jobservice.tolerations` | Tolerations for pod assignment | `[]` | | `jobservice.affinity` | Node/Pod affinities | `{}` | +| `jobservice.topologySpreadConstraints` | Constraints that define how Pods are spread across failure-domains like regions or availability zones | `[]` | | `jobservice.podAnnotations` | Annotations to add to the jobservice pod | `{}` | | `jobservice.priorityClassName` | The priority class to run the pod as | | | `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. | | @@ -269,12 +266,13 @@ The following table lists the configurable parameters of the Harbor chart and th | `registry.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | | `registry.tolerations` | Tolerations for pod assignment | `[]` | | `registry.affinity` | Node/Pod affinities | `{}` | +| `registry.topologySpreadConstraints` | Constraints that define how Pods are spread across failure-domains like regions or availability zones | `[]` | | `registry.middleware` | Middleware is used to add support for a CDN between backend storage and `docker pull` recipient. See [official docs](https://github.com/docker/distribution/blob/master/docs/configuration.md#middleware). | | | `registry.podAnnotations` | Annotations to add to the registry pod | `{}` | | `registry.priorityClassName` | The priority class to run the pod as | | | `registry.secret` | Secret is used to secure the upload state from client and registry storage backend. See [official docs](https://github.com/docker/distribution/blob/master/docs/configuration.md#http). 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](https://github.com/docker/distribution/blob/master/docs/configuration.md#htpasswd). | `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](https://github.com/docker/distribution/blob/master/docs/configuration.md#htpasswd). It is suggested you update this value before installation. | `harbor_registry_password` | +| `registry.credentials.username` | The username that harbor core uses internally to access the registry instance. Together with the `registry.credentials.password`, a htpasswd  is created. This is an alternative to providing `registry.credentials.htpasswdString`. For more details see [official docs](https://github.com/docker/distribution/blob/master/docs/configuration.md#htpasswd). | `harbor_registry_user` | +| `registry.credentials.password` | The password that harbor core uses internally to access the registry instance. Together with the `registry.credentials.username`, a htpasswd  is created. This is an alternative to providing `registry.credentials.htpasswdString`. For more details see [official docs](https://github.com/docker/distribution/blob/master/docs/configuration.md#htpasswd). It is suggested you update this value before installation. | `harbor_registry_password` | | `registry.credentials.existingSecret` | An existing secret containing the password for accessing the registry instance, which is hosted by htpasswd auth mode. More details see [official docs](https://github.com/docker/distribution/blob/master/docs/configuration.md#htpasswd). The key must be `REGISTRY_PASSWD` | `""` | | `registry.credentials.htpasswdString` | Login and password in htpasswd string format. Excludes `registry.credentials.username` and `registry.credentials.password`. May come in handy when integrating with tools like argocd or flux. This allows the same line to be generated each time the template is rendered, instead of the `htpasswd` function from helm, which generates different lines each time because of the salt. | undefined | | `registry.relativeurls` | If true, the registry returns relative URLs in Location headers. The client is responsible for resolving the correct URL. Needed if harbor is behind a reverse proxy | `false` | @@ -300,26 +298,7 @@ The following table lists the configurable parameters of the Harbor chart and th | `trivy.timeout` | The duration to wait for scan completion | `5m0s` | | `trivy.gitHubToken` | The GitHub access token to download [Trivy DB][trivy-db] (see [GitHub rate limiting][trivy-rate-limiting]) | | | `trivy.priorityClassName` | The priority class to run the pod as | | -| **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 | `1` | -| `notary.server.resources` | The [resources] to allocate for container | undefined | -| `notary.server.priorityClassName` | The priority class to run the pod as | | -| `notary.server.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | -| `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 | `1` | -| `notary.signer.resources` | The [resources] to allocate for container | undefined | -| `notary.signer.priorityClassName` | The priority class to run the pod as | | -| `notary.signer.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | -| `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.serviceAnnotations` | Annotations to add to the notary service | `{}` | -| `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 `ca.crt`, `tls.crt` and `tls.key` that contain the CA, certificate and private key. They will be generated if not set. | | +| `trivy.topologySpreadConstraints` | The priority class to run the pod as | | | **Database** | | | | `database.type` | If external database is used, set it to `external` | `internal` | | `database.internal.image.repository` | Repository for database image | `goharbor/harbor-db` | @@ -341,8 +320,6 @@ The following table lists the configurable parameters of the Harbor chart and th | `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.notaryServerDatabase` | The database used by Notary server | `notary_server` | -| `database.external.notarySignerDatabase` | The database used by Notary signer | `notary_signer` | | `database.external.existingSecret` | An existing password containing the database password. the key must be `password`. | `""` | | `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` | @@ -377,6 +354,7 @@ The following table lists the configurable parameters of the Harbor chart and th | `exporter.nodeSelector` | Node labels for pod assignment | `{}` | | `exporter.tolerations` | Tolerations for pod assignment | `[]` | | `exporter.affinity` | Node/Pod affinities | `{}` | +| `exporter.topologySpreadConstraints` | Constraints that define how Pods are spread across failure-domains like regions or availability zones | `[]` | | `exporter.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | | `exporter.cacheDuration` | the cache duration for information that exporter collected from Harbor | `30` | | `exporter.cacheCleanInterval` | cache clean interval for information that exporter collected from Harbor | `14400` | diff --git a/conf/notary-server.json b/conf/notary-server.json deleted file mode 100644 index b3c262413..000000000 --- a/conf/notary-server.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "server": { - "http_addr": ":4443" - }, - "trust_service": { - "type": "remote", - "hostname": "{{ template "harbor.notary-signer" . }}", - "port": "7899", - "tls_ca_file": "/etc/ssl/notary/ca.crt", - "key_algorithm": "ecdsa" - }, - "logging": { - "level": "{{ .Values.logLevel }}" - }, - "storage": { - "backend": "postgres", - "db_url": "{{ template "harbor.database.notaryServer" . }}" - }, - "auth": { - "type": "token", - "options": { - "realm": "{{ .Values.externalURL }}/service/token", - "service": "harbor-notary", - "issuer": "harbor-token-issuer", - "rootcertbundle": "/root.crt" - } - } -} \ No newline at end of file diff --git a/conf/notary-signer.json b/conf/notary-signer.json deleted file mode 100644 index 75a4d68bd..000000000 --- a/conf/notary-signer.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "server": { - "grpc_addr": ":7899", - "tls_cert_file": "/etc/ssl/notary/tls.crt", - "tls_key_file": "/etc/ssl/notary/tls.key" - }, - "logging": { - "level": "{{ .Values.logLevel }}" - }, - "storage": { - "backend": "postgres", - "db_url": "{{ template "harbor.database.notarySigner" . }}", - "default_alias": "defaultalias" - } -} \ No newline at end of file diff --git a/docs/High Availability.md b/docs/High Availability.md index e4a2c0217..17a190ae8 100644 --- a/docs/High Availability.md +++ b/docs/High Availability.md @@ -39,13 +39,13 @@ helm fetch harbor/harbor --untar Configure the following items in `values.yaml`, you can also set them as parameters via `--set` flag during running `helm install`: - **Ingress rule** - Configure the `expose.ingress.hosts.core` and `expose.ingress.hosts.notary`. + Configure the `expose.ingress.hosts.core`. - **External URL** Configure the `externalURL`. - **External PostgreSQL** Set the `database.type` to `external` and fill the information in `database.external` section. - Four empty databases should be created manually for `Harbor core`, `Notary server` and `Notary signer` and configure them in the section. Harbor will create tables automatically when starting up. + Four empty databases should be created manually for `Harbor core`, and configure them in the section. Harbor will create tables automatically when starting up. - **External Redis** Set the `redis.type` to `external` and fill the information in `redis.external` section. Redis sentinel is supported after v1.9.0, configure the `redis.external.sentinelMasterSet` and `redis.external.addr` to enable it. @@ -61,7 +61,7 @@ Configure the following items in `values.yaml`, you can also set them as paramet If you have no PVCs that can be shared across nodes, you can use external object storage to store images and charts and store the job logs in database. Set the `persistence.imageChartStorage.type` to the value you want to use and fill the corresponding section and set `jobservice.jobLoggers` to `database`. - **Replica** - Set `portal.replicas`, `core.replicas`, `jobservice.replicas`, `registry.replicas`, `notary.server.replicas` and `notary.signer.replicas` to `n`(`n`>=2). + Set `portal.replicas`, `core.replicas`, `jobservice.replicas`, `registry.replicas` to `n`(`n`>=2). ### Installation diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index eb467e773..7f6f3f72e 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -111,22 +111,6 @@ app: "{{ template "harbor.name" . }}" {{- end -}} {{- end -}} -{{- define "harbor.database.notaryServerDatabase" -}} - {{- if eq .Values.database.type "internal" -}} - {{- printf "%s" "notaryserver" -}} - {{- else -}} - {{- .Values.database.external.notaryServerDatabase -}} - {{- end -}} -{{- end -}} - -{{- define "harbor.database.notarySignerDatabase" -}} - {{- if eq .Values.database.type "internal" -}} - {{- printf "%s" "notarysigner" -}} - {{- else -}} - {{- .Values.database.external.notarySignerDatabase -}} - {{- end -}} -{{- end -}} - {{- define "harbor.database.sslmode" -}} {{- if eq .Values.database.type "internal" -}} {{- printf "%s" "disable" -}} @@ -135,14 +119,6 @@ app: "{{ template "harbor.name" . }}" {{- end -}} {{- end -}} -{{- define "harbor.database.notaryServer" -}} -postgres://{{ template "harbor.database.username" . }}:{{ template "harbor.database.escapedRawPassword" . }}@{{ template "harbor.database.host" . }}:{{ template "harbor.database.port" . }}/{{ template "harbor.database.notaryServerDatabase" . }}?sslmode={{ template "harbor.database.sslmode" . }} -{{- end -}} - -{{- define "harbor.database.notarySigner" -}} -postgres://{{ template "harbor.database.username" . }}:{{ template "harbor.database.escapedRawPassword" . }}@{{ template "harbor.database.host" . }}:{{ template "harbor.database.port" . }}/{{ template "harbor.database.notarySignerDatabase" . }}?sslmode={{ template "harbor.database.sslmode" . }} -{{- end -}} - {{- define "harbor.redis.scheme" -}} {{- with .Values.redis }} {{- ternary "redis+sentinel" "redis" (and (eq .type "external" ) (not (not .external.sentinelMasterSet))) }} @@ -247,14 +223,6 @@ postgres://{{ template "harbor.database.username" . }}:{{ template "harbor.datab {{- printf "%s-trivy" (include "harbor.fullname" .) -}} {{- end -}} -{{- define "harbor.notary-server" -}} - {{- printf "%s-notary-server" (include "harbor.fullname" .) -}} -{{- end -}} - -{{- define "harbor.notary-signer" -}} - {{- printf "%s-notary-signer" (include "harbor.fullname" .) -}} -{{- end -}} - {{- define "harbor.nginx" -}} {{- printf "%s-nginx" (include "harbor.fullname" .) -}} {{- end -}} @@ -267,12 +235,8 @@ postgres://{{ template "harbor.database.username" . }}:{{ template "harbor.datab {{- printf "%s-ingress" (include "harbor.fullname" .) -}} {{- end -}} -{{- define "harbor.ingress-notary" -}} - {{- printf "%s-ingress-notary" (include "harbor.fullname" .) -}} -{{- end -}} - {{- define "harbor.noProxy" -}} - {{- printf "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s" (include "harbor.core" .) (include "harbor.jobservice" .) (include "harbor.database" .) (include "harbor.notary-server" .) (include "harbor.notary-signer" .) (include "harbor.registry" .) (include "harbor.portal" .) (include "harbor.trivy" .) (include "harbor.exporter" .) .Values.proxy.noProxy -}} + {{- printf "%s,%s,%s,%s,%s,%s,%s,%s" (include "harbor.core" .) (include "harbor.jobservice" .) (include "harbor.database" .) (include "harbor.registry" .) (include "harbor.portal" .) (include "harbor.trivy" .) (include "harbor.exporter" .) .Values.proxy.noProxy -}} {{- end -}} {{- define "harbor.caBundleVolume" -}} @@ -287,7 +251,7 @@ postgres://{{ template "harbor.database.username" . }}:{{ template "harbor.datab subPath: ca.crt {{- end -}} -{{/* scheme for all components except notary because it only support http mode */}} +{{/* scheme for all components because it only support http mode */}} {{- define "harbor.component.scheme" -}} {{- if .Values.internalTLS.enabled -}} {{- printf "https" -}} @@ -490,16 +454,6 @@ postgres://{{ template "harbor.database.username" . }}:{{ template "harbor.datab {{- end -}} {{- end -}} -{{- define "harbor.tlsNotarySecretForIngress" -}} - {{- if eq .Values.expose.tls.certSource "none" -}} - {{- printf "" -}} - {{- else if eq .Values.expose.tls.certSource "secret" -}} - {{- .Values.expose.tls.secret.notarySecretName -}} - {{- else -}} - {{- include "harbor.ingress" . -}} - {{- end -}} -{{- end -}} - {{- define "harbor.tlsSecretForNginx" -}} {{- if eq .Values.expose.tls.certSource "secret" -}} {{- .Values.expose.tls.secret.secretName -}} diff --git a/templates/core/core-cm.yaml b/templates/core/core-cm.yaml index 307074752..cd393b926 100644 --- a/templates/core/core-cm.yaml +++ b/templates/core/core-cm.yaml @@ -26,8 +26,6 @@ data: JOBSERVICE_URL: "{{ template "harbor.jobserviceURL" . }}" REGISTRY_URL: "{{ template "harbor.registryURL" . }}" TOKEN_SERVICE_URL: "{{ template "harbor.tokenServiceURL" . }}" - WITH_NOTARY: "{{ .Values.notary.enabled }}" - NOTARY_URL: "http://{{ template "harbor.notary-server" . }}:4443" CORE_LOCAL_URL: "{{ ternary "https://127.0.0.1:8443" "http://127.0.0.1:8080" .Values.internalTLS.enabled }}" WITH_TRIVY: {{ .Values.trivy.enabled | quote }} TRIVY_ADAPTER_URL: "{{ template "harbor.trivyAdapterURL" . }}" @@ -48,7 +46,7 @@ data: HTTPS_PROXY: "{{ .Values.proxy.httpsProxy }}" NO_PROXY: "{{ template "harbor.noProxy" . }}" {{- end }} - PERMITTED_REGISTRY_TYPES_FOR_PROXY_CACHE: "docker-hub,harbor,azure-acr,aws-ecr,google-gcr,quay,docker-registry,jfrog-artifactory" + PERMITTED_REGISTRY_TYPES_FOR_PROXY_CACHE: "docker-hub,harbor,azure-acr,aws-ecr,google-gcr,quay,docker-registry,github-ghcr,jfrog-artifactory" {{- if .Values.metrics.enabled}} METRIC_ENABLE: "true" METRIC_PATH: "{{ .Values.metrics.core.path }}" diff --git a/templates/core/core-dpl.yaml b/templates/core/core-dpl.yaml index 93caa36a3..8d202498d 100644 --- a/templates/core/core-dpl.yaml +++ b/templates/core/core-dpl.yaml @@ -45,6 +45,16 @@ spec: {{- end }} automountServiceAccountToken: {{ .Values.core.automountServiceAccountToken | default false }} terminationGracePeriodSeconds: 120 +{{- with .Values.core.topologySpreadConstraints}} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: core +{{- end }} +{{- end }} containers: - name: core image: {{ .Values.core.image.repository }}:{{ .Values.core.image.tag }} diff --git a/templates/core/core-pdb.yaml b/templates/core/core-pdb.yaml index 3de79a2a4..7aab16607 100644 --- a/templates/core/core-pdb.yaml +++ b/templates/core/core-pdb.yaml @@ -1,4 +1,4 @@ -{{- if and .Values.core.podDisruptionBudget (gt (int .Values.core.replicas) 1) }} +{{- if and .Values.core.podDisruptionBudget.enabled (gt (int .Values.core.replicas) 1) }} apiVersion: policy/v1 kind: PodDisruptionBudget metadata: @@ -6,7 +6,12 @@ metadata: labels: {{ include "harbor.labels" . | indent 4 }} spec: - minAvailable: 1 + {{- if .Values.core.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.core.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.core.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.core.podDisruptionBudget.maxUnavailable }} + {{- end }} selector: {{ include "harbor.matchLabels" . | indent 4 }} component: core diff --git a/templates/core/core-secret.yaml b/templates/core/core-secret.yaml index 20f835b1d..23b352b47 100644 --- a/templates/core/core-secret.yaml +++ b/templates/core/core-secret.yaml @@ -25,4 +25,7 @@ data: REGISTRY_CREDENTIAL_PASSWORD: {{ .Values.registry.credentials.password | b64enc | quote }} {{- end }} CSRF_KEY: {{ .Values.core.xsrfKey | default (randAlphaNum 32) | b64enc | quote }} +{{- if .Values.core.configureUserSettings }} + CONFIG_OVERWRITE_JSON: {{ .Values.core.configureUserSettings | b64enc | quote }} +{{- end }} {{- template "harbor.traceJaegerPassword" . }} diff --git a/templates/exporter/exporter-dpl.yaml b/templates/exporter/exporter-dpl.yaml index 60d6f4312..6d2e1f53a 100644 --- a/templates/exporter/exporter-dpl.yaml +++ b/templates/exporter/exporter-dpl.yaml @@ -22,6 +22,11 @@ spec: {{ toYaml .Values.exporter.podLabels | indent 8 }} {{- end }} annotations: +{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} + checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }} +{{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }} + checksum/tls: {{ include (print $.Template.BasePath "/core/core-tls.yaml") . | sha256sum }} +{{- end }} {{- if .Values.exporter.podAnnotations }} {{ toYaml .Values.exporter.podAnnotations | indent 8 }} {{- end }} @@ -37,6 +42,16 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} automountServiceAccountToken: {{ .Values.exporter.automountServiceAccountToken | default false }} +{{- with .Values.exporter.topologySpreadConstraints }} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: exporter +{{- end }} +{{- end }} containers: - name: exporter image: {{ .Values.exporter.image.repository }}:{{ .Values.exporter.image.tag }} diff --git a/templates/ingress/ingress.yaml b/templates/ingress/ingress.yaml index eedd13604..e4c06939c 100644 --- a/templates/ingress/ingress.yaml +++ b/templates/ingress/ingress.yaml @@ -8,7 +8,6 @@ {{- $_ := set . "v2_path" "/v2/*" -}} {{- $_ := set . "chartrepo_path" "/chartrepo/*" -}} {{- $_ := set . "controller_path" "/c/*" -}} - {{- $_ := set . "notary_path" "/" -}} {{- else if eq .Values.expose.ingress.controller "ncp" }} {{- $_ := set . "portal_path" "/.*" -}} {{- $_ := set . "api_path" "/api/.*" -}} @@ -16,7 +15,6 @@ {{- $_ := set . "v2_path" "/v2/.*" -}} {{- $_ := set . "chartrepo_path" "/chartrepo/.*" -}} {{- $_ := set . "controller_path" "/c/.*" -}} - {{- $_ := set . "notary_path" "/.*" -}} {{- else }} {{- $_ := set . "portal_path" "/" -}} {{- $_ := set . "api_path" "/api/" -}} @@ -24,7 +22,6 @@ {{- $_ := set . "v2_path" "/v2/" -}} {{- $_ := set . "chartrepo_path" "/chartrepo/" -}} {{- $_ := set . "controller_path" "/c/" -}} - {{- $_ := set . "notary_path" "/" -}} {{- end }} --- @@ -145,65 +142,4 @@ spec: host: {{ $ingress.hosts.core }} {{- end }} -{{- if .Values.notary.enabled }} ---- -{{- if semverCompare "<1.14-0" (include "harbor.ingress.kubeVersion" .) }} -apiVersion: extensions/v1beta1 -{{- else if semverCompare "<1.19-0" (include "harbor.ingress.kubeVersion" .) }} -apiVersion: networking.k8s.io/v1beta1 -{{- else }} -apiVersion: networking.k8s.io/v1 -{{- end }} -kind: Ingress -metadata: - name: "{{ template "harbor.ingress-notary" . }}" - labels: -{{ include "harbor.labels" . | indent 4 }} -{{- if $ingress.notary.labels }} -{{ toYaml $ingress.notary.labels | indent 4 }} -{{- end }} - annotations: -{{ toYaml $ingress.annotations | indent 4 }} -{{- if eq .Values.expose.ingress.controller "ncp" }} - ncp/use-regex: "true" - {{- if $tls.enabled }} - ncp/http-redirect: "true" - {{- end }} -{{- end }} -{{- if $ingress.notary.annotations }} -{{ toYaml $ingress.notary.annotations | indent 4 }} -{{- end }} -spec: - {{- if $ingress.className }} - ingressClassName: {{ $ingress.className }} - {{- end }} - {{- if $tls.enabled }} - tls: - - secretName: {{ template "harbor.tlsNotarySecretForIngress" . }} - {{- if $ingress.hosts.notary }} - hosts: - - {{ $ingress.hosts.notary }} - {{- end }} - {{- end }} - rules: - - http: - paths: - - path: {{ .notary_path }} -{{- if semverCompare "<1.19-0" (include "harbor.ingress.kubeVersion" .) }} - backend: - serviceName: {{ template "harbor.notary-server" . }} - servicePort: 4443 -{{- else }} - pathType: Prefix - backend: - service: - name: {{ template "harbor.notary-server" . }} - port: - number: 4443 -{{- end -}} - {{- if $ingress.hosts.notary }} - host: {{ $ingress.hosts.notary }} - {{- end }} -{{- end }} - {{- end }} diff --git a/templates/ingress/secret.yaml b/templates/ingress/secret.yaml index 0d89af99a..41507b3dd 100644 --- a/templates/ingress/secret.yaml +++ b/templates/ingress/secret.yaml @@ -1,6 +1,6 @@ {{- if eq (include "harbor.autoGenCertForIngress" .) "true" }} {{- $ca := genCA "harbor-ca" 365 }} -{{- $cert := genSignedCert .Values.expose.ingress.hosts.core nil (list .Values.expose.ingress.hosts.core .Values.expose.ingress.hosts.notary) 365 $ca }} +{{- $cert := genSignedCert .Values.expose.ingress.hosts.core nil (list .Values.expose.ingress.hosts.core) 365 $ca }} apiVersion: v1 kind: Secret metadata: diff --git a/templates/jobservice/jobservice-dpl.yaml b/templates/jobservice/jobservice-dpl.yaml index f30c9763f..32df97db7 100644 --- a/templates/jobservice/jobservice-dpl.yaml +++ b/templates/jobservice/jobservice-dpl.yaml @@ -51,6 +51,16 @@ spec: {{- end }} automountServiceAccountToken: {{ .Values.jobservice.automountServiceAccountToken | default false }} terminationGracePeriodSeconds: 120 +{{- with .Values.jobservice.topologySpreadConstraints}} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: jobservice +{{- end }} +{{- end }} containers: - name: jobservice image: {{ .Values.jobservice.image.repository }}:{{ .Values.jobservice.image.tag }} diff --git a/templates/jobservice/jobservice-pdb.yaml b/templates/jobservice/jobservice-pdb.yaml index a542d421f..a2c6d76fc 100644 --- a/templates/jobservice/jobservice-pdb.yaml +++ b/templates/jobservice/jobservice-pdb.yaml @@ -1,4 +1,4 @@ -{{- if and .Values.jobservice.podDisruptionBudget (gt (int .Values.jobservice.replicas) 1) }} +{{- if and .Values.jobservice.podDisruptionBudget.enabled (gt (int .Values.jobservice.replicas) 1) }} apiVersion: policy/v1 kind: PodDisruptionBudget metadata: @@ -6,7 +6,12 @@ metadata: labels: {{ include "harbor.labels" . | indent 4 }} spec: - minAvailable: 1 + {{- if .Values.jobservice.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.jobservice.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.jobservice.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.jobservice.podDisruptionBudget.maxUnavailable }} + {{- end }} selector: {{ include "harbor.matchLabels" . | indent 4 }} component: jobservice diff --git a/templates/metrics/metrics-svcmon.yaml b/templates/metrics/metrics-svcmon.yaml index ad8522974..1122ef01e 100644 --- a/templates/metrics/metrics-svcmon.yaml +++ b/templates/metrics/metrics-svcmon.yaml @@ -1,4 +1,4 @@ -{{- if and ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" ) .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }} +{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }} apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: diff --git a/templates/nginx/configmap-https.yaml b/templates/nginx/configmap-https.yaml index 74c667e00..7b001460b 100644 --- a/templates/nginx/configmap-https.yaml +++ b/templates/nginx/configmap-https.yaml @@ -36,12 +36,6 @@ data: server "{{ template "harbor.portal" . }}:{{ template "harbor.portal.servicePort" . }}"; } - {{- if .Values.notary.enabled }} - upstream notary-server { - server {{ template "harbor.notary-server" . }}:4443; - } - {{- end }} - log_format timed_combined '[$time_local]:$remote_addr - ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' @@ -54,47 +48,6 @@ data: "" $scheme; } - {{- if .Values.notary.enabled }} - server { - {{- if .Values.ipFamily.ipv4.enabled }} - listen 4443 ssl; - {{- end}} - {{- if .Values.ipFamily.ipv6.enabled}} - listen [::]:4443 ssl; - {{- end }} - server_tokens off; - # ssl - ssl_certificate /etc/nginx/cert/tls.crt; - ssl_certificate_key /etc/nginx/cert/tls.key; - - # recommendations from https://raymii.org/s/tutorials/strong_ssl_security_on_nginx.html - ssl_protocols tlsv1.2; - ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:'; - ssl_prefer_server_ciphers on; - ssl_session_cache shared:ssl:10m; - - # disable any limits to avoid http 413 for large image uploads - client_max_body_size 0; - - # required to avoid http 411: see issue #1486 (https://github.com/docker/docker/issues/1486) - chunked_transfer_encoding on; - - location /v2/ { - proxy_pass http://notary-server/v2/; - proxy_set_header Host $http_host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $x_forwarded_proto; - - proxy_buffering off; - proxy_request_buffering off; - - proxy_send_timeout 900; - proxy_read_timeout 900; - } - } - {{- end }} - server { {{- if .Values.ipFamily.ipv4.enabled }} listen 8443 ssl; @@ -109,7 +62,7 @@ data: ssl_certificate_key /etc/nginx/cert/tls.key; # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html - ssl_protocols TLSv1.2; + ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:'; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; diff --git a/templates/nginx/deployment.yaml b/templates/nginx/deployment.yaml index 43884bc03..8290d497b 100644 --- a/templates/nginx/deployment.yaml +++ b/templates/nginx/deployment.yaml @@ -45,6 +45,16 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} automountServiceAccountToken: {{ .Values.nginx.automountServiceAccountToken | default false }} +{{- with .Values.nginx.topologySpreadConstraints}} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: nginx +{{- end }} +{{- end }} containers: - name: nginx image: "{{ .Values.nginx.image.repository }}:{{ .Values.nginx.image.tag }}" diff --git a/templates/nginx/nginx-pdb.yaml b/templates/nginx/nginx-pdb.yaml index 3d73a0a46..05743f91f 100644 --- a/templates/nginx/nginx-pdb.yaml +++ b/templates/nginx/nginx-pdb.yaml @@ -1,4 +1,4 @@ -{{- if and .Values.nginx.podDisruptionBudget (gt (int .Values.nginx.replicas) 1) }} +{{- if and .Values.nginx.podDisruptionBudget.enabled (gt (int .Values.nginx.replicas) 1) }} apiVersion: policy/v1 kind: PodDisruptionBudget metadata: @@ -6,7 +6,12 @@ metadata: labels: {{ include "harbor.labels" . | indent 4 }} spec: - minAvailable: 1 + {{- if .Values.nginx.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.nginx.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.nginx.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.nginx.podDisruptionBudget.maxUnavailable }} + {{- end }} selector: {{ include "harbor.matchLabels" . | indent 4 }} component: nginx diff --git a/templates/nginx/service.yaml b/templates/nginx/service.yaml index df4da0944..12021bfd1 100644 --- a/templates/nginx/service.yaml +++ b/templates/nginx/service.yaml @@ -22,11 +22,6 @@ spec: port: {{ $clusterIP.ports.httpsPort }} targetPort: 8443 {{- end }} - {{- if .Values.notary.enabled }} - - name: notary - port: {{ $clusterIP.ports.notaryPort }} - targetPort: 4443 - {{- end }} {{- else if eq .Values.expose.type "nodePort" }} {{- $nodePort := .Values.expose.nodePort }} name: {{ $nodePort.name }} @@ -49,14 +44,6 @@ spec: nodePort: {{ $nodePort.ports.https.nodePort }} {{- end }} {{- end }} - {{- if .Values.notary.enabled }} - - name: notary - port: {{ $nodePort.ports.notary.port }} - targetPort: 4443 - {{- if $nodePort.ports.notary.nodePort }} - nodePort: {{ $nodePort.ports.notary.nodePort }} - {{- end }} - {{- end }} {{- else if eq .Values.expose.type "loadBalancer" }} {{- $loadBalancer := .Values.expose.loadBalancer }} name: {{ $loadBalancer.name }} @@ -84,11 +71,6 @@ spec: port: {{ $loadBalancer.ports.httpsPort }} targetPort: 8443 {{- end }} - {{- if .Values.notary.enabled }} - - name: notary - port: {{ $loadBalancer.ports.notaryPort }} - targetPort: 4443 - {{- end }} {{- end }} selector: {{ include "harbor.matchLabels" . | indent 4 }} diff --git a/templates/notary/notary-secret.yaml b/templates/notary/notary-secret.yaml deleted file mode 100644 index 6de63dd8c..000000000 --- a/templates/notary/notary-secret.yaml +++ /dev/null @@ -1,22 +0,0 @@ -{{- if and .Values.notary.enabled }} -apiVersion: v1 -kind: Secret -metadata: - name: {{ template "harbor.notary-server" . }} - labels: -{{ include "harbor.labels" . | indent 4 }} - component: notary -type: Opaque -data: - {{- if not .Values.notary.secretName }} - {{- $ca := genCA "harbor-notary-ca" 365 }} - {{- $cert := genSignedCert (include "harbor.notary-signer" .) nil (list (include "harbor.notary-signer" .)) 365 $ca }} - ca.crt: {{ $ca.Cert | b64enc | quote }} - tls.crt: {{ $cert.Cert | b64enc | quote }} - tls.key: {{ $cert.Key | b64enc | quote }} - {{- end }} - server.json: {{ tpl (.Files.Get "conf/notary-server.json") . | b64enc }} - signer.json: {{ tpl (.Files.Get "conf/notary-signer.json") . | b64enc }} - NOTARY_SERVER_DB_URL: {{ include "harbor.database.notaryServer" . | b64enc }} - NOTARY_SIGNER_DB_URL: {{ include "harbor.database.notarySigner" . | b64enc }} -{{- end }} diff --git a/templates/notary/notary-server.yaml b/templates/notary/notary-server.yaml deleted file mode 100644 index 844557a28..000000000 --- a/templates/notary/notary-server.yaml +++ /dev/null @@ -1,117 +0,0 @@ -{{ if .Values.notary.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "harbor.notary-server" . }} - labels: -{{ include "harbor.labels" . | indent 4 }} - component: notary-server -spec: - replicas: {{ .Values.notary.server.replicas }} - selector: - matchLabels: -{{ include "harbor.matchLabels" . | indent 6 }} - component: notary-server - template: - metadata: - labels: -{{ include "harbor.labels" . | indent 8 }} - component: notary-server -{{- if .Values.notary.server.podLabels }} -{{ toYaml .Values.notary.server.podLabels | indent 8 }} -{{- end }} - annotations: - checksum/secret: {{ include (print $.Template.BasePath "/notary/notary-secret.yaml") . | sha256sum }} - checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }} -{{- if .Values.notary.server.podAnnotations }} -{{ toYaml .Values.notary.server.podAnnotations | indent 8 }} -{{- end }} - spec: - securityContext: - runAsUser: 10000 - fsGroup: 10000 -{{- if .Values.notary.server.serviceAccountName }} - serviceAccountName: {{ .Values.notary.server.serviceAccountName }} -{{- end -}} - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} - automountServiceAccountToken: {{ .Values.notary.server.automountServiceAccountToken | default false }} - containers: - - name: notary-server - image: {{ .Values.notary.server.image.repository }}:{{ .Values.notary.server.image.tag }} - imagePullPolicy: {{ .Values.imagePullPolicy }} - livenessProbe: - httpGet: - path: /_notary_server/health - scheme: "HTTP" - port: 4443 - initialDelaySeconds: 300 - periodSeconds: 10 - readinessProbe: - httpGet: - path: /_notary_server/health - scheme: "HTTP" - port: 4443 - initialDelaySeconds: 20 - periodSeconds: 10 -{{- if .Values.notary.server.resources }} - resources: -{{ toYaml .Values.notary.server.resources | indent 10 }} -{{- end }} - env: - - name: MIGRATIONS_PATH - value: migrations/server/postgresql - - name: DB_URL - valueFrom: - secretKeyRef: - name: {{ template "harbor.notary-server" . }} - key: NOTARY_SERVER_DB_URL -{{- with .Values.notary.server.extraEnvVars }} -{{- toYaml . | nindent 8 }} -{{- end }} - volumeMounts: - - name: config - mountPath: /etc/notary/server-config.postgres.json - subPath: server.json - - name: token-service-certificate - mountPath: /root.crt - subPath: tls.crt - - name: signer-certificate - mountPath: /etc/ssl/notary/ca.crt - subPath: ca.crt - volumes: - - name: config - secret: - secretName: "{{ template "harbor.notary-server" . }}" - - name: token-service-certificate - secret: - {{- if .Values.core.secretName }} - secretName: {{ .Values.core.secretName }} - {{- else }} - secretName: {{ template "harbor.core" . }} - {{- end }} - - name: signer-certificate - secret: - {{- if .Values.notary.secretName }} - secretName: {{ .Values.notary.secretName }} - {{- else }} - secretName: {{ template "harbor.notary-server" . }} - {{- end }} - {{- with .Values.notary.server.nodeSelector }} - nodeSelector: -{{ toYaml . | indent 8 }} - {{- end }} - {{- with .Values.notary.server.affinity }} - affinity: -{{ toYaml . | indent 8 }} - {{- end }} - {{- with .Values.notary.server.tolerations }} - tolerations: -{{ toYaml . | indent 8 }} - {{- end }} - {{- if .Values.notary.server.priorityClassName }} - priorityClassName: {{ .Values.notary.server.priorityClassName }} - {{- end }} -{{ end }} diff --git a/templates/notary/notary-signer.yaml b/templates/notary/notary-signer.yaml deleted file mode 100644 index e29ff5680..000000000 --- a/templates/notary/notary-signer.yaml +++ /dev/null @@ -1,111 +0,0 @@ -{{ if .Values.notary.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ template "harbor.notary-signer" . }} - labels: -{{ include "harbor.labels" . | indent 4 }} - component: notary-signer -spec: - replicas: {{ .Values.notary.signer.replicas }} - selector: - matchLabels: -{{ include "harbor.matchLabels" . | indent 6 }} - component: notary-signer - template: - metadata: - labels: -{{ include "harbor.labels" . | indent 8 }} - component: notary-signer -{{- if .Values.notary.signer.podLabels }} -{{ toYaml .Values.notary.signer.podLabels | indent 8 }} -{{- end }} - annotations: - checksum/secret: {{ include (print $.Template.BasePath "/notary/notary-secret.yaml") . | sha256sum }} -{{- if .Values.notary.signer.podAnnotations }} -{{ toYaml .Values.notary.signer.podAnnotations | indent 8 }} -{{- end }} - spec: - securityContext: - runAsUser: 10000 - fsGroup: 10000 -{{- if .Values.notary.signer.serviceAccountName }} - serviceAccountName: {{ .Values.notary.signer.serviceAccountName }} -{{- end -}} - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} - automountServiceAccountToken: {{ .Values.notary.signer.automountServiceAccountToken | default false }} - containers: - - name: notary-signer - image: {{ .Values.notary.signer.image.repository }}:{{ .Values.notary.signer.image.tag }} - imagePullPolicy: {{ .Values.imagePullPolicy }} - livenessProbe: - httpGet: - path: / - scheme: "HTTPS" - port: 7899 - initialDelaySeconds: 300 - periodSeconds: 10 - readinessProbe: - httpGet: - path: / - scheme: "HTTPS" - port: 7899 - initialDelaySeconds: 20 - periodSeconds: 10 -{{- if .Values.notary.signer.resources }} - resources: -{{ toYaml .Values.notary.signer.resources | indent 10 }} -{{- end }} - env: - - name: MIGRATIONS_PATH - value: migrations/signer/postgresql - - name: DB_URL - valueFrom: - secretKeyRef: - name: {{ template "harbor.notary-server" . }} - key: NOTARY_SIGNER_DB_URL - - name: NOTARY_SIGNER_DEFAULTALIAS - value: defaultalias -{{- with .Values.notary.signer.extraEnvVars }} -{{- toYaml . | nindent 8 }} -{{- end }} - volumeMounts: - - name: config - mountPath: /etc/notary/signer-config.postgres.json - subPath: signer.json - - name: signer-certificate - mountPath: /etc/ssl/notary/tls.crt - subPath: tls.crt - - name: signer-certificate - mountPath: /etc/ssl/notary/tls.key - subPath: tls.key - volumes: - - name: config - secret: - secretName: "{{ template "harbor.notary-server" . }}" - - name: signer-certificate - secret: - {{- if .Values.notary.secretName }} - secretName: {{ .Values.notary.secretName }} - {{- else }} - secretName: {{ template "harbor.notary-server" . }} - {{- end }} - {{- with .Values.notary.signer.nodeSelector }} - nodeSelector: -{{ toYaml . | indent 8 }} - {{- end }} - {{- with .Values.notary.signer.affinity }} - affinity: -{{ toYaml . | indent 8 }} - {{- end }} - {{- with .Values.notary.signer.tolerations }} - tolerations: -{{ toYaml . | indent 8 }} - {{- end }} - {{- if .Values.notary.signer.priorityClassName }} - priorityClassName: {{ .Values.notary.signer.priorityClassName }} - {{- end }} -{{ end }} diff --git a/templates/notary/notary-svc.yaml b/templates/notary/notary-svc.yaml deleted file mode 100644 index b6aa42d89..000000000 --- a/templates/notary/notary-svc.yaml +++ /dev/null @@ -1,35 +0,0 @@ -{{ if .Values.notary.enabled }} -apiVersion: v1 -kind: Service -metadata: - name: {{ template "harbor.notary-server" . }} - labels: -{{ include "harbor.labels" . | indent 4 }} -{{- with .Values.notary.serviceAnnotations }} - annotations: - {{- toYaml . | nindent 4 }} -{{- end }} -spec: -{{- if or (eq .Values.expose.ingress.controller "gce") (eq .Values.expose.ingress.controller "alb") (eq .Values.expose.ingress.controller "f5-bigip") }} - type: NodePort -{{- end }} - ports: - - port: 4443 - selector: -{{ include "harbor.matchLabels" . | indent 4 }} - component: notary-server - ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "harbor.notary-signer" . }} - labels: -{{ include "harbor.labels" . | indent 4 }} -spec: - ports: - - port: 7899 - selector: -{{ include "harbor.matchLabels" . | indent 4 }} - component: notary-signer -{{ end }} diff --git a/templates/portal/configmap.yaml b/templates/portal/configmap.yaml index 1cea8ab63..156fd34f4 100644 --- a/templates/portal/configmap.yaml +++ b/templates/portal/configmap.yaml @@ -30,7 +30,7 @@ data: ssl_certificate_key /etc/harbor/ssl/portal/tls.key; # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html - ssl_protocols TLSv1.2; + ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:'; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; diff --git a/templates/portal/deployment.yaml b/templates/portal/deployment.yaml index c4ad02679..959a3fd7b 100644 --- a/templates/portal/deployment.yaml +++ b/templates/portal/deployment.yaml @@ -42,6 +42,16 @@ spec: serviceAccountName: {{ .Values.portal.serviceAccountName }} {{- end }} automountServiceAccountToken: {{ .Values.portal.automountServiceAccountToken | default false }} +{{- with .Values.portal.topologySpreadConstraints}} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: portal +{{- end }} +{{- end }} containers: - name: portal image: {{ .Values.portal.image.repository }}:{{ .Values.portal.image.tag }} diff --git a/templates/portal/portal-pdb.yaml b/templates/portal/portal-pdb.yaml index b20aca4da..baf707d5c 100644 --- a/templates/portal/portal-pdb.yaml +++ b/templates/portal/portal-pdb.yaml @@ -1,4 +1,4 @@ -{{- if and .Values.portal.podDisruptionBudget (gt (int .Values.portal.replicas) 1) }} +{{- if and .Values.portal.podDisruptionBudget.enabled (gt (int .Values.portal.replicas) 1) }} apiVersion: policy/v1 kind: PodDisruptionBudget metadata: @@ -6,7 +6,12 @@ metadata: labels: {{ include "harbor.labels" . | indent 4 }} spec: - minAvailable: 1 + {{- if .Values.portal.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.portal.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.portal.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.portal.podDisruptionBudget.maxUnavailable }} + {{- end }} selector: {{ include "harbor.matchLabels" . | indent 4 }} component: portal diff --git a/templates/registry/registry-dpl.yaml b/templates/registry/registry-dpl.yaml index ec694ffdb..adb5a73f5 100644 --- a/templates/registry/registry-dpl.yaml +++ b/templates/registry/registry-dpl.yaml @@ -54,6 +54,16 @@ spec: {{- end }} automountServiceAccountToken: {{ .Values.registry.automountServiceAccountToken | default false }} terminationGracePeriodSeconds: 120 +{{- with .Values.registry.topologySpreadConstraints}} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: registry +{{- end }} +{{- end }} containers: - name: registry image: {{ .Values.registry.registry.image.repository }}:{{ .Values.registry.registry.image.tag }} diff --git a/templates/registry/registry-pdb.yaml b/templates/registry/registry-pdb.yaml index f99a8cee5..5f56e18d3 100644 --- a/templates/registry/registry-pdb.yaml +++ b/templates/registry/registry-pdb.yaml @@ -1,4 +1,4 @@ -{{- if and .Values.registry.podDisruptionBudget (gt (int .Values.registry.replicas) 1) }} +{{- if and .Values.registry.podDisruptionBudget.enabled (gt (int .Values.registry.replicas) 1) }} apiVersion: policy/v1 kind: PodDisruptionBudget metadata: @@ -6,7 +6,12 @@ metadata: labels: {{ include "harbor.labels" . | indent 4 }} spec: - minAvailable: 1 + {{- if .Values.registry.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.registry.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.registry.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.registry.podDisruptionBudget.maxUnavailable }} + {{- end }} selector: {{ include "harbor.matchLabels" . | indent 4 }} component: registry diff --git a/templates/trivy/trivy-pdb.yaml b/templates/trivy/trivy-pdb.yaml index c284ba2c5..4f7cd7110 100644 --- a/templates/trivy/trivy-pdb.yaml +++ b/templates/trivy/trivy-pdb.yaml @@ -1,4 +1,4 @@ -{{- if and .Values.trivy.podDisruptionBudget (gt (int .Values.trivy.replicas) 1) }} +{{- if and .Values.trivy.podDisruptionBudget.enabled (gt (int .Values.trivy.replicas) 1) }} apiVersion: policy/v1 kind: PodDisruptionBudget metadata: @@ -6,7 +6,12 @@ metadata: labels: {{ include "harbor.labels" . | indent 4 }} spec: - minAvailable: 1 + {{- if .Values.trivy.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.trivy.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.trivy.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.trivy.podDisruptionBudget.maxUnavailable }} + {{- end }} selector: {{ include "harbor.matchLabels" . | indent 4 }} component: trivy diff --git a/templates/trivy/trivy-sts.yaml b/templates/trivy/trivy-sts.yaml index 76ba65623..aba23c9e8 100644 --- a/templates/trivy/trivy-sts.yaml +++ b/templates/trivy/trivy-sts.yaml @@ -44,6 +44,16 @@ spec: runAsUser: 10000 fsGroup: 10000 automountServiceAccountToken: {{ .Values.trivy.automountServiceAccountToken | default false }} +{{- with .Values.trivy.topologySpreadConstraints}} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: trivy +{{- end }} +{{- end }} containers: - name: trivy image: {{ .Values.trivy.image.repository }}:{{ .Values.trivy.image.tag }} diff --git a/test/e2e/Jenkinsfile b/test/e2e/Jenkinsfile index a40751fbe..a7f7d0502 100644 --- a/test/e2e/Jenkinsfile +++ b/test/e2e/Jenkinsfile @@ -50,23 +50,21 @@ class HarborChartFreshInstallPipelineExecutor extends FreshInstallPipelineExecut # install harbor chart docker run -i --rm -w /workspace -v \${KUBE_CONFIG_FILE_PATH}:/root/.kube/config -v \$(pwd):/workspace deployer:dev \ helm install harbor --kube-context ${context} -n ${namespace} --create-namespace \ - --set "expose.ingress.hosts.core=${coreHostname},expose.ingress.hosts.notary=notary.${coreHostname},externalURL=https://${coreHostname},internalTLS.enabled=true,imagePullPolicy=Always,trivy.skipUpdate=true,core.gcTimeWindowHours=0" . + --set "expose.ingress.hosts.core=${coreHostname},externalURL=https://${coreHostname},internalTLS.enabled=true,imagePullPolicy=Always,trivy.skipUpdate=true,core.gcTimeWindowHours=0" . """ } HarborInstance instance = new HarborInstance() instance.coreServiceURL = "https://" + coreHostname - instance.notaryServiceURL = "https://notary." + coreHostname instance.adminPassword = "Harbor12345" instance.authMode = "database" - instance.components = "trivy,notary" - instance.hostIPMappings = "${coreHostname}:${ingressControllerIP},notary.${coreHostname}:${ingressControllerIP}" + instance.components = "trivy" + instance.hostIPMappings = "${coreHostname}:${ingressControllerIP}" script.currentBuild.description = """ Kubernetes: ${context} Namespace: ${namespace} Core Service: $instance.coreServiceURL - Notary Service: $instance.notaryServiceURL Ingress Controller IP: ${ingressControllerIP} """ @@ -101,7 +99,7 @@ def properties = { def caseSettings = { CaseSettings settings = new CaseSettings() - settings.cases = "gc,common,database,trivy,notary" + settings.cases = "gc,common,database,trivy" return settings } diff --git a/test/integration/ingress_test.go b/test/integration/ingress_test.go index 4e7364973..107a4f8c9 100644 --- a/test/integration/ingress_test.go +++ b/test/integration/ingress_test.go @@ -14,15 +14,13 @@ type IngressTestSuite struct { func (i *IngressTestSuite) TestIngress() { k8s.GetIngress(i.T(), i.Options.KubectlOptions, fmt.Sprintf("%s-ingress", i.ReleaseName)) - k8s.GetIngress(i.T(), i.Options.KubectlOptions, fmt.Sprintf("%s-ingress-notary", i.ReleaseName)) } func TestIngressTestSuite(t *testing.T) { suite.Run(t, &IngressTestSuite{ BaseTestSuite: NewBaseTestSuite(map[string]string{ - "expose.ingress.hosts.core": "harbor.local", - "expose.ingress.hosts.notary": "notary.harbor.local", - "externalURL": "https://harbor.local", + "expose.ingress.hosts.core": "harbor.local", + "externalURL": "https://harbor.local", }), }) } diff --git a/values.yaml b/values.yaml index 0e4fb94e7..6fdf4dd5c 100644 --- a/values.yaml +++ b/values.yaml @@ -26,15 +26,9 @@ expose: # "tls.crt" - the certificate # "tls.key" - the private key secretName: "" - # The name of secret which contains keys named: - # "tls.crt" - the certificate - # "tls.key" - the private key - # Only needed when the "expose.type" is "ingress". - notarySecretName: "" ingress: hosts: core: core.harbor.domain - notary: notary.harbor.domain # set to the type of ingress controller if it has specific requirements. # leave as `default` for most ingress controllers. # set to `gce` if using the GCE ingress controller @@ -52,11 +46,6 @@ expose: ingress.kubernetes.io/proxy-body-size: "0" nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/proxy-body-size: "0" - notary: - # notary ingress-specific annotations - annotations: {} - # notary ingress-specific labels - labels: {} harbor: # harbor ingress-specific annotations annotations: {} @@ -71,10 +60,6 @@ expose: # The service port Harbor listens on when serving HTTP httpPort: 80 # The service port Harbor listens on when serving HTTPS - httpsPort: 443 - # The service port Notary listens on. Only needed when notary.enabled - # is set to true - notaryPort: 4443 nodePort: # The name of NodePort service name: harbor @@ -89,12 +74,6 @@ expose: port: 443 # The node port Harbor listens on when serving HTTPS nodePort: 30003 - # Only needed when notary.enabled is set to true - notary: - # The service port Notary listens on - port: 4443 - # The node port Notary listens on - nodePort: 30004 loadBalancer: # The name of LoadBalancer service name: harbor @@ -105,15 +84,12 @@ expose: httpPort: 80 # The service port Harbor listens on when serving HTTPS httpsPort: 443 - # The service port Notary listens on. Only needed when notary.enabled - # is set to true - notaryPort: 4443 annotations: {} sourceRanges: [] # The external URL for Harbor core service. It is used to # 1) populate the docker/helm commands showed on portal -# 2) populate the token service URL returned to docker/notary client +# 2) populate the token service URL returned to docker client # # Format: protocol://domain[:port]. Usually: # 1) if "expose.type" is "ingress", the "domain" should be @@ -284,7 +260,7 @@ persistence: encodedkey: base64-encoded-json-key-file #rootdirectory: /gcs/object/name/prefix #chunksize: "5242880" - # To use existing secret, the key must be gcs-key.json + # To use existing secret, the key must be GCS_KEY_DATA existingSecret: "" useWorkloadIdentity: false s3: @@ -406,6 +382,10 @@ nginx: # mount the service account token automountServiceAccountToken: false replicas: 1 + podDisruptionBudget: + enabled: false + minAvailable: 1 + # maxUnavailable: 1 revisionHistoryLimit: 10 # resources: # requests: @@ -415,7 +395,12 @@ nginx: nodeSelector: {} tolerations: [] affinity: {} - podDisruptionBudget: false + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule ## Additional deployment annotations podAnnotations: {} ## Additional deployment labels @@ -432,6 +417,10 @@ portal: # mount the service account token automountServiceAccountToken: false replicas: 1 + podDisruptionBudget: + enabled: false + minAvailable: 1 + # maxUnavailable: 1 revisionHistoryLimit: 10 # resources: # requests: @@ -441,7 +430,12 @@ portal: nodeSelector: {} tolerations: [] affinity: {} - podDisruptionBudget: false + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule ## Additional deployment annotations podAnnotations: {} ## Additional deployment labels @@ -458,6 +452,10 @@ core: # mount the service account token automountServiceAccountToken: false replicas: 1 + podDisruptionBudget: + enabled: false + minAvailable: 1 + # maxUnavailable: 1 revisionHistoryLimit: 10 ## Startup probe values startupProbe: @@ -471,13 +469,20 @@ core: nodeSelector: {} tolerations: [] affinity: {} - podDisruptionBudget: false + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule ## Additional deployment annotations podAnnotations: {} ## Additional deployment labels podLabels: {} ## Additional service annotations serviceAnnotations: {} + ## User settings configuration json string + configureUserSettings: # 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. @@ -511,6 +516,10 @@ jobservice: repository: goharbor/harbor-jobservice tag: dev replicas: 1 + podDisruptionBudget: + enabled: false + minAvailable: 1 + # maxUnavailable: 1 revisionHistoryLimit: 10 # set the service account to be used, default if left empty serviceAccountName: "" @@ -541,7 +550,12 @@ jobservice: nodeSelector: {} tolerations: [] affinity: {} - podDisruptionBudget: false + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule ## Additional deployment annotations podAnnotations: {} ## Additional deployment labels @@ -578,11 +592,20 @@ registry: # cpu: 100m extraEnvVars: [] replicas: 1 + podDisruptionBudget: + enabled: false + minAvailable: 1 + # maxUnavailable: 1 revisionHistoryLimit: 10 nodeSelector: {} tolerations: [] affinity: {} - podDisruptionBudget: false + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule ## Additional deployment annotations podAnnotations: {} ## Additional deployment labels @@ -638,6 +661,10 @@ trivy: automountServiceAccountToken: false # replicas the number of Pod replicas replicas: 1 + podDisruptionBudget: + enabled: false + minAvailable: 1 + # maxUnavailable: 1 # debugMode the flag to enable Trivy debug mode with more verbose scanning log debugMode: false # vulnType a comma-separated list of vulnerability types. Possible values are `os` and `library`. @@ -693,7 +720,12 @@ trivy: nodeSelector: {} tolerations: [] affinity: {} - podDisruptionBudget: false + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule ## Additional deployment annotations podAnnotations: {} ## Additional deployment labels @@ -701,64 +733,6 @@ trivy: ## The priority class to run the pod as priorityClassName: -notary: - enabled: true - server: - # set the service account to be used, default if left empty - serviceAccountName: "" - # mount the service account token - automountServiceAccountToken: false - image: - repository: goharbor/notary-server-photon - tag: dev - replicas: 1 - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - extraEnvVars: [] - nodeSelector: {} - tolerations: [] - affinity: {} - ## Additional deployment annotations - podAnnotations: {} - ## Additional deployment labels - podLabels: {} - ## The priority class to run the pod as - priorityClassName: - ## Additional service annotations - serviceAnnotations: {} - signer: - # set the service account to be used, default if left empty - serviceAccountName: "" - # mount the service account token - automountServiceAccountToken: false - image: - repository: goharbor/notary-signer-photon - tag: dev - replicas: 1 - # resources: - # requests: - # memory: 256Mi - # cpu: 100m - extraEnvVars: [] - nodeSelector: {} - tolerations: [] - affinity: {} - ## Additional deployment annotations - podAnnotations: {} - ## Additional deployment labels - podLabels: {} - ## The priority class to run the pod as - priorityClassName: - # 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 ca.crt, tls.crt and tls.key that - # contain the CA, certificate and private key. - # They will be generated if not set. - secretName: "" - database: # if external database is used, set "type" to "external" # and fill the connection information in "external" section @@ -810,8 +784,6 @@ database: username: "user" password: "password" coreDatabase: "registry" - notaryServerDatabase: "notary_server" - notarySignerDatabase: "notary_signer" # if using existing secret, the key must be "password" existingSecret: "" # "disable" - No SSL @@ -899,6 +871,12 @@ exporter: nodeSelector: {} tolerations: [] affinity: {} + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule cacheDuration: 23 cacheCleanInterval: 14400 ## The priority class to run the pod as