Commit c039253d authored by root's avatar root

update chart fis

parent 124d25a4
name: Integration test
on:
pull_request:
push:
jobs:
integration-test:
runs-on: ubuntu-latest
strategy:
matrix:
k8s_version: [v1.18.2, v1.17.5, v1.16.9]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Docker
uses: docker-practice/actions-setup-docker@0.0.1
with:
docker_version: 18.09
docker_channel: stable
docker_daemon_json: '{"insecure-registries":["0.0.0.0/0"]}'
- name: Create kind cluster
uses: helm/kind-action@v1.0.0-rc.1
with:
version: v0.8.1
node_image: kindest/node:${{ matrix.k8s_version }}
cluster_name: kind-cluster-${{ matrix.k8s_version }}
config: test/integration/kind-cluster.yaml
- name: Install Nginx ingress controller
run: |
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/ingress-nginx-2.3.0/deploy/static/provider/kind/deploy.yaml
kubectl wait --namespace ingress-nginx --for=condition=ready pod --selector=app.kubernetes.io/component=controller --timeout=120s
- name: Set up Go 1.13
uses: actions/setup-go@v2
with:
go-version: 1.13
- name: Cache go mod
uses: actions/cache@v2
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- 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
run:
go test -v -timeout 30m github.com/goharbor/harbor-helm/integration
\ No newline at end of file
name: Lint
on:
pull_request:
push:
jobs:
lint:
runs-on: ubuntu-latest
strategy:
matrix:
helm_version: [3.2.3, 2.16.8]
steps:
- name: Checkout
uses: actions/checkout@v2
with:
path: harbor
- name: Set up Helm
uses: azure/setup-helm@v1
with:
version: '${{ matrix.helm_version }}'
- name: Helm version
run:
helm version -c
- name: Run lint
working-directory: ./harbor
run:
helm lint .
- name: Update dependency
working-directory: ./harbor
run:
helm dependency update .
- name: Run template for ingress expose
working-directory: ./harbor
run:
helm template --set "expose.type=ingress" --output-dir $(mktemp -d -t output-XXXXXXXXXX) .
- name: Run template for nodePort expose
working-directory: ./harbor
run:
helm template --set "expose.type=nodePort,expose.tls.auto.commonName=127.0.0.1" --output-dir $(mktemp -d -t output-XXXXXXXXXX) .
\ No newline at end of file
name: Unit test
on:
pull_request:
push:
jobs:
unit-test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up Helm 3.2.3
uses: azure/setup-helm@v1
with:
version: '3.2.3'
- name: Set up Go 1.13
uses: actions/setup-go@v2
with:
go-version: 1.13
- name: Cache go mod
uses: actions/cache@v2
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Run unit tests
working-directory: ./test
run:
go test -v github.com/goharbor/harbor-helm/unittest
charts/* charts/*
requirements.lock requirements.lock
\ No newline at end of file
docs/* docs/*
.git/* .git/*
.gitignore .gitignore
CONTRIBUTING.md CONTRIBUTING.md
\ No newline at end of file .travis.yaml
test/*
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
Please follow [Harbor contributing guide](https://github.com/goharbor/harbor/blob/master/CONTRIBUTING.md) to learn how to make code contribution. Please follow [Harbor contributing guide](https://github.com/goharbor/harbor/blob/master/CONTRIBUTING.md) to learn how to make code contribution.
# Contributers ## Contributers
Thanks very much to all contributers who submitted pull requests to Helm Chart for Harbor. Thanks very much to all contributers who submitted pull requests to Helm Chart for Harbor.
......
apiVersion: v1
name: harbor name: harbor
version: 1.1.1 version: 1.5.1
appVersion: 1.8.1 appVersion: 2.1.1
description: An open source trusted cloud native registry that stores, signs, and scans content description: An open source trusted cloud native registry that stores, signs, and scans content
keywords: keywords:
- docker - docker
- registry - registry
- harbor - harbor
home: https://goharbor.io home: https://goharbor.io
icon: https://raw.githubusercontent.com/goharbor/harbor/master/docs/img/harbor_logo.png icon: https://raw.githubusercontent.com/goharbor/website/master/static/img/logos/harbor-icon-color.png
sources: sources:
- https://github.com/goharbor/harbor - https://github.com/goharbor/harbor
- https://github.com/goharbor/harbor-helm - https://github.com/goharbor/harbor-helm
maintainers: maintainers:
- name: Jesse Hu - name: Wenkai Yin
email: huh@vmware.com email: yinw@vmware.com
- name: paulczar - name: Weiwei He
email: username.taken@gmail.com email: hweiwei@vmware.com
- name: Qian Deng
email: dengq@vmware.com
engine: gotpl engine: gotpl
...@@ -33,24 +33,24 @@ helm template \ ...@@ -33,24 +33,24 @@ helm template \
```bash ```bash
# goharbor/harbor-portal # goharbor/harbor-portal
docker pull goharbor/harbor-portal:v1.8.6 && \ docker pull goharbor/harbor-portal:v2.1.1 && \
docker tag goharbor/harbor-portal:v1.8.6 registry.cn-qingdao.aliyuncs.com/wod/harbor-portal:v1.8.6 && \ docker tag goharbor/harbor-portal:v2.1.1 registry.cn-qingdao.aliyuncs.com/wod/harbor-portal:v2.1.1 && \
docker push registry.cn-qingdao.aliyuncs.com/wod/harbor-portal:v1.8.6 docker push registry.cn-qingdao.aliyuncs.com/wod/harbor-portal:v2.1.1
# goharbor/harbor-core # goharbor/harbor-core
docker pull goharbor/harbor-core:v1.8.6 && \ docker pull goharbor/harbor-core:v2.1.1 && \
docker tag goharbor/harbor-core:v1.8.6 registry.cn-qingdao.aliyuncs.com/wod/harbor-core:v1.8.6 && \ docker tag goharbor/harbor-core:v2.1.1 registry.cn-qingdao.aliyuncs.com/wod/harbor-core:v2.1.1 && \
docker push registry.cn-qingdao.aliyuncs.com/wod/harbor-core:v1.8.6 docker push registry.cn-qingdao.aliyuncs.com/wod/harbor-core:v2.1.1
# goharbor/harbor-jobservice # goharbor/harbor-jobservice
docker pull goharbor/harbor-jobservice:v1.8.6 && \ docker pull goharbor/harbor-jobservice:v2.1.1 && \
docker tag goharbor/harbor-jobservice:v1.8.6 registry.cn-qingdao.aliyuncs.com/wod/harbor-jobservice:v1.8.6 && \ docker tag goharbor/harbor-jobservice:v2.1.1 registry.cn-qingdao.aliyuncs.com/wod/harbor-jobservice:v2.1.1 && \
docker push registry.cn-qingdao.aliyuncs.com/wod/harbor-jobservice:v1.8.6 docker push registry.cn-qingdao.aliyuncs.com/wod/harbor-jobservice:v2.1.1
# goharbor/harbor-db # goharbor/harbor-db
docker pull goharbor/harbor-db:v1.8.6 && \ docker pull goharbor/harbor-db:v2.1.1 && \
docker tag goharbor/harbor-db:v1.8.6 registry.cn-qingdao.aliyuncs.com/wod/harbor-db:v1.8.6 && \ docker tag goharbor/harbor-db:v2.1.1 registry.cn-qingdao.aliyuncs.com/wod/harbor-db:v2.1.1 && \
docker push registry.cn-qingdao.aliyuncs.com/wod/harbor-db:v1.8.6 docker push registry.cn-qingdao.aliyuncs.com/wod/harbor-db:v2.1.1
# registry # registry
docker pull registry:2.7.1 && \ docker pull registry:2.7.1 && \
...@@ -58,29 +58,38 @@ docker tag registry:2.7.1 registry.cn-qingdao.aliyuncs.com/wod/registry:2.7.1 && ...@@ -58,29 +58,38 @@ docker tag registry:2.7.1 registry.cn-qingdao.aliyuncs.com/wod/registry:2.7.1 &&
docker push registry.cn-qingdao.aliyuncs.com/wod/registry:2.7.1 docker push registry.cn-qingdao.aliyuncs.com/wod/registry:2.7.1
# goharbor/harbor-registryctl # goharbor/harbor-registryctl
docker pull goharbor/harbor-registryctl:v1.8.6 && \ docker pull goharbor/harbor-registryctl:v2.1.1 && \
docker tag goharbor/harbor-registryctl:v1.8.6 registry.cn-qingdao.aliyuncs.com/wod/harbor-registryctl:v1.8.6 && \ docker tag goharbor/harbor-registryctl:v2.1.1 registry.cn-qingdao.aliyuncs.com/wod/harbor-registryctl:v2.1.1 && \
docker push registry.cn-qingdao.aliyuncs.com/wod/harbor-registryctl:v1.8.6 docker push registry.cn-qingdao.aliyuncs.com/wod/harbor-registryctl:v2.1.1
# goharbor/chartmuseum-photon # goharbor/chartmuseum-photon
docker pull goharbor/chartmuseum-photon:v0.9.0-v1.8.6 && \ docker pull goharbor/chartmuseum-photon:v2.1.1 && \
docker tag goharbor/chartmuseum-photon:v0.9.0-v1.8.6 registry.cn-qingdao.aliyuncs.com/wod/chartmuseum-photon:v0.9.0-v1.8.6 && \ docker tag goharbor/chartmuseum-photon:v2.1.1 registry.cn-qingdao.aliyuncs.com/wod/chartmuseum-photon:v2.1.1 && \
docker push registry.cn-qingdao.aliyuncs.com/wod/chartmuseum-photon:v0.9.0-v1.8.6 docker push registry.cn-qingdao.aliyuncs.com/wod/chartmuseum-photon:v2.1.1
# goharbor/clair-photon # goharbor/clair-photon
docker pull goharbor/clair-photon:v2.1.0-v1.8.6 && \ docker pull goharbor/clair-photon:v2.1.1 && \
docker tag goharbor/clair-photon:v2.1.0-v1.8.6 registry.cn-qingdao.aliyuncs.com/wod/clair-photon:v2.1.0-v1.8.6 && \ docker tag goharbor/clair-photon:v2.1.1 registry.cn-qingdao.aliyuncs.com/wod/clair-photon:v2.1.1 && \
docker push registry.cn-qingdao.aliyuncs.com/wod/clair-photon:v2.1.0-v1.8.6 docker push registry.cn-qingdao.aliyuncs.com/wod/clair-photon:v2.1.1
docker pull goharbor/clair-adapter-photon:v2.1.1 && \
docker tag goharbor/clair-adapter-photon:v2.1.1 registry.cn-qingdao.aliyuncs.com/wod/clair-adapter-photon:v2.1.1 && \
docker push registry.cn-qingdao.aliyuncs.com/wod/clair-adapter-photon:v2.1.1
# goharbor/trivy
docker pull goharbor/trivy-adapter-photon:v2.1.1 && \
docker tag goharbor/trivy-adapter-photon:v2.1.1 registry.cn-qingdao.aliyuncs.com/wod/trivy-adapter-photon:v2.1.1 && \
docker push registry.cn-qingdao.aliyuncs.com/wod/trivy-adapter-photon:v2.1.1
# goharbor/notary-server-photon # goharbor/notary-server-photon
docker pull goharbor/notary-server-photon:v0.6.1-v1.8.6 && \ docker pull goharbor/notary-server-photon:v2.1.1 && \
docker tag goharbor/notary-server-photon:v0.6.1-v1.8.6 registry.cn-qingdao.aliyuncs.com/wod/notary-server-photon:v0.6.1-v1.8.6 && \ docker tag goharbor/notary-server-photon:v2.1.1 registry.cn-qingdao.aliyuncs.com/wod/notary-server-photon:v2.1.1 && \
docker push registry.cn-qingdao.aliyuncs.com/wod/notary-server-photon:v0.6.1-v1.8.6 docker push registry.cn-qingdao.aliyuncs.com/wod/notary-server-photon:v2.1.1
# goharbor/notary-signer-photon # goharbor/notary-signer-photon
docker pull goharbor/notary-signer-photon:v0.6.1-v1.8.6 && \ docker pull goharbor/notary-signer-photon:v2.1.1 && \
docker tag goharbor/notary-signer-photon:v0.6.1-v1.8.6 registry.cn-qingdao.aliyuncs.com/wod/notary-signer-photon:v0.6.1-v1.8.6 && \ docker tag goharbor/notary-signer-photon:v2.1.1 registry.cn-qingdao.aliyuncs.com/wod/notary-signer-photon:v2.1.1 && \
docker push registry.cn-qingdao.aliyuncs.com/wod/notary-signer-photon:v0.6.1-v1.8.6 docker push registry.cn-qingdao.aliyuncs.com/wod/notary-signer-photon:v2.1.1
# redis # redis
docker pull redis:4.0.14-alpine && \ docker pull redis:4.0.14-alpine && \
...@@ -92,13 +101,13 @@ docker push registry.cn-qingdao.aliyuncs.com/wod/redis:4.0.14-alpine ...@@ -92,13 +101,13 @@ docker push registry.cn-qingdao.aliyuncs.com/wod/redis:4.0.14-alpine
```bash ```bash
# gitlab.wodcloud.com/cloud/awecloud-goharbor-harbor # gitlab.wodcloud.com/cloud/awecloud-goharbor-harbor
registry.cn-qingdao.aliyuncs.com/wod/awecloud-harbor-portal-arm64:v1.8.6 registry.cn-qingdao.aliyuncs.com/wod/awecloud-harbor-portal-arm64:v2.1.1
registry.cn-qingdao.aliyuncs.com/wod/awecloud-harbor-core-arm64:v1.8.6 registry.cn-qingdao.aliyuncs.com/wod/awecloud-harbor-core-arm64:v2.1.1
registry.cn-qingdao.aliyuncs.com/wod/awecloud-harbor-jobservice-arm64:v1.8.6 registry.cn-qingdao.aliyuncs.com/wod/awecloud-harbor-jobservice-arm64:v2.1.1
registry.cn-qingdao.aliyuncs.com/wod/awecloud-harbor-registryctl-arm64:v1.8.6 registry.cn-qingdao.aliyuncs.com/wod/awecloud-harbor-registryctl-arm64:v2.1.1
# gitlab.wodcloud.com/cloud/awecloud-goharbor-harbor-db # gitlab.wodcloud.com/cloud/awecloud-goharbor-harbor-db
registry.cn-qingdao.aliyuncs.com/wod/awecloud-harbor-db-arm64:v1.8.6 registry.cn-qingdao.aliyuncs.com/wod/awecloud-harbor-db-arm64:v2.1.1
# registry # registry
docker pull registry:2.7.1@sha256:df3e5e623e469600373cb327e8788e4eeb5e4a4c48e58461feb2b0d4c7f3c588 && \ docker pull registry:2.7.1@sha256:df3e5e623e469600373cb327e8788e4eeb5e4a4c48e58461feb2b0d4c7f3c588 && \
...@@ -106,14 +115,14 @@ docker tag registry:2.7.1@sha256:df3e5e623e469600373cb327e8788e4eeb5e4a4c48e5846 ...@@ -106,14 +115,14 @@ docker tag registry:2.7.1@sha256:df3e5e623e469600373cb327e8788e4eeb5e4a4c48e5846
docker push registry.cn-qingdao.aliyuncs.com/wod/registry-arm64:2.7.1 docker push registry.cn-qingdao.aliyuncs.com/wod/registry-arm64:2.7.1
# gitlab.wodcloud.com/cloud/chartmuseum # gitlab.wodcloud.com/cloud/chartmuseum
registry.cn-qingdao.aliyuncs.com/wod/awecloud-harbor-chartmuseum-arm64:v1.8.6 registry.cn-qingdao.aliyuncs.com/wod/awecloud-harbor-chartmuseum-arm64:v2.1.1
# gitlab.wodcloud.com/cloud/clair # gitlab.wodcloud.com/cloud/clair
registry.cn-qingdao.aliyuncs.com/wod/awecloud-harbor-clair-arm64:v1.8.6 registry.cn-qingdao.aliyuncs.com/wod/awecloud-harbor-clair-arm64:v2.1.1
# gitlab.wodcloud.com/cloud/notary # gitlab.wodcloud.com/cloud/notary
registry.cn-qingdao.aliyuncs.com/wod/awecloud-harbor-notary-server-arm64:v1.8.6 registry.cn-qingdao.aliyuncs.com/wod/awecloud-harbor-notary-server-arm64:v2.1.1
registry.cn-qingdao.aliyuncs.com/wod/awecloud-harbor-notary-signer-arm64:v1.8.6 registry.cn-qingdao.aliyuncs.com/wod/awecloud-harbor-notary-signer-arm64:v2.1.1
# redis # redis
docker pull redis:4.0.14-alpine@sha256:2c1fb6d8d5a7626b3c69a1a96f7f2471aece258e1e6d4a3d722ac65e486aba85 && \ docker pull redis:4.0.14-alpine@sha256:2c1fb6d8d5a7626b3c69a1a96f7f2471aece258e1e6d4a3d722ac65e486aba85 && \
......
This diff is collapsed.
clair:
database:
type: pgsql
options:
source: "{{ template "harbor.database.clair" . }}"
# Number of elements kept in the cache
# Values unlikely to change (e.g. namespaces) are cached in order to save prevent needless roundtrips to the database.
cachesize: 16384
api:
# API server port
port: 6060
healthport: 6061
# Deadline before an API request will respond with a 503
timeout: 300s
updater:
interval: {{ .Values.clair.updatersInterval }}h
{
"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
{
"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
# Harbor High Availability Guide ---
title: Harbor High Availability Guide
---
## Goal ## Goal
Deploy Harbor on K8S via helm to make it highly available, that is, if one of node that has Harbor's container running becomes un accessible. Users does not experience interrupt of service of Harbor. Deploy Harbor on K8S via helm to make it highly available, that is, if one of node that has Harbor's container running becomes un accessible. Users does not experience interrupt of service of Harbor.
## Prerequisites ## Prerequisites
- Kubernetes cluster 1.10+ - Kubernetes cluster 1.10+
- Helm 2.8.0+ - Helm 2.10.0+
- High available ingress controller (Harbor does not manage the external endpoint) - High available ingress controller (Harbor does not manage the external endpoint)
- High available PostgreSQL database (Harbor does not handle the deployment of HA of database) - High available PostgreSQL database (Harbor does not handle the deployment of HA of database)
- High available Redis (Harbor does not handle the deployment of HA of Redis) - High available Redis (Harbor does not handle the deployment of HA of Redis)
- PVC that can be shared across nodes or external object storage - PVC that can be shared across nodes or external object storage
## Architecture ## Architecture
Most of Harbor's components are stateless now. So we can simply increase the replica of the pods to make sure the components are distributed to multiple worker nodes, and leverage the "Service" mechanism of K8S to ensure the connectivity across pods. Most of Harbor's components are stateless now. So we can simply increase the replica of the pods to make sure the components are distributed to multiple worker nodes, and leverage the "Service" mechanism of K8S to ensure the connectivity across pods.
As for storage layer, it is expected that the user provide high available PostgreSQL, Redis cluster for application data and PVCs or object storage for storing images and charts. As for storage layer, it is expected that the user provide high available PostgreSQL, Redis cluster for application data and PVCs or object storage for storing images and charts.
![HA](img/ha.png) ![HA](img/ha.png)
## Installation ## Usage
### Download Chart ### Download Chart
Download Harbor helm chart code.
Download Harbor helm chart:
```bash ```bash
git clone https://github.com/goharbor/harbor-helm helm repo add harbor https://helm.goharbor.io
cd harbor-helm helm fetch harbor/harbor --untar
``` ```
### Configuration ### Configuration
Configure the followings items in `values.yaml`, you can also set them as parameters via `--set` flag during running `helm install`: Configure the followings items in `values.yaml`, you can also set them as parameters via `--set` flag during running `helm install`:
- **Ingress rule**
- **Ingress rule**
Configure the `expose.ingress.hosts.core` and `expose.ingress.hosts.notary`. Configure the `expose.ingress.hosts.core` and `expose.ingress.hosts.notary`.
- **External URL** - **External URL**
Configure the `externalURL`. Configure the `externalURL`.
- **External PostgreSQL** - **External PostgreSQL**
Set the `database.type` to `external` and fill the information in `database.external` section. Set the `database.type` to `external` and fill the information in `database.external` section.
Four empty databases should be created manually for `Harbor core`, `Clair`, `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`, `Clair`, `Notary server` and `Notary signer` and configure them in the section. Harbor will create tables automatically when starting up.
- **External Redis** - **External Redis**
Set the `redis.type` to `external` and fill the information in `redis.external` section. Set the `redis.type` to `external` and fill the information in `redis.external` section.
As the Redis client used by Harbor's upstream projects doesn't support `Sentinel`, Harbor can only work with a single entry point Redis. You can refer to this [guide](https://community.pivotal.io/s/article/How-to-setup-HAProxy-and-Redis-Sentinel-for-automatic-failover-between-Redis-Master-and-Slave-servers) to setup a HAProxy before the Redis to expose a single entry point. As the Redis client used by Harbor's upstream projects doesn't support `Sentinel`, Harbor can only work with a single entry point Redis. You can refer to this [guide](https://community.pivotal.io/s/article/How-to-setup-HAProxy-and-Redis-Sentinel-for-automatic-failover-between-Redis-Master-and-Slave-servers) to setup a HAProxy before the Redis to expose a single entry point.
- **Storage** - **Storage**
By default, a default `StorageClass` is needed in the K8S cluster to provision volumes to store images, charts and job logs. By default, a default `StorageClass` is needed in the K8S cluster to provision volumes to store images, charts and job logs.
If you want to specify the `StorageClass`, set `persistence.persistentVolumeClaim.registry.storageClass`, `persistence.persistentVolumeClaim.chartmuseum.storageClass` and `persistence.persistentVolumeClaim.jobservice.storageClass`. If you want to specify the `StorageClass`, set `persistence.persistentVolumeClaim.registry.storageClass`, `persistence.persistentVolumeClaim.chartmuseum.storageClass` and `persistence.persistentVolumeClaim.jobservice.storageClass`.
If you use `StorageClass`, for both default or specified one, set `persistence.persistentVolumeClaim.registry.accessMode`, `persistence.persistentVolumeClaim.chartmuseum.accessMode` and `persistence.persistentVolumeClaim.jobservice.accessMode` as `ReadWriteMany`, and make sure that the persistent volumes must can be shared cross different nodes. If you use `StorageClass`, for both default or specified one, set `persistence.persistentVolumeClaim.registry.accessMode`, `persistence.persistentVolumeClaim.chartmuseum.accessMode` and `persistence.persistentVolumeClaim.jobservice.accessMode` as `ReadWriteMany`, and make sure that the persistent volumes must can be shared cross different nodes.
You can also use the existing PVCs to store data, set `persistence.persistentVolumeClaim.registry.existingClaim`, `persistence.persistentVolumeClaim.chartmuseum.existingClaim` and `persistence.persistentVolumeClaim.jobservice.existingClaim`. You can also use the existing PVCs to store data, set `persistence.persistentVolumeClaim.registry.existingClaim`, `persistence.persistentVolumeClaim.chartmuseum.existingClaim` and `persistence.persistentVolumeClaim.jobservice.existingClaim`.
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.jobLogger` to `database`. 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.jobLogger` to `database`.
- **Replica** - **Replica**
Set `portal.replicas`, `core.replicas`, `jobservice.replicas`, `registry.replicas`, `chartmuseum.replicas`, `clair.replicas`, `notary.server.replicas` and `notary.signer.replicas` to `n`(`n`>=2). Set `portal.replicas`, `core.replicas`, `jobservice.replicas`, `registry.replicas`, `chartmuseum.replicas`, `clair.replicas`, `notary.server.replicas` and `notary.signer.replicas` to `n`(`n`>=2).
### Installation ### Installation
Install the Harbor helm chart with a release name `my-release`:
Install the Harbor helm chart with a release name `my-release`:
helm 2:
```bash ```bash
helm install --name my-release . helm install --name my-release .
``` ```
helm 3:
```
helm install my-release .
```
# Upgrade Guide ---
title: Upgrade Guide
---
This guide is used to upgrade Harbor deployed by chart since version 0.3.0. This guide is used to upgrade Harbor deployed by chart since version 0.3.0.
**Notes**: ## Notes
- As the database schema may change between different versions of Harbor, there is a progress to migrate the schema during the upgrade and the downtime cannot be avoid
- The database schema cannot be downgraded automatically, so the `helm rollback` is not supported - As the database schema may change between different versions of Harbor, there is a progress to migrate the schema during the upgrade and the downtime cannot be avoid
- The database schema cannot be downgraded automatically, so the `helm rollback` is not supported
## Upgrade ## Upgrade
1. **Backup database**
Backup the database used by Harbor in case the upgrade process fails. ### 1. Backup database
2. **Download new chart**
Download the latest version of Harbor chart. Backup the database used by Harbor in case the upgrade process fails.
3. **Configure new chart**
Configure the new chart to make sure that the configuration items have the same values with the old one. ### 2. Download new chart
**Note**: if TLS is enabled and the certificate is generated by chart automatically, a new certificate will be generated and overwrite the old one during the upgrade, this may cause some issues if you have distributed the certificate. You can follow the below steps to configure the new chart to use the old certificate: Download the latest version of Harbor chart.
1) Get the secret name which certificate is stored in: ### 3. Configure new chart
```
kubectl get secret Configure the new chart to make sure that the configuration items have the same values with the old one.
```
Find the secret whose name ends with `-harbor-ingress`(expose service via `Ingress`) or `-harbor-nginx`(expose service via `ClusterIP` or `NodePort`) > Note: if TLS is enabled and the certificate is generated by chart automatically, a new certificate will be generated and overwrite the old one during the upgrade, this may cause some issues if you have distributed the certificate. You can follow the below steps to configure the new chart to use the old certificate:
2) Export the secret as yaml file: 1) Get the secret name which certificate is stored in:
```
kubectl get secret secret-name -o yaml > secret.yaml ```bash
``` kubectl get secret
Replace the `secret-name` with the one got in step i
3) Rename the secret by setting `metadata.name` in `secret.yaml`
4) Create a new secret:
```
kubectl create -f secret.yaml
```
5) Configure the chart to use the new secret by setting `expose.tls.secretName` as the value you set in step iii
4. **Upgrade**
Run upgrade command:
``` ```
helm upgrade release-name --force .
``` Find the secret whose name ends with `-harbor-ingress` (expose service via `Ingress`) or `-harbor-nginx`(expose service via `ClusterIP` or `NodePort`)
The `--force` is necessary if upgrade from version 0.3.0 due to issue [#30](https://github.com/goharbor/harbor-helm/issues/30).
2) Export the secret as yaml file:
```bash
kubectl get secret <secret-name-from-step-1> -o yaml > secret.yaml
```
3) Rename the secret by setting `metadata.name` in `secret.yaml`
4) Create a new secret:
```bash
kubectl create -f secret.yaml
```
5) Configure the chart to use the new secret by setting `expose.tls.secretName` as the value you set in step **3**
### 4. Upgrade
Run upgrade command:
```bash
helm upgrade release-name --force .
```
> The `--force` is necessary if upgrade from version 0.3.0 due to issue [#30](https://github.com/goharbor/harbor-helm/issues/30).
## Known issues ## Known issues
- The job logs will be lost if you upgrade from version 0.3.0 as the logs are store in a `emptyDir` in 0.3.0.
- The job logs will be lost if you upgrade from version 0.3.0 as the logs are store in a `emptyDir` in 0.3.0.
---
title: Managing Harbor with Helm
weight: 50
---
This documentation focuses on deploying and managing Harbor via [Helm](https://helm.sh). For general documentation for Harbor, please see the [Harbor docs](https://goharbor.io/docs).
\ No newline at end of file
This diff is collapsed.
Please wait for several minutes for Harbor deployment to complete. Please wait for several minutes for Harbor deployment to complete.
Then you should be able to visit the Harbor portal at {{ .Values.externalURL }}. Then you should be able to visit the Harbor portal at {{ .Values.externalURL }}
For more details, please visit https://github.com/goharbor/harbor. For more details, please visit https://github.com/goharbor/harbor
\ No newline at end of file
This diff is collapsed.
...@@ -6,11 +6,23 @@ metadata: ...@@ -6,11 +6,23 @@ metadata:
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
data: data:
PORT: "9999" PORT: "{{ template "harbor.chartmuseum.containerPort" . }}"
{{- if .Values.internalTLS.enabled }}
TLS_CERT: "/etc/harbor/ssl/chartmuseum/tls.crt"
TLS_KEY: "/etc/harbor/ssl/chartmuseum/tls.key"
{{- end }}
{{- if eq "redis" (include "harbor.redis.scheme" .) }}
CACHE: "redis" CACHE: "redis"
CACHE_REDIS_ADDR: "{{ template "harbor.redis.host" . }}:{{ template "harbor.redis.port" . }}" {{- else }}
CACHE_REDIS_DB: "{{ template "harbor.redis.chartmuseumDatabaseIndex" . }}" CACHE: "redis_sentinel"
CACHE_REDIS_MASTERNAME: "{{ template "harbor.redis.masterSet" . }}"
{{- end }}
CACHE_REDIS_ADDR: "{{ template "harbor.redis.addr" . }}"
CACHE_REDIS_DB: "{{ template "harbor.redis.dbForChartmuseum" . }}"
BASIC_AUTH_USER: "chart_controller" BASIC_AUTH_USER: "chart_controller"
{{- if .Values.chartmuseum.absoluteUrl }}
CHART_URL: {{ .Values.externalURL }}/chartrepo
{{- end }}
DEPTH: "1" DEPTH: "1"
{{- if eq .Values.logLevel "debug" }} {{- if eq .Values.logLevel "debug" }}
DEBUG: "true" DEBUG: "true"
...@@ -22,10 +34,7 @@ data: ...@@ -22,10 +34,7 @@ data:
DISABLE_API: "false" DISABLE_API: "false"
DISABLE_STATEFILES: "false" DISABLE_STATEFILES: "false"
ALLOW_OVERWRITE: "true" ALLOW_OVERWRITE: "true"
#CHART_URL: {{ .Values.externalURL }}/chartrepo
AUTH_ANONYMOUS_GET: "false" AUTH_ANONYMOUS_GET: "false"
TLS_CERT: ""
TLS_KEY: ""
CONTEXT_PATH: "" CONTEXT_PATH: ""
INDEX_LIMIT: "0" INDEX_LIMIT: "0"
MAX_STORAGE_OBJECTS: "0" MAX_STORAGE_OBJECTS: "0"
...@@ -41,6 +50,7 @@ data: ...@@ -41,6 +50,7 @@ data:
STORAGE: "microsoft" STORAGE: "microsoft"
STORAGE_MICROSOFT_CONTAINER: {{ $storage.azure.container }} STORAGE_MICROSOFT_CONTAINER: {{ $storage.azure.container }}
AZURE_STORAGE_ACCOUNT: {{ $storage.azure.accountname }} AZURE_STORAGE_ACCOUNT: {{ $storage.azure.accountname }}
AZURE_BASE_URL: {{ $storage.azure.realm }}
STORAGE_MICROSOFT_PREFIX: "/azure/harbor/charts" STORAGE_MICROSOFT_PREFIX: "/azure/harbor/charts"
{{- else if eq $storageType "gcs" }} {{- else if eq $storageType "gcs" }}
STORAGE: "google" STORAGE: "google"
...@@ -62,36 +72,39 @@ data: ...@@ -62,36 +72,39 @@ data:
{{- if $storage.s3.accesskey }} {{- if $storage.s3.accesskey }}
AWS_ACCESS_KEY_ID: {{ $storage.s3.accesskey }} AWS_ACCESS_KEY_ID: {{ $storage.s3.accesskey }}
{{- end }} {{- end }}
{{- if $storage.s3.keyid }}
STORAGE_AMAZON_SSE: aws:kms
{{- end }}
{{- else if eq $storageType "swift" }} {{- else if eq $storageType "swift" }}
STORAGE: "openstack" STORAGE: "openstack"
STORAGE_OPENSTACK_CONTAINER: {{ $storage.swift.container }} STORAGE_OPENSTACK_CONTAINER: {{ $storage.swift.container }}
{{- if $storage.swift.secretkey }} {{- if $storage.swift.prefix }}
STORAGE_OPENSTACK_PREFIX: {{ $storage.swift.prefix }} STORAGE_OPENSTACK_PREFIX: {{ $storage.swift.prefix }}
{{- end }} {{- end }}
{{- if $storage.swift.secretkey }} {{- if $storage.swift.region }}
STORAGE_OPENSTACK_REGION: {{ $storage.swift.region }} STORAGE_OPENSTACK_REGION: {{ $storage.swift.region }}
{{- end }} {{- end }}
OS_AUTH_URL: {{ $storage.swift.authurl }} OS_AUTH_URL: {{ $storage.swift.authurl }}
OS_USERNAME: {{ $storage.swift.username }} OS_USERNAME: {{ $storage.swift.username }}
{{- if $storage.swift.secretkey }} {{- if $storage.swift.tenantid }}
OS_PROJECT_ID: {{ $storage.swift.tenantid }} OS_PROJECT_ID: {{ $storage.swift.tenantid }}
{{- end }} {{- end }}
{{- if $storage.swift.secretkey }} {{- if $storage.swift.tenant }}
OS_PROJECT_NAME: {{ $storage.swift.tenant }} OS_PROJECT_NAME: {{ $storage.swift.tenant }}
{{- end }} {{- end }}
{{- if $storage.swift.secretkey }} {{- if $storage.swift.domainid }}
OS_DOMAIN_ID: {{ $storage.swift.domainid }} OS_DOMAIN_ID: {{ $storage.swift.domainid }}
{{- end }} {{- end }}
{{- if $storage.swift.secretkey }} {{- if $storage.swift.domain }}
OS_DOMAIN_NAME: {{ $storage.swift.domain }} OS_DOMAIN_NAME: {{ $storage.swift.domain }}
{{- end }} {{- end }}
{{- else if eq $storageType "oss" }} {{- else if eq $storageType "oss" }}
STORAGE: "alibaba" STORAGE: "alibaba"
STORAGE_ALIBABA_BUCKET: {{ $storage.oss.bucket }} STORAGE_ALIBABA_BUCKET: {{ $storage.oss.bucket }}
{{- if $storage.oss.secretkey }} {{- if $storage.oss.rootdirectory }}
STORAGE_ALIBABA_PREFIX: {{ $storage.oss.rootdirectory }} STORAGE_ALIBABA_PREFIX: {{ $storage.oss.rootdirectory }}
{{- end }} {{- end }}
{{- if $storage.oss.secretkey }} {{- if $storage.oss.endpoint }}
STORAGE_ALIBABA_ENDPOINT: {{ $storage.oss.endpoint }} STORAGE_ALIBABA_ENDPOINT: {{ $storage.oss.endpoint }}
{{- end }} {{- end }}
ALIBABA_CLOUD_ACCESS_KEY_ID: {{ $storage.oss.accesskeyid }} ALIBABA_CLOUD_ACCESS_KEY_ID: {{ $storage.oss.accesskeyid }}
......
...@@ -5,26 +5,45 @@ metadata: ...@@ -5,26 +5,45 @@ metadata:
name: "{{ template "harbor.chartmuseum" . }}" name: "{{ template "harbor.chartmuseum" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
app: chartmuseum component: chartmuseum
spec: spec:
replicas: {{ .Values.chartmuseum.replicas }} replicas: {{ .Values.chartmuseum.replicas }}
strategy:
type: {{ .Values.updateStrategy.type }}
{{- if eq .Values.updateStrategy.type "Recreate" }}
rollingUpdate: null
{{- end }}
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
app: chartmuseum component: chartmuseum
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
app: chartmuseum component: chartmuseum
annotations: annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/chartmuseum/chartmuseum-cm.yaml") . | sha256sum }} checksum/configmap: {{ include (print $.Template.BasePath "/chartmuseum/chartmuseum-cm.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/chartmuseum/chartmuseum-secret.yaml") . | sha256sum }} checksum/secret: {{ include (print $.Template.BasePath "/chartmuseum/chartmuseum-secret.yaml") . | sha256sum }}
checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }} checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }}
{{- 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 "/chartmuseum/chartmuseum-tls.yaml") . | sha256sum }}
{{- end }}
{{- if .Values.chartmuseum.podAnnotations }} {{- if .Values.chartmuseum.podAnnotations }}
{{ toYaml .Values.chartmuseum.podAnnotations | indent 8 }} {{ toYaml .Values.chartmuseum.podAnnotations | indent 8 }}
{{- end }} {{- end }}
spec: spec:
securityContext:
fsGroup: 10000
{{- if .Values.chartmuseum.serviceAccountName }}
serviceAccountName: {{ .Values.chartmuseum.serviceAccountName }}
{{- end -}}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers: containers:
- name: chartmuseum - name: chartmuseum
image: {{ .Values.chartmuseum.image.repository }}:{{ .Values.chartmuseum.image.tag }} image: {{ .Values.chartmuseum.image.repository }}:{{ .Values.chartmuseum.image.tag }}
...@@ -32,13 +51,15 @@ spec: ...@@ -32,13 +51,15 @@ spec:
livenessProbe: livenessProbe:
httpGet: httpGet:
path: /health path: /health
port: 9999 scheme: {{ include "harbor.component.scheme" . | upper }}
initialDelaySeconds: 1 port: {{ template "harbor.chartmuseum.containerPort" . }}
initialDelaySeconds: 300
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
httpGet: httpGet:
path: /health path: /health
port: 9999 scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.chartmuseum.containerPort" . }}
initialDelaySeconds: 1 initialDelaySeconds: 1
periodSeconds: 10 periodSeconds: 10
{{- if .Values.chartmuseum.resources }} {{- if .Values.chartmuseum.resources }}
...@@ -51,30 +72,84 @@ spec: ...@@ -51,30 +72,84 @@ spec:
- secretRef: - secretRef:
name: "{{ template "harbor.chartmuseum" . }}" name: "{{ template "harbor.chartmuseum" . }}"
env: env:
{{- if has "chartmuseum" .Values.proxy.components }}
- name: HTTP_PROXY
value: "{{ .Values.proxy.httpProxy }}"
- name: HTTPS_PROXY
value: "{{ .Values.proxy.httpsProxy }}"
- name: NO_PROXY
value: "{{ template "harbor.noProxy" . }}"
{{- end }}
{{- if .Values.internalTLS.enabled }}
- name: INTERNAL_TLS_ENABLED
value: "true"
- name: INTERNAL_TLS_KEY_PATH
value: /etc/harbor/ssl/chartmuseum/tls.key
- name: INTERNAL_TLS_CERT_PATH
value: /etc/harbor/ssl/chartmuseum/tls.crt
- name: INTERNAL_TLS_TRUST_CA_PATH
value: /etc/harbor/ssl/chartmuseum/ca.crt
{{- end }}
- name: BASIC_AUTH_PASS - name: BASIC_AUTH_PASS
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: {{ template "harbor.core" . }} name: {{ template "harbor.core" . }}
key: secret key: secret
- # Needed to make AWS' client connect correctly (see https://github.com/helm/chartmuseum/issues/280)
name: AWS_SDK_LOAD_CONFIG
value: "1"
ports: ports:
- containerPort: 9999 - containerPort: {{ template "harbor.chartmuseum.containerPort" . }}
volumeMounts: volumeMounts:
- name: data - name: chartmuseum-data
mountPath: /chart_storage mountPath: /chart_storage
- name: etc-localtime subPath: {{ .Values.persistence.persistentVolumeClaim.chartmuseum.subPath }}
mountPath: /etc/localtime {{- if .Values.internalTLS.enabled }}
- name: chart-internal-certs
mountPath: /etc/harbor/ssl/chartmuseum
{{- end }}
{{- if and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "gcs") }}
- name: gcs-key
mountPath: /etc/chartmuseum/gcs-key.json
subPath: gcs-key.json
{{- end }}
{{- if .Values.persistence.imageChartStorage.caBundleSecretName }}
- name: storage-service-ca
mountPath: /harbor_cust_cert/custom-ca-bundle.crt
subPath: ca.crt
{{- end }}
{{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolumeMount" . | indent 8 }}
{{- end }}
volumes: volumes:
- name: etc-localtime - name: chartmuseum-data
hostPath: {{- if and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "filesystem") }}
path: /etc/localtime persistentVolumeClaim:
{{- if eq .Values.chartmuseum.storageSpec.type "hostPath" }} claimName: {{ .Values.persistence.persistentVolumeClaim.chartmuseum.existingClaim | default (include "harbor.chartmuseum" .) }}
- name: data {{- else }}
hostPath:
path: {{.Values.chartmuseum.storageSpec.hostPath.root | default "/data" }}/{{ .Release.Namespace }}/{{ .Release.Name }}/chartmuseum
{{- else if eq .Values.chartmuseum.storageSpec.type "emptyDir" }}
- name: data
emptyDir: {} emptyDir: {}
{{- end }} {{- end }}
{{- if .Values.internalTLS.enabled }}
- name: chart-internal-certs
secret:
secretName: {{ template "harbor.internalTLS.chartmuseum.secretName" . }}
{{- end }}
{{- if and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "gcs") }}
- name: gcs-key
secret:
secretName: {{ template "harbor.registry" . }}
items:
- key: GCS_KEY_DATA
path: gcs-key.json
{{- end }}
{{- if .Values.persistence.imageChartStorage.caBundleSecretName }}
- name: storage-service-ca
secret:
secretName: {{ .Values.persistence.imageChartStorage.caBundleSecretName }}
{{- end }}
{{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolume" . | indent 6 }}
{{- end }}
{{- with .Values.chartmuseum.nodeSelector }} {{- with .Values.chartmuseum.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
......
{{- if .Values.chartmuseum.enabled }}
{{- $persistence := .Values.persistence -}}
{{- if $persistence.enabled }}
{{- $chartmuseum := $persistence.persistentVolumeClaim.chartmuseum -}}
{{- if and (not $chartmuseum.existingClaim) (eq $persistence.imageChartStorage.type "filesystem") }}
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: {{ template "harbor.chartmuseum" . }}
{{- if eq $persistence.resourcePolicy "keep" }}
annotations:
helm.sh/resource-policy: keep
{{- end }}
labels:
{{ include "harbor.labels" . | indent 4 }}
component: chartmuseum
spec:
accessModes:
- {{ $chartmuseum.accessMode }}
resources:
requests:
storage: {{ $chartmuseum.size }}
{{- if $chartmuseum.storageClass }}
{{- if eq "-" $chartmuseum.storageClass }}
storageClassName: ""
{{- else }}
storageClassName: {{ $chartmuseum.storageClass }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
\ No newline at end of file
...@@ -7,7 +7,7 @@ metadata: ...@@ -7,7 +7,7 @@ metadata:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: Opaque type: Opaque
data: data:
CACHE_REDIS_PASSWORD: {{ include "harbor.redis.rawPassword" . | b64enc | quote }} CACHE_REDIS_PASSWORD: {{ include "harbor.redis.password" . | b64enc | quote }}
{{- $storage := .Values.persistence.imageChartStorage }} {{- $storage := .Values.persistence.imageChartStorage }}
{{- $storageType := $storage.type }} {{- $storageType := $storage.type }}
{{- if eq $storageType "azure" }} {{- if eq $storageType "azure" }}
......
...@@ -7,9 +7,9 @@ metadata: ...@@ -7,9 +7,9 @@ metadata:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
spec: spec:
ports: ports:
- port: 80 - port: {{ template "harbor.chartmuseum.servicePort" . }}
targetPort: 9999 targetPort: {{ template "harbor.chartmuseum.containerPort" . }}
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
app: chartmuseum component: chartmuseum
{{- end }} {{- end }}
\ No newline at end of file
{{- if and .Values.chartmuseum.enabled .Values.internalTLS.enabled }}
{{- if eq .Values.internalTLS.certSource "manual" }}
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.internalTLS.chartmuseum.secretName" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls
data:
tls.ca: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }}
tls.crt: {{ (required "The \"internalTLS.chartmuseum.crt\" is required!" .Values.internalTLS.chartmuseum.crt) | b64enc | quote }}
tls.key: {{ (required "The \"internalTLS.chartmuseum.key\" is required!" .Values.internalTLS.chartmuseum.key) | b64enc | quote }}
{{- end }}
{{- end }}
{{ if .Values.clair.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "harbor.clair" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
app: clair
data:
config.yaml: |
clair:
database:
type: pgsql
options:
source: "{{ template "harbor.database.clair" . }}"
# Number of elements kept in the cache
# Values unlikely to change (e.g. namespaces) are cached in order to save prevent needless roundtrips to the database.
cachesize: 16384
api:
# API server port
port: 6060
healthport: 6061
# Deadline before an API request will respond with a 503
timeout: 300s
updater:
interval: {{ .Values.clair.updatersInterval }}h
notifier:
attempts: 3
renotifyinterval: 2h
http:
endpoint: "http://{{ template "harbor.core" . }}/service/notifications/clair"
{{ end }}
...@@ -5,33 +5,47 @@ metadata: ...@@ -5,33 +5,47 @@ metadata:
name: {{ template "harbor.clair" . }} name: {{ template "harbor.clair" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
app: clair component: clair
spec: spec:
replicas: {{ .Values.clair.replicas }} replicas: {{ .Values.clair.replicas }}
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
app: clair component: clair
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
app: clair component: clair
annotations: annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/clair/clair-cm.yaml") . | sha256sum }} checksum/secret: {{ include (print $.Template.BasePath "/clair/clair-secret.yaml") . | sha256sum }}
{{- 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 "/clair/clair-tls.yaml") . | sha256sum }}
{{- end }}
{{- if .Values.clair.podAnnotations }} {{- if .Values.clair.podAnnotations }}
{{ toYaml .Values.clair.podAnnotations | indent 8 }} {{ toYaml .Values.clair.podAnnotations | indent 8 }}
{{- end }} {{- end }}
spec: spec:
securityContext:
fsGroup: 10000
{{- if .Values.clair.serviceAccountName }}
serviceAccountName: {{ .Values.clair.serviceAccountName }}
{{- end -}}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers: containers:
- name: clair - name: clair
image: {{ .Values.clair.image.repository }}:{{ .Values.clair.image.tag }} image: {{ .Values.clair.clair.image.repository }}:{{ .Values.clair.clair.image.tag }}
imagePullPolicy: {{ .Values.imagePullPolicy }} imagePullPolicy: {{ .Values.imagePullPolicy }}
livenessProbe: livenessProbe:
httpGet: httpGet:
path: /health path: /health
port: 6061 port: 6061
initialDelaySeconds: 30 initialDelaySeconds: 300
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
httpGet: httpGet:
...@@ -41,38 +55,102 @@ spec: ...@@ -41,38 +55,102 @@ spec:
periodSeconds: 10 periodSeconds: 10
args: ["-log-level", "{{ .Values.logLevel }}"] args: ["-log-level", "{{ .Values.logLevel }}"]
env: env:
{{- if .Values.clair.httpProxy }} {{- if has "clair" .Values.proxy.components }}
- name: HTTP_PROXY - name: HTTP_PROXY
value: {{ .Values.clair.httpProxy }} value: "{{ .Values.proxy.httpProxy }}"
{{- end }}
{{- if .Values.clair.httpsProxy }}
- name: HTTPS_PROXY - name: HTTPS_PROXY
value: {{ .Values.clair.httpsProxy }} value: "{{ .Values.proxy.httpsProxy }}"
{{- end }}
- name: NO_PROXY - name: NO_PROXY
value: "{{ template "harbor.registry" . }},{{ template "harbor.core" . }}" value: "{{ template "harbor.noProxy" . }}"
{{- if .Values.clair.resources }} {{- end }}
{{- if .Values.clair.clair.resources }}
resources: resources:
{{ toYaml .Values.clair.resources | indent 10 }} {{ toYaml .Values.clair.clair.resources | indent 10 }}
{{- end }} {{- end }}
ports: ports:
- containerPort: 6060 - containerPort: 6060
volumeMounts: volumeMounts:
- name: clair-config - name: config
mountPath: /etc/clair/config.yaml mountPath: /etc/clair/config.yaml
subPath: config.yaml subPath: config.yaml
- name: etc-localtime {{- if .Values.internalTLS.enabled }}
mountPath: /etc/localtime - name: clair-internal-certs
mountPath: /etc/harbor/ssl/clair
{{- end }}
{{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolumeMount" . | indent 8 }}
{{- end }}
- name: adapter
image: {{ .Values.clair.adapter.image.repository }}:{{ .Values.clair.adapter.image.tag }}
imagePullPolicy: {{ .Values.imagePullPolicy }}
livenessProbe:
httpGet:
path: /probe/healthy
scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.clairAdapter.containerPort" . }}
initialDelaySeconds: 300
periodSeconds: 10
readinessProbe:
httpGet:
path: /probe/ready
scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.clairAdapter.containerPort" . }}
initialDelaySeconds: 30
periodSeconds: 10
env:
- name: SCANNER_CLAIR_URL
# To avoid a pod cannot reach itself via service IP when the clusters disable hairpin
value: "http://127.0.0.1:6060"
- name: SCANNER_STORE_REDIS_URL
valueFrom:
secretKeyRef:
name: {{ template "harbor.clair" . }}
key: redis
- name: SCANNER_CLAIR_DATABASE_URL
valueFrom:
secretKeyRef:
name: {{ template "harbor.clair" . }}
key: database
{{- if .Values.internalTLS.enabled }}
- name: INTERNAL_TLS_ENABLED
value: "true"
- name: SCANNER_API_SERVER_ADDR
value: ":8443"
- name: SCANNER_API_SERVER_TLS_KEY
value: /etc/harbor/ssl/clair/tls.key
- name: SCANNER_API_SERVER_TLS_CERTIFICATE
value: /etc/harbor/ssl/clair/tls.crt
{{- end }}
- name: SCANNER_LOG_LEVEL
value: "{{ .Values.logLevel }}"
{{- if .Values.clair.adapter.resources }}
resources:
{{ toYaml .Values.clair.adapter.resources | indent 10 }}
{{- end }}
ports:
- containerPort: {{ template "harbor.clairAdapter.containerPort" . }}
{{- if or .Values.internalTLS.enabled .Values.caBundleSecretName }}
volumeMounts:
{{- if .Values.internalTLS.enabled }}
- name: clair-internal-certs
mountPath: /etc/harbor/ssl/clair
{{- end }}
{{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolumeMount" . | indent 8 }}
{{- end }}
{{- end }}
volumes: volumes:
- name: etc-localtime - name: config
hostPath: secret:
path: /etc/localtime secretName: "{{ template "harbor.clair" . }}"
- name: clair-config {{- if .Values.internalTLS.enabled }}
configMap: - name: clair-internal-certs
name: "{{ template "harbor.clair" . }}" secret:
items: secretName: {{ template "harbor.internalTLS.clair.secretName" . }}
- key: config.yaml {{- end }}
path: config.yaml {{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolume" . | indent 6 }}
{{- end }}
{{- with .Values.clair.nodeSelector }} {{- with .Values.clair.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
......
{{- if .Values.clair.enabled }}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "harbor.clair" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
type: Opaque
data:
config.yaml: {{ tpl (.Files.Get "conf/clair.yaml") . | b64enc }}
redis: {{ include "harbor.redis.urlForClair" . | b64enc }}
database: {{ include "harbor.database.clair" . | b64enc }}
{{- end }}
\ No newline at end of file
...@@ -7,11 +7,9 @@ metadata: ...@@ -7,11 +7,9 @@ metadata:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
spec: spec:
ports: ports:
- name: clair - name: adapter
port: 6060 port: {{ include "harbor.clairAdapter.servicePort" . }}
- name: health
port: 6061
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
app: clair component: clair
{{ end }} {{ end }}
{{- if and .Values.clair.enabled .Values.internalTLS.enabled }}
{{- if eq .Values.internalTLS.certSource "manual" }}
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.internalTLS.clair.secretName" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls
data:
ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }}
tls.crt: {{ (required "The \"internalTLS.clair.crt\" is required!" .Values.internalTLS.clair.crt) | b64enc | quote }}
tls.key: {{ (required "The \"internalTLS.clair.key\" is required!" .Values.internalTLS.clair.key) | b64enc | quote }}
{{- end }}
{{- end }}
\ No newline at end of file
...@@ -7,41 +7,53 @@ metadata: ...@@ -7,41 +7,53 @@ metadata:
data: data:
app.conf: |+ app.conf: |+
appname = Harbor appname = Harbor
runmode = dev runmode = prod
enablegzip = true enablegzip = true
[dev] [prod]
httpport = 8080 httpport = {{ ternary "8443" "8080" .Values.internalTLS.enabled }}
PORT: "{{ ternary "8443" "8080" .Values.internalTLS.enabled }}"
DATABASE_TYPE: "postgresql" DATABASE_TYPE: "postgresql"
POSTGRESQL_HOST: "{{ template "harbor.database.host" . }}" POSTGRESQL_HOST: "{{ template "harbor.database.host" . }}"
POSTGRESQL_PORT: "{{ template "harbor.database.port" . }}" POSTGRESQL_PORT: "{{ template "harbor.database.port" . }}"
POSTGRESQL_USERNAME: "{{ template "harbor.database.username" . }}" POSTGRESQL_USERNAME: "{{ template "harbor.database.username" . }}"
POSTGRESQL_DATABASE: "{{ template "harbor.database.coreDatabase" . }}" POSTGRESQL_DATABASE: "{{ template "harbor.database.coreDatabase" . }}"
POSTGRESQL_SSLMODE: "{{ template "harbor.database.sslmode" . }}" POSTGRESQL_SSLMODE: "{{ template "harbor.database.sslmode" . }}"
POSTGRESQL_MAX_IDLE_CONNS: "{{ .Values.database.maxIdleConns }}"
POSTGRESQL_MAX_OPEN_CONNS: "{{ .Values.database.maxOpenConns }}"
EXT_ENDPOINT: "{{ .Values.externalURL }}" EXT_ENDPOINT: "{{ .Values.externalURL }}"
CORE_URL: "http://{{ template "harbor.core" . }}" CORE_URL: "{{ template "harbor.coreURL" . }}"
JOBSERVICE_URL: "http://{{ template "harbor.fullname" . }}-jobservice" JOBSERVICE_URL: "{{ template "harbor.jobserviceURL" . }}"
REGISTRY_URL: "http://{{ template "harbor.registry" . }}:5000" REGISTRY_URL: "{{ template "harbor.registryURL" . }}"
TOKEN_SERVICE_URL: "http://{{ template "harbor.core" . }}/service/token" TOKEN_SERVICE_URL: "{{ template "harbor.tokenServiceURL" . }}"
WITH_NOTARY: "{{ .Values.notary.enabled }}" WITH_NOTARY: "{{ .Values.notary.enabled }}"
NOTARY_URL: "http://{{ template "harbor.notary-server" . }}:4443" NOTARY_URL: "http://{{ template "harbor.notary-server" . }}:4443"
CFG_EXPIRATION: "5" CORE_LOCAL_URL: "{{ ternary "https://127.0.0.1:8443" "http://127.0.0.1:8080" .Values.internalTLS.enabled }}"
WITH_CLAIR: "{{ .Values.clair.enabled }}" WITH_CLAIR: "{{ .Values.clair.enabled }}"
CLAIR_DB_HOST: "{{ template "harbor.database.host" . }}" CLAIR_ADAPTER_URL: "{{ template "harbor.clairAdapterURL" . }}"
CLAIR_DB_PORT: "{{ template "harbor.database.port" . }}" WITH_TRIVY: {{ .Values.trivy.enabled | quote }}
CLAIR_DB_USERNAME: "{{ template "harbor.database.username" . }}" TRIVY_ADAPTER_URL: "{{ template "harbor.trivyAdapterURL" . }}"
CLAIR_DB: "{{ template "harbor.database.clairDatabase" . }}"
CLAIR_DB_SSLMODE: "{{ template "harbor.database.sslmode" . }}"
CLAIR_URL: "http://{{ template "harbor.fullname" . }}-clair:6060"
REGISTRY_STORAGE_PROVIDER_NAME: "{{ .Values.persistence.imageChartStorage.type }}" REGISTRY_STORAGE_PROVIDER_NAME: "{{ .Values.persistence.imageChartStorage.type }}"
WITH_CHARTMUSEUM: "{{ .Values.chartmuseum.enabled }}" WITH_CHARTMUSEUM: "{{ .Values.chartmuseum.enabled }}"
CHART_REPOSITORY_URL: "http://{{ template "harbor.chartmuseum" . }}" CHART_REPOSITORY_URL: "{{ template "harbor.component.scheme" . }}://{{ template "harbor.chartmuseum" . }}"
LOG_LEVEL: "{{ .Values.logLevel }}" LOG_LEVEL: "{{ .Values.logLevel }}"
CONFIG_PATH: "/etc/core/app.conf" CONFIG_PATH: "/etc/core/app.conf"
SYNC_REGISTRY: "false"
CHART_CACHE_DRIVER: "redis" CHART_CACHE_DRIVER: "redis"
_REDIS_URL: "{{ template "harbor.redisForCore" . }}" _REDIS_URL_CORE: "{{ template "harbor.redis.urlForCore" . }}"
_REDIS_URL_REG: "{{ template "harbor.redisForGC" . }}" _REDIS_URL_REG: "{{ template "harbor.redis.urlForRegistry" . }}"
PORTAL_URL: "http://{{ template "harbor.portal" . }}" PORTAL_URL: "{{ template "harbor.portalURL" . }}"
REGISTRYCTL_URL: "http://{{ template "harbor.registry" . }}:8080" REGISTRY_CONTROLLER_URL: "{{ template "harbor.registryControllerURL" . }}"
CLAIR_HEALTH_CHECK_SERVER_URL: "http://{{ template "harbor.clair" . }}:6061" REGISTRY_CREDENTIAL_USERNAME: "{{ .Values.registry.credentials.username }}"
\ No newline at end of file {{- if .Values.uaaSecretName }}
UAA_CA_ROOT: "/etc/core/auth-ca/auth-ca.crt"
{{- end }}
{{- if has "core" .Values.proxy.components }}
HTTP_PROXY: "{{ .Values.proxy.httpProxy }}"
HTTPS_PROXY: "{{ .Values.proxy.httpsProxy }}"
NO_PROXY: "{{ template "harbor.noProxy" . }}"
{{- end }}
PERMITTED_REGISTRY_TYPES_FOR_PROXY_CACHE: "docker-hub,harbor"
{{- if hasKey .Values.core "gcTimeWindowHours" }}
#make the GC time window configurable for testing
GC_TIME_WINDOW_HOURS: "{{ .Values.core.gcTimeWindowHours }}"
{{- end }}
\ No newline at end of file
...@@ -4,41 +4,65 @@ metadata: ...@@ -4,41 +4,65 @@ metadata:
name: {{ template "harbor.core" . }} name: {{ template "harbor.core" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
app: core component: core
spec: spec:
replicas: {{ .Values.core.replicas }} replicas: {{ .Values.core.replicas }}
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
app: core component: core
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.matchLabels" . | indent 8 }} {{ include "harbor.matchLabels" . | indent 8 }}
app: core component: core
annotations: annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/core/core-cm.yaml") . | sha256sum }} checksum/configmap: {{ include (print $.Template.BasePath "/core/core-cm.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }} checksum/secret: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }}
checksum/secret-jobservice: {{ include (print $.Template.BasePath "/jobservice/jobservice-secrets.yaml") . | sha256sum }} checksum/secret-jobservice: {{ include (print $.Template.BasePath "/jobservice/jobservice-secrets.yaml") . | sha256sum }}
{{- 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.core.podAnnotations }} {{- if .Values.core.podAnnotations }}
{{ toYaml .Values.core.podAnnotations | indent 8 }} {{ toYaml .Values.core.podAnnotations | indent 8 }}
{{- end }} {{- end }}
spec: spec:
securityContext:
fsGroup: 10000
{{- if .Values.core.serviceAccountName }}
serviceAccountName: {{ .Values.core.serviceAccountName }}
{{- end -}}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers: containers:
- name: core - name: core
image: {{ .Values.core.image.repository }}:{{ .Values.core.image.tag }} image: {{ .Values.core.image.repository }}:{{ .Values.core.image.tag }}
imagePullPolicy: {{ .Values.imagePullPolicy }} imagePullPolicy: {{ .Values.imagePullPolicy }}
startupProbe:
httpGet:
path: /api/v2.0/ping
scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.core.containerPort" . }}
failureThreshold: 360
initialDelaySeconds: {{ .Values.core.startupProbe.initialDelaySeconds }}
periodSeconds: 10
livenessProbe: livenessProbe:
httpGet: httpGet:
path: /api/ping path: /api/v2.0/ping
port: 8080 scheme: {{ include "harbor.component.scheme" . | upper }}
initialDelaySeconds: 20 port: {{ template "harbor.core.containerPort" . }}
failureThreshold: 2
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
httpGet: httpGet:
path: /api/ping path: /api/v2.0/ping
port: 8080 scheme: {{ include "harbor.component.scheme" . | upper }}
initialDelaySeconds: 20 port: {{ template "harbor.core.containerPort" . }}
failureThreshold: 2
periodSeconds: 10 periodSeconds: 10
envFrom: envFrom:
- configMapRef: - configMapRef:
...@@ -55,12 +79,20 @@ spec: ...@@ -55,12 +79,20 @@ spec:
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: "{{ template "harbor.jobservice" . }}" name: "{{ template "harbor.jobservice" . }}"
key: secret key: JOBSERVICE_SECRET
{{- if .Values.internalTLS.enabled }}
- name: INTERNAL_TLS_ENABLED
value: "true"
- name: INTERNAL_TLS_KEY_PATH
value: /etc/harbor/ssl/core/tls.key
- name: INTERNAL_TLS_CERT_PATH
value: /etc/harbor/ssl/core/tls.crt
- name: INTERNAL_TLS_TRUST_CA_PATH
value: /etc/harbor/ssl/core/ca.crt
{{- end }}
ports: ports:
- containerPort: 8080 - containerPort: {{ template "harbor.core.containerPort" . }}
volumeMounts: volumeMounts:
- name: etc-localtime
mountPath: /etc/localtime
- name: config - name: config
mountPath: /etc/core/app.conf mountPath: /etc/core/app.conf
subPath: app.conf subPath: app.conf
...@@ -72,22 +104,33 @@ spec: ...@@ -72,22 +104,33 @@ spec:
subPath: tls.key subPath: tls.key
{{- if .Values.expose.tls.enabled }} {{- if .Values.expose.tls.enabled }}
- name: ca-download - name: ca-download
mountPath: /etc/core/ca/ca.crt mountPath: /etc/core/ca
subPath: ca.crt {{- end }}
{{- if .Values.uaaSecretName }}
- name: auth-ca-cert
mountPath: /etc/core/auth-ca/auth-ca.crt
subPath: auth-ca.crt
{{- end }}
{{- if .Values.internalTLS.enabled }}
- name: core-internal-certs
mountPath: /etc/harbor/ssl/core
{{- end }} {{- end }}
- name: psc - name: psc
mountPath: /etc/core/token mountPath: /etc/core/token
{{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolumeMount" . | indent 8 }}
{{- end }}
{{- if .Values.core.resources }} {{- if .Values.core.resources }}
resources: resources:
{{ toYaml .Values.core.resources | indent 10 }} {{ toYaml .Values.core.resources | indent 10 }}
{{- end }} {{- end }}
volumes: volumes:
- name: etc-localtime
hostPath:
path: /etc/localtime
- name: config - name: config
configMap: configMap:
name: {{ template "harbor.core" . }} name: {{ template "harbor.core" . }}
items:
- key: app.conf
path: app.conf
- name: secret-key - name: secret-key
secret: secret:
secretName: {{ template "harbor.core" . }} secretName: {{ template "harbor.core" . }}
...@@ -104,19 +147,32 @@ spec: ...@@ -104,19 +147,32 @@ spec:
{{- if .Values.expose.tls.enabled }} {{- if .Values.expose.tls.enabled }}
- name: ca-download - name: ca-download
secret: secret:
{{- if eq (include "harbor.autoGenCertForIngress" .) "true" }} {{- if .Values.caSecretName }}
secretName: {{ .Values.caSecretName }}
{{- else if eq (include "harbor.autoGenCertForIngress" .) "true" }}
secretName: "{{ template "harbor.ingress" . }}" secretName: "{{ template "harbor.ingress" . }}"
{{- else if eq (include "harbor.autoGenCertForNginx" .) "true" }} {{- else if eq (include "harbor.autoGenCertForNginx" .) "true" }}
secretName: {{ template "harbor.nginx" . }} secretName: {{ template "harbor.tlsSecretForNginx" . }}
{{- else }}
secretName: {{ .Values.expose.tls.secretName }}
{{- end }} {{- end }}
{{- end }}
{{- if .Values.uaaSecretName }}
- name: auth-ca-cert
secret:
secretName: {{ .Values.uaaSecretName }}
items: items:
- key: ca.crt - key: ca.crt
path: ca.crt path: auth-ca.crt
{{- end }}
{{- if .Values.internalTLS.enabled }}
- name: core-internal-certs
secret:
secretName: {{ template "harbor.internalTLS.core.secretName" . }}
{{- end }} {{- end }}
- name: psc - name: psc
emptyDir: {} emptyDir: {}
{{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolume" . | indent 6 }}
{{- end }}
{{- with .Values.core.nodeSelector }} {{- with .Values.core.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
......
...@@ -14,6 +14,5 @@ data: ...@@ -14,6 +14,5 @@ data:
{{- end }} {{- end }}
HARBOR_ADMIN_PASSWORD: {{ .Values.harborAdminPassword | b64enc | quote }} HARBOR_ADMIN_PASSWORD: {{ .Values.harborAdminPassword | b64enc | quote }}
POSTGRESQL_PASSWORD: {{ template "harbor.database.encryptedPassword" . }} POSTGRESQL_PASSWORD: {{ template "harbor.database.encryptedPassword" . }}
{{- if .Values.clair.enabled }} REGISTRY_CREDENTIAL_PASSWORD: {{ .Values.registry.credentials.password | b64enc | quote }}
CLAIR_DB_PASSWORD: {{ template "harbor.database.encryptedPassword" . }} CSRF_KEY: {{ .Values.core.xsrfKey | default (randAlphaNum 32) | b64enc | quote }}
{{- end }}
\ No newline at end of file
...@@ -9,8 +9,8 @@ spec: ...@@ -9,8 +9,8 @@ spec:
type: NodePort type: NodePort
{{- end }} {{- end }}
ports: ports:
- port: 80 - port: {{ template "harbor.core.servicePort" . }}
targetPort: 8080 targetPort: {{ template "harbor.core.containerPort" . }}
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
app: core component: core
{{- if and .Values.internalTLS.enabled }}
{{- if eq .Values.internalTLS.certSource "manual" }}
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.internalTLS.core.secretName" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls
data:
ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }}
tls.crt: {{ (required "The \"internalTLS.core.crt\" is required!" .Values.internalTLS.core.crt) | b64enc | quote }}
tls.key: {{ (required "The \"internalTLS.core.key\" is required!" .Values.internalTLS.core.key) | b64enc | quote }}
{{- end }}
{{- end }}
\ No newline at end of file
...@@ -6,36 +6,52 @@ metadata: ...@@ -6,36 +6,52 @@ metadata:
name: "{{ template "harbor.database" . }}" name: "{{ template "harbor.database" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
app: database component: database
spec: spec:
replicas: 1 replicas: 1
serviceName: "{{ template "harbor.database" . }}" serviceName: "{{ template "harbor.database" . }}"
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
app: database component: database
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
app: database component: database
annotations: annotations:
checksum/secret: {{ include (print $.Template.BasePath "/database/database-secret.yaml") . | sha256sum }} checksum/secret: {{ include (print $.Template.BasePath "/database/database-secret.yaml") . | sha256sum }}
{{- if .Values.database.podAnnotations }} {{- if .Values.database.podAnnotations }}
{{ toYaml .Values.database.podAnnotations | indent 8 }} {{ toYaml .Values.database.podAnnotations | indent 8 }}
{{- end }} {{- end }}
spec: spec:
tolerations: {{- if .Values.database.internal.serviceAccountName }}
- effect: NoSchedule serviceAccountName: {{ .Values.database.internal.serviceAccountName }}
operator: Exists {{- end -}}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
initContainers: initContainers:
- name: "change-permission-of-directory"
securityContext:
runAsUser: 0
image: {{ .Values.database.internal.image.repository }}:{{ .Values.database.internal.image.tag }}
imagePullPolicy: {{ .Values.imagePullPolicy }}
command: ["/bin/sh"]
args: ["-c", "chown -R postgres:postgres /var/lib/postgresql/data"]
volumeMounts:
- name: database-data
mountPath: /var/lib/postgresql/data
subPath: {{ $database.subPath }}
- name: "remove-lost-found" - name: "remove-lost-found"
image: {{ .Values.database.internal.image.repository }}:{{ .Values.database.internal.image.tag }} image: {{ .Values.database.internal.image.repository }}:{{ .Values.database.internal.image.tag }}
imagePullPolicy: {{ .Values.imagePullPolicy }} imagePullPolicy: {{ .Values.imagePullPolicy }}
command: ["rm", "-Rf", "/var/lib/postgresql/data/lost+found"] command: ["rm", "-Rf", "/var/lib/postgresql/data/lost+found"]
volumeMounts: volumeMounts:
- name: data - name: database-data
mountPath: /var/lib/postgresql/data mountPath: /var/lib/postgresql/data
subPath: {{ $database.subPath }}
containers: containers:
- name: database - name: database
image: {{ .Values.database.internal.image.repository }}:{{ .Values.database.internal.image.tag }} image: {{ .Values.database.internal.image.repository }}:{{ .Values.database.internal.image.tag }}
...@@ -44,7 +60,7 @@ spec: ...@@ -44,7 +60,7 @@ spec:
exec: exec:
command: command:
- /docker-healthcheck.sh - /docker-healthcheck.sh
initialDelaySeconds: 60 initialDelaySeconds: 300
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
exec: exec:
...@@ -60,22 +76,19 @@ spec: ...@@ -60,22 +76,19 @@ spec:
- secretRef: - secretRef:
name: "{{ template "harbor.database" . }}" name: "{{ template "harbor.database" . }}"
volumeMounts: volumeMounts:
- name: etc-localtime - name: database-data
mountPath: /etc/localtime
- name: data
mountPath: /var/lib/postgresql/data mountPath: /var/lib/postgresql/data
subPath: {{ $database.subPath }}
{{- if not .Values.persistence.enabled }}
volumes: volumes:
- name: etc-localtime - name: "database-data"
hostPath:
path: /etc/localtime
{{- if eq .Values.database.internal.storageSpec.type "hostPath" }}
- name: data
hostPath:
path: {{.Values.database.internal.storageSpec.hostPath.root | default "/data" }}/{{ .Release.Namespace }}/{{ .Release.Name }}/database
{{- else if eq .Values.database.internal.storageSpec.type "emptyDir" }}
- name: data
emptyDir: {} emptyDir: {}
{{- end }} {{- else if $database.existingClaim }}
volumes:
- name: "database-data"
persistentVolumeClaim:
claimName: {{ $database.existingClaim }}
{{- end -}}
{{- with .Values.database.internal.nodeSelector }} {{- with .Values.database.internal.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
...@@ -88,14 +101,23 @@ spec: ...@@ -88,14 +101,23 @@ spec:
tolerations: tolerations:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- if eq .Values.database.internal.storageSpec.type "volumeClaimTemplate" }} {{- if and .Values.persistence.enabled (not $database.existingClaim) }}
volumeClaimTemplates: volumeClaimTemplates:
- metadata: - metadata:
name: "data" name: "database-data"
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
app: database
spec: spec:
{{ toYaml $.Values.database.internal.storageSpec.volumeClaimTemplate.spec | indent 6 }} accessModes: [{{ $database.accessMode | quote }}]
{{- end }} {{- if $database.storageClass }}
{{- end -}} {{- if (eq "-" $database.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: "{{ $database.storageClass }}"
{{- end }}
{{- end }}
resources:
requests:
storage: {{ $database.size | quote }}
{{- end -}}
{{- end -}}
...@@ -10,5 +10,5 @@ spec: ...@@ -10,5 +10,5 @@ spec:
- port: 5432 - port: 5432
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
app: database component: database
{{- end -}} {{- end -}}
\ No newline at end of file
...@@ -8,13 +8,15 @@ ...@@ -8,13 +8,15 @@
{{- $_ := set . "v2_path" "/v2/*" -}} {{- $_ := set . "v2_path" "/v2/*" -}}
{{- $_ := set . "chartrepo_path" "/chartrepo/*" -}} {{- $_ := set . "chartrepo_path" "/chartrepo/*" -}}
{{- $_ := set . "controller_path" "/c/*" -}} {{- $_ := set . "controller_path" "/c/*" -}}
{{- $_ := set . "notary_path" "/" -}}
{{- else if eq .Values.expose.ingress.controller "ncp" }} {{- else if eq .Values.expose.ingress.controller "ncp" }}
{{- $_ := set . "portal_path" "/" -}} {{- $_ := set . "portal_path" "/.*" -}}
{{- $_ := set . "api_path" "/api/.*" -}} {{- $_ := set . "api_path" "/api/.*" -}}
{{- $_ := set . "service_path" "/service/.*" -}} {{- $_ := set . "service_path" "/service/.*" -}}
{{- $_ := set . "v2_path" "/v2/.*" -}} {{- $_ := set . "v2_path" "/v2/.*" -}}
{{- $_ := set . "chartrepo_path" "/chartrepo/.*" -}} {{- $_ := set . "chartrepo_path" "/chartrepo/.*" -}}
{{- $_ := set . "controller_path" "/c/.*" -}} {{- $_ := set . "controller_path" "/c/.*" -}}
{{- $_ := set . "notary_path" "/.*" -}}
{{- else }} {{- else }}
{{- $_ := set . "portal_path" "/" -}} {{- $_ := set . "portal_path" "/" -}}
{{- $_ := set . "api_path" "/api/" -}} {{- $_ := set . "api_path" "/api/" -}}
...@@ -22,8 +24,15 @@ ...@@ -22,8 +24,15 @@
{{- $_ := set . "v2_path" "/v2/" -}} {{- $_ := set . "v2_path" "/v2/" -}}
{{- $_ := set . "chartrepo_path" "/chartrepo/" -}} {{- $_ := set . "chartrepo_path" "/chartrepo/" -}}
{{- $_ := set . "controller_path" "/c/" -}} {{- $_ := set . "controller_path" "/c/" -}}
{{- $_ := set . "notary_path" "/" -}}
{{- end }} {{- end }}
---
{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion }}
apiVersion: extensions/v1beta1 apiVersion: extensions/v1beta1
{{- else }}
apiVersion: networking.k8s.io/v1beta1
{{- end }}
kind: Ingress kind: Ingress
metadata: metadata:
name: "{{ template "harbor.ingress" . }}" name: "{{ template "harbor.ingress" . }}"
...@@ -31,36 +40,23 @@ metadata: ...@@ -31,36 +40,23 @@ metadata:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
annotations: annotations:
{{ toYaml $ingress.annotations | indent 4 }} {{ toYaml $ingress.annotations | indent 4 }}
{{- if .Values.internalTLS.enabled }}
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
{{- end }}
{{- if eq .Values.expose.ingress.controller "ncp" }}
ncp/use-regex: "true"
{{- if $tls.enabled }}
ncp/http-redirect: "true"
{{- end }}
{{- end }}
spec: spec:
{{- if $tls.enabled }} {{- if $tls.enabled }}
tls: tls:
{{- if $tls.secretName }} - secretName: {{ template "harbor.tlsCoreSecretForIngress" . }}
- secretName: {{ $tls.secretName }}
{{- else }}
- secretName: "{{ template "harbor.ingress" . }}"
{{- end }}
{{- if $ingress.hosts.core }} {{- if $ingress.hosts.core }}
hosts: hosts:
- {{ $ingress.hosts.core }} - {{ $ingress.hosts.core }}
{{- end }} {{- end }}
{{- if .Values.notary.enabled }}
{{- if $tls.notarySecretName }}
- secretName: {{ $tls.notarySecretName }}
{{- else if $tls.secretName }}
- secretName: {{ $tls.secretName }}
{{- else }}
- secretName: "{{ template "harbor.ingress" . }}"
{{- end }}
{{- if $ingress.hosts.notary }}
hosts:
- {{ $ingress.hosts.notary }}
{{- end }}
{{- end }}
{{- end }}
{{- if eq .Values.expose.ingress.controller "ncp" }}
backend:
serviceName: {{ template "harbor.portal" . }}
servicePort: 80
{{- end }} {{- end }}
rules: rules:
- http: - http:
...@@ -68,130 +64,70 @@ spec: ...@@ -68,130 +64,70 @@ spec:
- path: {{ .portal_path }} - path: {{ .portal_path }}
backend: backend:
serviceName: {{ template "harbor.portal" . }} serviceName: {{ template "harbor.portal" . }}
servicePort: 80 servicePort: {{ template "harbor.portal.servicePort" . }}
- path: {{ .api_path }} - path: {{ .api_path }}
backend: backend:
serviceName: {{ template "harbor.core" . }} serviceName: {{ template "harbor.core" . }}
servicePort: 80 servicePort: {{ template "harbor.core.servicePort" . }}
- path: {{ .service_path }} - path: {{ .service_path }}
backend: backend:
serviceName: {{ template "harbor.core" . }} serviceName: {{ template "harbor.core" . }}
servicePort: 80 servicePort: {{ template "harbor.core.servicePort" . }}
- path: {{ .v2_path }} - path: {{ .v2_path }}
backend: backend:
serviceName: {{ template "harbor.core" . }} serviceName: {{ template "harbor.core" . }}
servicePort: 80 servicePort: {{ template "harbor.core.servicePort" . }}
- path: {{ .chartrepo_path }} - path: {{ .chartrepo_path }}
backend: backend:
serviceName: {{ template "harbor.core" . }} serviceName: {{ template "harbor.core" . }}
servicePort: 80 servicePort: {{ template "harbor.core.servicePort" . }}
- path: {{ .controller_path }} - path: {{ .controller_path }}
backend: backend:
serviceName: {{ template "harbor.core" . }} serviceName: {{ template "harbor.core" . }}
servicePort: 80 servicePort: {{ template "harbor.core.servicePort" . }}
{{- if $ingress.hosts.core }} {{- if $ingress.hosts.core }}
host: {{ $ingress.hosts.core }} host: {{ $ingress.hosts.core }}
{{- end }} {{- end }}
{{- if .Values.notary.enabled }}
{{- if .Values.notary.enabled }}
---
{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion }}
apiVersion: extensions/v1beta1
{{- else }}
apiVersion: networking.k8s.io/v1beta1
{{- end }}
kind: Ingress
metadata:
name: "{{ template "harbor.ingress-notary" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
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 }}
spec:
{{- if $tls.enabled }}
tls:
- secretName: {{ template "harbor.tlsNotarySecretForIngress" . }}
{{- if $ingress.hosts.notary }}
hosts:
- {{ $ingress.hosts.notary }}
{{- end }}
{{- end }}
rules:
- http: - http:
paths: paths:
- path: / - path: {{ .notary_path }}
backend: backend:
serviceName: {{ template "harbor.notary-server" . }} serviceName: {{ template "harbor.notary-server" . }}
servicePort: 4443 servicePort: 4443
{{- if $ingress.hosts.notary }} {{- if $ingress.hosts.notary }}
host: {{ $ingress.hosts.notary }} host: {{ $ingress.hosts.notary }}
{{- end }} {{- end }}
{{- end }}
{{- end }} {{- end }}
---
apiVersion: bcc.bd-apaas.com/v1alpha1 {{- end }}
kind: IngressRoute
metadata:
name: harbor-ingress
namespace: {{ .Release.Namespace }}
spec:
entryPoints:
- websecure
routes:
- kind: Rule
match: Host(`{{ .Values.expose.ingress.hosts.core }}`) && PathPrefix(`/`)
middlewares: []
priority: 0
services:
- kind: Service
name: harbor-portal
namespace: devops
port: 80
- kind: Rule
match: Host(`{{ .Values.expose.ingress.hosts.core }}`) && PathPrefix(`/api/`)
middlewares: []
priority: 0
services:
- kind: Service
name: harbor-core
namespace: devops
port: 80
- kind: Rule
match: Host(`{{ .Values.expose.ingress.hosts.core }}`) && PathPrefix(`/service/`)
middlewares: []
priority: 0
services:
- kind: Service
name: harbor-core
namespace: devops
port: 80
- kind: Rule
match: Host(`{{ .Values.expose.ingress.hosts.core }}`) && PathPrefix(`/v2/`)
middlewares: []
priority: 0
services:
- kind: Service
name: harbor-core
namespace: devops
port: 80
- kind: Rule
match: Host(`{{ .Values.expose.ingress.hosts.core }}`) && PathPrefix(`/chartrepo/`)
middlewares: []
priority: 0
services:
- kind: Service
name: harbor-core
namespace: devops
port: 80
- kind: Rule
match: Host(`{{ .Values.expose.ingress.hosts.core }}`) && PathPrefix(`/c/`)
middlewares: []
priority: 0
services:
- kind: Service
name: harbor-core
namespace: devops
port: 80
- kind: Rule
match: Host(`{{ .Values.expose.ingress.hosts.notary }}`) && PathPrefix(`/`)
middlewares: []
priority: 0
services:
- kind: Service
name: harbor-notary-server
namespace: devops
port: 4443
tls:
certResolver: default
---
apiVersion: bcc.bd-apaas.com/v1alpha1
kind: IngressHost
metadata:
name: harbor-core
namespace: {{ .Release.Namespace }}
spec:
host: {{ .Values.expose.ingress.hosts.core }}
---
apiVersion: bcc.bd-apaas.com/v1alpha1
kind: IngressHost
metadata:
name: harbor-natory
namespace: {{ .Release.Namespace }}
spec:
host: {{ .Values.expose.ingress.hosts.notary }}
\ No newline at end of file
{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }}
{{- $ca := genCA "harbor-internal-ca" 365 }}
{{- $coreCN := (include "harbor.core" .) }}
{{- $coreCrt := genSignedCert $coreCN (list "127.0.0.1") (list "localhost" $coreCN) 365 $ca }}
{{- $jsCN := (include "harbor.jobservice" .) }}
{{- $jsCrt := genSignedCert $jsCN nil (list $jsCN) 365 $ca }}
{{- $regCN := (include "harbor.registry" .) }}
{{- $regCrt := genSignedCert $regCN nil (list $regCN) 365 $ca }}
{{- $portalCN := (include "harbor.portal" .) }}
{{- $portalCrt := genSignedCert $portalCN nil (list $portalCN) 365 $ca }}
---
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.internalTLS.core.secretName" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls
data:
ca.crt: {{ $ca.Cert | b64enc | quote }}
tls.crt: {{ $coreCrt.Cert | b64enc | quote }}
tls.key: {{ $coreCrt.Key | b64enc | quote }}
---
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.internalTLS.jobservice.secretName" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls
data:
ca.crt: {{ $ca.Cert | b64enc | quote }}
tls.crt: {{ $jsCrt.Cert | b64enc | quote }}
tls.key: {{ $jsCrt.Key | b64enc | quote }}
---
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.internalTLS.registry.secretName" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls
data:
ca.crt: {{ $ca.Cert | b64enc | quote }}
tls.crt: {{ $regCrt.Cert | b64enc | quote }}
tls.key: {{ $regCrt.Key | b64enc | quote }}
---
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.internalTLS.portal.secretName" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls
data:
ca.crt: {{ $ca.Cert | b64enc | quote }}
tls.crt: {{ $portalCrt.Cert | b64enc | quote }}
tls.key: {{ $portalCrt.Key | b64enc | quote }}
{{- if .Values.chartmuseum.enabled }}
---
{{- $chartCN := (include "harbor.chartmuseum" .) }}
{{- $chartCrt := genSignedCert $chartCN nil (list $chartCN) 365 $ca }}
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.internalTLS.chartmuseum.secretName" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls
data:
ca.crt: {{ $ca.Cert | b64enc | quote }}
tls.crt: {{ $chartCrt.Cert | b64enc | quote }}
tls.key: {{ $chartCrt.Key | b64enc | quote }}
{{- end }}
{{- if .Values.clair.enabled }}
---
{{- $clairCN := (include "harbor.clair" .) }}
{{- $clairCrt := genSignedCert $clairCN nil (list $clairCN) 365 $ca }}
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.internalTLS.clair.secretName" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls
data:
ca.crt: {{ $ca.Cert | b64enc | quote }}
tls.crt: {{ $clairCrt.Cert | b64enc | quote }}
tls.key: {{ $clairCrt.Key | b64enc | quote }}
{{- end }}
{{- if and .Values.trivy.enabled}}
---
{{- $trivyCN := (include "harbor.trivy" .) }}
{{- $trivyCrt := genSignedCert $trivyCN nil (list $trivyCN) 365 $ca }}
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.internalTLS.trivy.secretName" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls
data:
ca.crt: {{ $ca.Cert | b64enc | quote }}
tls.crt: {{ $trivyCrt.Cert | b64enc | quote }}
tls.key: {{ $trivyCrt.Key | b64enc | quote }}
{{- end }}
{{- end }}
\ No newline at end of file
apiVersion: v1
kind: ConfigMap
metadata:
name: "{{ template "harbor.jobservice" . }}-env"
labels:
{{ include "harbor.labels" . | indent 4 }}
data:
CORE_URL: "{{ template "harbor.coreURL" . }}"
TOKEN_SERVICE_URL: "{{ template "harbor.tokenServiceURL" . }}"
REGISTRY_URL: "{{ template "harbor.registryURL" . }}"
REGISTRY_CONTROLLER_URL: "{{ template "harbor.registryControllerURL" . }}"
REGISTRY_CREDENTIAL_USERNAME: "{{ .Values.registry.credentials.username }}"
{{- if has "jobservice" .Values.proxy.components }}
HTTP_PROXY: "{{ .Values.proxy.httpProxy }}"
HTTPS_PROXY: "{{ .Values.proxy.httpsProxy }}"
NO_PROXY: "{{ template "harbor.noProxy" . }}"
{{- end }}
...@@ -6,14 +6,21 @@ metadata: ...@@ -6,14 +6,21 @@ metadata:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
data: data:
config.yml: |+ config.yml: |+
protocol: "http" #Server listening port
port: 8080 protocol: "{{ template "harbor.component.scheme" . }}"
port: {{ template "harbor.jobservice.containerPort". }}
{{- if .Values.internalTLS.enabled }}
https_config:
cert: "/etc/harbor/ssl/jobservice/tls.crt"
key: "/etc/harbor/ssl/jobservice/tls.key"
{{- end }}
worker_pool: worker_pool:
workers: {{ .Values.jobservice.maxJobWorkers }} workers: {{ .Values.jobservice.maxJobWorkers }}
backend: "redis" backend: "redis"
redis_pool: redis_pool:
redis_url: "{{ template "harbor.redisForJobservice" . }}" redis_url: "{{ template "harbor.redis.urlForJobservice" . }}"
namespace: "harbor_job_service_namespace" namespace: "harbor_job_service_namespace"
idle_timeout_second: 3600
job_loggers: job_loggers:
{{- if eq .Values.jobservice.jobLogger "file" }} {{- if eq .Values.jobservice.jobLogger "file" }}
- name: "FILE" - name: "FILE"
......
...@@ -4,26 +4,46 @@ metadata: ...@@ -4,26 +4,46 @@ metadata:
name: "{{ template "harbor.jobservice" . }}" name: "{{ template "harbor.jobservice" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
app: jobservice component: jobservice
spec: spec:
replicas: {{ .Values.jobservice.replicas }} replicas: {{ .Values.jobservice.replicas }}
strategy:
type: {{ .Values.updateStrategy.type }}
{{- if eq .Values.updateStrategy.type "Recreate" }}
rollingUpdate: null
{{- end }}
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
app: jobservice component: jobservice
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
app: jobservice component: jobservice
annotations: annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/jobservice/jobservice-cm.yaml") . | sha256sum }} checksum/configmap: {{ include (print $.Template.BasePath "/jobservice/jobservice-cm.yaml") . | sha256sum }}
checksum/configmap-env: {{ include (print $.Template.BasePath "/jobservice/jobservice-cm-env.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/jobservice/jobservice-secrets.yaml") . | sha256sum }} checksum/secret: {{ include (print $.Template.BasePath "/jobservice/jobservice-secrets.yaml") . | sha256sum }}
checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }} checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }}
{{- 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 "/jobservice/jobservice-tls.yaml") . | sha256sum }}
{{- end }}
{{- if .Values.jobservice.podAnnotations }} {{- if .Values.jobservice.podAnnotations }}
{{ toYaml .Values.jobservice.podAnnotations | indent 8 }} {{ toYaml .Values.jobservice.podAnnotations | indent 8 }}
{{- end }} {{- end }}
spec: spec:
securityContext:
fsGroup: 10000
{{- if .Values.jobservice.serviceAccountName }}
serviceAccountName: {{ .Values.jobservice.serviceAccountName }}
{{- end -}}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers: containers:
- name: jobservice - name: jobservice
image: {{ .Values.jobservice.image.repository }}:{{ .Values.jobservice.image.tag }} image: {{ .Values.jobservice.image.repository }}:{{ .Values.jobservice.image.tag }}
...@@ -31,13 +51,15 @@ spec: ...@@ -31,13 +51,15 @@ spec:
livenessProbe: livenessProbe:
httpGet: httpGet:
path: /api/v1/stats path: /api/v1/stats
port: 8080 scheme: {{ include "harbor.component.scheme" . | upper }}
initialDelaySeconds: 20 port: {{ template "harbor.jobservice.containerPort" . }}
initialDelaySeconds: 300
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
httpGet: httpGet:
path: /api/v1/stats path: /api/v1/stats
port: 8080 scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.jobservice.containerPort" . }}
initialDelaySeconds: 20 initialDelaySeconds: 20
periodSeconds: 10 periodSeconds: 10
{{- if .Values.jobservice.resources }} {{- if .Values.jobservice.resources }}
...@@ -50,36 +72,56 @@ spec: ...@@ -50,36 +72,56 @@ spec:
secretKeyRef: secretKeyRef:
name: {{ template "harbor.core" . }} name: {{ template "harbor.core" . }}
key: secret key: secret
- name: JOBSERVICE_SECRET {{- if .Values.internalTLS.enabled }}
valueFrom: - name: INTERNAL_TLS_ENABLED
secretKeyRef: value: "true"
name: "{{ template "harbor.jobservice" . }}" - name: INTERNAL_TLS_KEY_PATH
key: secret value: /etc/harbor/ssl/jobservice/tls.key
- name: CORE_URL - name: INTERNAL_TLS_CERT_PATH
value: "http://{{ template "harbor.core" . }}" value: /etc/harbor/ssl/jobservice/tls.crt
- name: REGISTRY_CONTROLLER_URL - name: INTERNAL_TLS_TRUST_CA_PATH
value: "http://{{ template "harbor.registry" . }}:8080" value: /etc/harbor/ssl/jobservice/ca.crt
- name: LOG_LEVEL {{- end }}
value: debug envFrom:
- configMapRef:
name: "{{ template "harbor.jobservice" . }}-env"
- secretRef:
name: "{{ template "harbor.jobservice" . }}"
ports: ports:
- containerPort: 8080 - containerPort: {{ template "harbor.jobservice.containerPort" . }}
volumeMounts: volumeMounts:
- name: jobservice-config - name: jobservice-config
mountPath: /etc/jobservice/config.yml mountPath: /etc/jobservice/config.yml
subPath: config.yml subPath: config.yml
- name: data - name: job-logs
mountPath: /var/log/jobs mountPath: /var/log/jobs
- name: etc-localtime subPath: {{ .Values.persistence.persistentVolumeClaim.jobservice.subPath }}
mountPath: /etc/localtime {{- if .Values.internalTLS.enabled }}
- name: jobservice-internal-certs
mountPath: /etc/harbor/ssl/jobservice
{{- end }}
{{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolumeMount" . | indent 8 }}
{{- end }}
volumes: volumes:
- name: etc-localtime
hostPath:
path: /etc/localtime
- name: jobservice-config - name: jobservice-config
configMap: configMap:
name: "{{ template "harbor.jobservice" . }}" name: "{{ template "harbor.jobservice" . }}"
- name: data - name: job-logs
{{- if and .Values.persistence.enabled (eq .Values.jobservice.jobLogger "file") }}
persistentVolumeClaim:
claimName: {{ .Values.persistence.persistentVolumeClaim.jobservice.existingClaim | default (include "harbor.jobservice" .) }}
{{- else }}
emptyDir: {} emptyDir: {}
{{- end }}
{{- if .Values.internalTLS.enabled }}
- name: jobservice-internal-certs
secret:
secretName: {{ template "harbor.internalTLS.jobservice.secretName" . }}
{{- end }}
{{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolume" . | indent 6 }}
{{- end }}
{{- with .Values.jobservice.nodeSelector }} {{- with .Values.jobservice.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
......
{{- $jobservice := .Values.persistence.persistentVolumeClaim.jobservice -}}
{{- if and .Values.persistence.enabled (not $jobservice.existingClaim) }}
{{- if eq .Values.jobservice.jobLogger "file" }}
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: {{ template "harbor.jobservice" . }}
{{- if eq .Values.persistence.resourcePolicy "keep" }}
annotations:
helm.sh/resource-policy: keep
{{- end }}
labels:
{{ include "harbor.labels" . | indent 4 }}
component: jobservice
spec:
accessModes:
- {{ $jobservice.accessMode }}
resources:
requests:
storage: {{ $jobservice.size }}
{{- if $jobservice.storageClass }}
{{- if eq "-" $jobservice.storageClass }}
storageClassName: ""
{{- else }}
storageClassName: {{ $jobservice.storageClass }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
\ No newline at end of file
...@@ -6,4 +6,5 @@ metadata: ...@@ -6,4 +6,5 @@ metadata:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: Opaque type: Opaque
data: data:
secret: {{ .Values.jobservice.secret | default (randAlphaNum 16) | b64enc | quote }} JOBSERVICE_SECRET: {{ .Values.jobservice.secret | default (randAlphaNum 16) | b64enc | quote }}
REGISTRY_CREDENTIAL_PASSWORD: {{ .Values.registry.credentials.password | b64enc | quote }}
...@@ -6,8 +6,8 @@ metadata: ...@@ -6,8 +6,8 @@ metadata:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
spec: spec:
ports: ports:
- port: 80 - port: {{ template "harbor.jobservice.servicePort" . }}
targetPort: 8080 targetPort: {{ template "harbor.jobservice.containerPort" . }}
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
app: jobservice component: jobservice
{{- if and .Values.internalTLS.enabled }}
{{- if eq .Values.internalTLS.certSource "manual" }}
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.internalTLS.jobservice.secretName" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls
data:
ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }}
tls.crt: {{ (required "The \"internalTLS.jobservice.crt\" is required!" .Values.internalTLS.jobservice.crt) | b64enc | quote }}
tls.key: {{ (required "The \"internalTLS.jobservice.key\" is required!" .Values.internalTLS.jobservice.key) | b64enc | quote }}
{{- end }}
{{- end }}
\ No newline at end of file
{{- if and (ne .Values.expose.type "ingress") (not .Values.expose.tls.enabled) }} {{- if and (ne .Values.expose.type "ingress") (not .Values.expose.tls.enabled) }}
{{- $scheme := (include "harbor.component.scheme" .) -}}
apiVersion: v1 apiVersion: v1
kind: ConfigMap kind: ConfigMap
metadata: metadata:
...@@ -8,6 +9,7 @@ metadata: ...@@ -8,6 +9,7 @@ metadata:
data: data:
nginx.conf: |+ nginx.conf: |+
worker_processes auto; worker_processes auto;
pid /tmp/nginx.pid;
events { events {
worker_connections 1024; worker_connections 1024;
...@@ -16,20 +18,25 @@ data: ...@@ -16,20 +18,25 @@ data:
} }
http { http {
client_body_temp_path /tmp/client_body_temp;
proxy_temp_path /tmp/proxy_temp;
fastcgi_temp_path /tmp/fastcgi_temp;
uwsgi_temp_path /tmp/uwsgi_temp;
scgi_temp_path /tmp/scgi_temp;
tcp_nodelay on; tcp_nodelay on;
# this is necessary for us to be able to disable request buffering in all cases # this is necessary for us to be able to disable request buffering in all cases
proxy_http_version 1.1; proxy_http_version 1.1;
upstream core { upstream core {
server {{ template "harbor.core" . }}; server "{{ template "harbor.core" . }}:{{ template "harbor.core.servicePort" . }}";
} }
upstream portal { upstream portal {
server {{ template "harbor.portal" . }}; server {{ template "harbor.portal" . }}:{{ template "harbor.portal.servicePort" . }};
} }
log_format timed_combined '$remote_addr - ' log_format timed_combined '[$time_local]:$remote_addr - '
'"$request" $status $body_bytes_sent ' '"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" ' '"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time $pipe'; '$request_time $upstream_response_time $pipe';
...@@ -37,39 +44,51 @@ data: ...@@ -37,39 +44,51 @@ data:
access_log /dev/stdout timed_combined; access_log /dev/stdout timed_combined;
server { server {
listen 80; listen 8080;
server_tokens off; server_tokens off;
# disable any limits to avoid HTTP 413 for large image uploads # disable any limits to avoid HTTP 413 for large image uploads
client_max_body_size 0; client_max_body_size 0;
# Add extra headers
add_header X-Frame-Options DENY;
add_header Content-Security-Policy "frame-ancestors 'none'";
location / { location / {
proxy_pass http://portal/; proxy_pass {{ $scheme }}://portal/;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings. # When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /api/ { location /api/ {
proxy_pass http://core/api/; proxy_pass {{ $scheme }}://core/api/;
{{- if and .Values.internalTLS.enabled }}
proxy_ssl_verify off;
proxy_ssl_session_reuse on;
{{- end }}
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings. # When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /chartrepo/ { location /chartrepo/ {
proxy_pass http://core/chartrepo/; proxy_pass {{ $scheme }}://core/chartrepo/;
{{- if and .Values.internalTLS.enabled }}
proxy_ssl_verify off;
proxy_ssl_session_reuse on;
{{- end }}
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
...@@ -82,14 +101,14 @@ data: ...@@ -82,14 +101,14 @@ data:
} }
location /c/ { location /c/ {
proxy_pass http://core/c/; proxy_pass {{ $scheme }}://core/c/;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings. # When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
...@@ -99,11 +118,11 @@ data: ...@@ -99,11 +118,11 @@ data:
} }
location /v2/ { location /v2/ {
proxy_pass http://core/v2/; proxy_pass {{ $scheme }}://core/v2/;
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings. # When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off; proxy_buffering off;
...@@ -111,22 +130,21 @@ data: ...@@ -111,22 +130,21 @@ data:
} }
location /service/ { location /service/ {
proxy_pass http://core/service/; proxy_pass {{ $scheme }}://core/service/;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings. # When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /service/notifications { location /service/notifications {
return 404; return 404;
} }
} }
} }
{{- end }} {{- end }}
\ No newline at end of file
{{- if and (ne .Values.expose.type "ingress") .Values.expose.tls.enabled }} {{- if and (ne .Values.expose.type "ingress") .Values.expose.tls.enabled }}
{{- $scheme := (include "harbor.component.scheme" .) -}}
apiVersion: v1 apiVersion: v1
kind: ConfigMap kind: ConfigMap
metadata: metadata:
...@@ -8,6 +9,7 @@ metadata: ...@@ -8,6 +9,7 @@ metadata:
data: data:
nginx.conf: |+ nginx.conf: |+
worker_processes auto; worker_processes auto;
pid /tmp/nginx.pid;
events { events {
worker_connections 1024; worker_connections 1024;
...@@ -16,17 +18,22 @@ data: ...@@ -16,17 +18,22 @@ data:
} }
http { http {
client_body_temp_path /tmp/client_body_temp;
proxy_temp_path /tmp/proxy_temp;
fastcgi_temp_path /tmp/fastcgi_temp;
uwsgi_temp_path /tmp/uwsgi_temp;
scgi_temp_path /tmp/scgi_temp;
tcp_nodelay on; tcp_nodelay on;
# this is necessary for us to be able to disable request buffering in all cases # this is necessary for us to be able to disable request buffering in all cases
proxy_http_version 1.1; proxy_http_version 1.1;
upstream core { upstream core {
server {{ template "harbor.core" . }}; server "{{ template "harbor.core" . }}:{{ template "harbor.core.servicePort" . }}";
} }
upstream portal { upstream portal {
server {{ template "harbor.portal" . }}; server "{{ template "harbor.portal" . }}:{{ template "harbor.portal.servicePort" . }}";
} }
{{- if .Values.notary.enabled }} {{- if .Values.notary.enabled }}
...@@ -34,8 +41,8 @@ data: ...@@ -34,8 +41,8 @@ data:
server {{ template "harbor.notary-server" . }}:4443; server {{ template "harbor.notary-server" . }}:4443;
} }
{{- end }} {{- end }}
log_format timed_combined 'remote_addr - ' log_format timed_combined '[$time_local]:$remote_addr - '
'"$request" $status $body_bytes_sent ' '"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" ' '"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time $pipe'; '$request_time $upstream_response_time $pipe';
...@@ -49,16 +56,16 @@ data: ...@@ -49,16 +56,16 @@ data:
# ssl # ssl
ssl_certificate /etc/nginx/cert/tls.crt; ssl_certificate /etc/nginx/cert/tls.crt;
ssl_certificate_key /etc/nginx/cert/tls.key; ssl_certificate_key /etc/nginx/cert/tls.key;
# recommendations from https://raymii.org/s/tutorials/strong_ssl_security_on_nginx.html # recommendations from https://raymii.org/s/tutorials/strong_ssl_security_on_nginx.html
ssl_protocols tlsv1.1 tlsv1.2; ssl_protocols tlsv1.1 tlsv1.2;
ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:'; ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:';
ssl_prefer_server_ciphers on; ssl_prefer_server_ciphers on;
ssl_session_cache shared:ssl:10m; ssl_session_cache shared:ssl:10m;
# disable any limits to avoid http 413 for large image uploads # disable any limits to avoid http 413 for large image uploads
client_max_body_size 0; client_max_body_size 0;
# required to avoid http 411: see issue #1486 (https://github.com/docker/docker/issues/1486) # required to avoid http 411: see issue #1486 (https://github.com/docker/docker/issues/1486)
chunked_transfer_encoding on; chunked_transfer_encoding on;
...@@ -78,56 +85,70 @@ data: ...@@ -78,56 +85,70 @@ data:
{{- end }} {{- end }}
server { server {
listen 443 ssl; listen 8443 ssl;
# server_name harbordomain.com; # server_name harbordomain.com;
server_tokens off; server_tokens off;
# SSL # SSL
ssl_certificate /etc/nginx/cert/tls.crt; ssl_certificate /etc/nginx/cert/tls.crt;
ssl_certificate_key /etc/nginx/cert/tls.key; ssl_certificate_key /etc/nginx/cert/tls.key;
# Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1.1 TLSv1.2; ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:'; ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:';
ssl_prefer_server_ciphers on; ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m; ssl_session_cache shared:SSL:10m;
# disable any limits to avoid HTTP 413 for large image uploads # disable any limits to avoid HTTP 413 for large image uploads
client_max_body_size 0; client_max_body_size 0;
# required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486) # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
chunked_transfer_encoding on; chunked_transfer_encoding on;
# Add extra headers
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
add_header X-Frame-Options DENY;
add_header Content-Security-Policy "frame-ancestors 'none'";
location / { location / {
proxy_pass http://portal/; proxy_pass {{ $scheme }}://portal/;
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings. # When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
# Add Secure flag when serving HTTPS proxy_cookie_path / "/; HttpOnly; Secure";
proxy_cookie_path / "/; secure";
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /api/ { location /api/ {
proxy_pass http://core/api/; proxy_pass {{ $scheme }}://core/api/;
{{- if and .Values.internalTLS.enabled }}
proxy_ssl_verify off;
proxy_ssl_session_reuse on;
{{- end }}
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings. # When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_cookie_path / "/; Secure";
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /chartrepo/ { location /chartrepo/ {
proxy_pass http://core/chartrepo/; proxy_pass {{ $scheme }}://core/chartrepo/;
{{- if and .Values.internalTLS.enabled }}
proxy_ssl_verify off;
proxy_ssl_session_reuse on;
{{- end }}
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
...@@ -135,19 +156,23 @@ data: ...@@ -135,19 +156,23 @@ data:
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings. # When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_cookie_path / "/; Secure";
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /c/ { location /c/ {
proxy_pass http://core/c/; proxy_pass {{ $scheme }}://core/c/;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings. # When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_cookie_path / "/; Secure";
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
...@@ -157,11 +182,11 @@ data: ...@@ -157,11 +182,11 @@ data:
} }
location /v2/ { location /v2/ {
proxy_pass http://core/v2/; proxy_pass {{ $scheme }}://core/v2/;
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings. # When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off; proxy_buffering off;
...@@ -169,27 +194,28 @@ data: ...@@ -169,27 +194,28 @@ data:
} }
location /service/ { location /service/ {
proxy_pass http://core/service/; proxy_pass {{ $scheme }}://core/service/;
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings. # When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_cookie_path / "/; Secure";
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /service/notifications { location /service/notifications {
return 404; return 404;
} }
} }
server { server {
listen 80; listen 8080;
#server_name harbordomain.com; #server_name harbordomain.com;
return 301 https://$host$request_uri; return 301 https://$host$request_uri;
} }
} }
{{- end }} {{- end }}
\ No newline at end of file
{{- if ne .Values.expose.type "ingress" }} {{- if ne .Values.expose.type "ingress" }}
apiVersion: extensions/v1beta1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: {{ template "harbor.nginx" . }} name: {{ template "harbor.nginx" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
app: nginx component: nginx
spec: spec:
replicas: 1 replicas: {{ .Values.nginx.replicas }}
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
app: nginx component: nginx
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
app: nginx component: nginx
annotations: annotations:
{{- if not .Values.expose.tls.enabled }} {{- if not .Values.expose.tls.enabled }}
checksum/configmap: {{ include (print $.Template.BasePath "/nginx/configmap-http.yaml") . | sha256sum }} checksum/configmap: {{ include (print $.Template.BasePath "/nginx/configmap-http.yaml") . | sha256sum }}
...@@ -30,20 +30,37 @@ spec: ...@@ -30,20 +30,37 @@ spec:
{{ toYaml .Values.nginx.podAnnotations | indent 8 }} {{ toYaml .Values.nginx.podAnnotations | indent 8 }}
{{- end }} {{- end }}
spec: spec:
{{- if .Values.nginx.serviceAccountName }}
serviceAccountName: {{ .Values.nginx.serviceAccountName }}
{{- end }}
securityContext:
fsGroup: 10000
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers: containers:
- name: nginx - name: nginx
image: "{{ .Values.nginx.image.repository }}:{{ .Values.nginx.image.tag }}" image: "{{ .Values.nginx.image.repository }}:{{ .Values.nginx.image.tag }}"
imagePullPolicy: "{{ .Values.imagePullPolicy }}" imagePullPolicy: "{{ .Values.imagePullPolicy }}"
{{- $_ := set . "scheme" "HTTP" -}}
{{- $_ := set . "port" "8080" -}}
{{- if .Values.expose.tls.enabled }}
{{- $_ := set . "scheme" "HTTPS" -}}
{{- $_ := set . "port" "8443" -}}
{{- end }}
livenessProbe: livenessProbe:
httpGet: httpGet:
scheme: {{ .scheme }}
path: / path: /
port: 80 port: {{ .port }}
initialDelaySeconds: 1 initialDelaySeconds: 300
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
httpGet: httpGet:
scheme: {{ .scheme }}
path: / path: /
port: 80 port: {{ .port }}
initialDelaySeconds: 1 initialDelaySeconds: 1
periodSeconds: 10 periodSeconds: 10
{{- if .Values.nginx.resources }} {{- if .Values.nginx.resources }}
...@@ -51,8 +68,8 @@ spec: ...@@ -51,8 +68,8 @@ spec:
{{ toYaml .Values.nginx.resources | indent 10 }} {{ toYaml .Values.nginx.resources | indent 10 }}
{{- end }} {{- end }}
ports: ports:
- containerPort: 80 - containerPort: 8080
- containerPort: 443 - containerPort: 8443
- containerPort: 4443 - containerPort: 4443
volumeMounts: volumeMounts:
- name: config - name: config
...@@ -69,11 +86,7 @@ spec: ...@@ -69,11 +86,7 @@ spec:
{{- if .Values.expose.tls.enabled }} {{- if .Values.expose.tls.enabled }}
- name: certificate - name: certificate
secret: secret:
{{- if .Values.expose.tls.secretName }} secretName: {{ template "harbor.tlsSecretForNginx" . }}
secretName: {{ .Values.expose.tls.secretName }}
{{- else }}
secretName: {{ template "harbor.nginx" . }}
{{- end }}
{{- end }} {{- end }}
{{- with .Values.nginx.nodeSelector }} {{- with .Values.nginx.nodeSelector }}
nodeSelector: nodeSelector:
...@@ -87,4 +100,4 @@ spec: ...@@ -87,4 +100,4 @@ spec:
tolerations: tolerations:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- end }} {{- end }}
\ No newline at end of file
{{- if eq (include "harbor.autoGenCertForNginx" .) "true" }} {{- if eq (include "harbor.autoGenCertForNginx" .) "true" }}
{{- $ca := genCA "harbor-ca" 365 }} {{- $ca := genCA "harbor-ca" 365 }}
{{- $cn := (required "The \"expose.tls.commonName\" is required!" .Values.expose.tls.commonName) }} {{- $cn := (required "The \"expose.tls.auto.commonName\" is required!" .Values.expose.tls.auto.commonName) }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
......
...@@ -5,7 +5,6 @@ metadata: ...@@ -5,7 +5,6 @@ metadata:
{{- if eq .Values.expose.type "clusterIP" }} {{- if eq .Values.expose.type "clusterIP" }}
{{- $clusterIP := .Values.expose.clusterIP }} {{- $clusterIP := .Values.expose.clusterIP }}
name: {{ $clusterIP.name }} name: {{ $clusterIP.name }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
spec: spec:
...@@ -13,11 +12,11 @@ spec: ...@@ -13,11 +12,11 @@ spec:
ports: ports:
- name: http - name: http
port: {{ $clusterIP.ports.httpPort }} port: {{ $clusterIP.ports.httpPort }}
targetPort: 80 targetPort: 8080
{{- if .Values.expose.tls.enabled }} {{- if .Values.expose.tls.enabled }}
- name: https - name: https
port: {{ $clusterIP.ports.httpsPort }} port: {{ $clusterIP.ports.httpsPort }}
targetPort: 443 targetPort: 8443
{{- end }} {{- end }}
{{- if .Values.notary.enabled }} {{- if .Values.notary.enabled }}
- name: notary - name: notary
...@@ -34,14 +33,14 @@ spec: ...@@ -34,14 +33,14 @@ spec:
ports: ports:
- name: http - name: http
port: {{ $nodePort.ports.http.port }} port: {{ $nodePort.ports.http.port }}
targetPort: 80 targetPort: 8080
{{- if $nodePort.ports.http.nodePort }} {{- if $nodePort.ports.http.nodePort }}
nodePort: {{ $nodePort.ports.http.nodePort }} nodePort: {{ $nodePort.ports.http.nodePort }}
{{- end }} {{- end }}
{{- if .Values.expose.tls.enabled }} {{- if .Values.expose.tls.enabled }}
- name: https - name: https
port: {{ $nodePort.ports.https.port }} port: {{ $nodePort.ports.https.port }}
targetPort: 443 targetPort: 8443
{{- if $nodePort.ports.https.nodePort }} {{- if $nodePort.ports.https.nodePort }}
nodePort: {{ $nodePort.ports.https.nodePort }} nodePort: {{ $nodePort.ports.https.nodePort }}
{{- end }} {{- end }}
...@@ -59,19 +58,27 @@ spec: ...@@ -59,19 +58,27 @@ spec:
name: {{ $loadBalancer.name }} name: {{ $loadBalancer.name }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
{{- with $loadBalancer.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec: spec:
type: LoadBalancer type: LoadBalancer
{{- with $loadBalancer.sourceRanges }}
loadBalancerSourceRanges:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- if $loadBalancer.IP }} {{- if $loadBalancer.IP }}
loadBalancerIP: {{ $loadBalancer.IP }} loadBalancerIP: {{ $loadBalancer.IP }}
{{- end }} {{- end }}
ports: ports:
- name: http - name: http
port: {{ $loadBalancer.ports.httpPort }} port: {{ $loadBalancer.ports.httpPort }}
targetPort: 80 targetPort: 8080
{{- if .Values.expose.tls.enabled }} {{- if .Values.expose.tls.enabled }}
- name: https - name: https
port: {{ $loadBalancer.ports.httpsPort }} port: {{ $loadBalancer.ports.httpsPort }}
targetPort: 443 targetPort: 8443
{{- end }} {{- end }}
{{- if .Values.notary.enabled }} {{- if .Values.notary.enabled }}
- name: notary - name: notary
...@@ -81,5 +88,5 @@ spec: ...@@ -81,5 +88,5 @@ spec:
{{- end }} {{- end }}
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
app: nginx component: nginx
{{- end }} {{- end }}
\ No newline at end of file
{{ if .Values.notary.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "harbor.notary-server" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
app: notary
data:
{{ $ca := genCA "harbor-notary-ca" 365 }}
{{ $cert := genSignedCert (include "harbor.notary-signer" .) nil nil 365 $ca }}
{{- if not .Values.notary.secretName }}
notary-signer-ca.crt: |
{{ $ca.Cert | indent 4 }}
notary-signer.crt: |
{{ $cert.Cert | indent 4 }}
notary-signer.key: |
{{ $cert.Key | indent 4 }}
{{- end }}
server-config.postgres.json: |
{
"server": {
"http_addr": ":4443"
},
"trust_service": {
"type": "remote",
"hostname": "{{ template "harbor.notary-signer" . }}",
"port": "7899",
{{- if not .Values.notary.secretName }}
"tls_ca_file": "./notary-signer-ca.crt",
{{- else }}
"tls_ca_file": "/etc/ssl/notary/cert/notary-signer-ca.crt",
{{- end }}
"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"
}
}
}
signer-config.postgres.json: |
{
"server": {
"grpc_addr": ":7899",
{{- if not .Values.notary.secretName }}
"tls_cert_file": "./notary-signer.crt",
"tls_key_file": "./notary-signer.key"
{{- else }}
"tls_cert_file": "/etc/ssl/notary/cert/notary-signer.crt",
"tls_key_file": "/etc/ssl/notary/cert/notary-signer.key"
{{- end }}
},
"logging": {
"level": "{{ .Values.logLevel }}"
},
"storage": {
"backend": "postgres",
"db_url": "{{ template "harbor.database.notarySigner" . }}",
"default_alias": "defaultalias"
}
}
{{ end }}
{{- 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 nil 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 }}
{{- end }}
...@@ -5,25 +5,34 @@ metadata: ...@@ -5,25 +5,34 @@ metadata:
name: {{ template "harbor.notary-server" . }} name: {{ template "harbor.notary-server" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
app: notary-server component: notary-server
spec: spec:
replicas: {{ .Values.notary.server.replicas }} replicas: {{ .Values.notary.server.replicas }}
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
app: notary-server component: notary-server
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
app: notary-server component: notary-server
annotations: annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/notary/notary-cm.yaml") . | sha256sum }} checksum/secret: {{ include (print $.Template.BasePath "/notary/notary-secret.yaml") . | sha256sum }}
checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }} checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }}
{{- if .Values.notary.podAnnotations }} {{- if .Values.notary.podAnnotations }}
{{ toYaml .Values.notary.podAnnotations | indent 8 }} {{ toYaml .Values.notary.podAnnotations | indent 8 }}
{{- end }} {{- end }}
spec: spec:
securityContext:
fsGroup: 10000
{{- if .Values.notary.server.serviceAccountName }}
serviceAccountName: {{ .Values.notary.server.serviceAccountName }}
{{- end -}}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers: containers:
- name: notary-server - name: notary-server
image: {{ .Values.notary.server.image.repository }}:{{ .Values.notary.server.image.tag }} image: {{ .Values.notary.server.image.repository }}:{{ .Values.notary.server.image.tag }}
...@@ -38,37 +47,33 @@ spec: ...@@ -38,37 +47,33 @@ spec:
- name: DB_URL - name: DB_URL
value: {{ template "harbor.database.notaryServer" . }} value: {{ template "harbor.database.notaryServer" . }}
volumeMounts: volumeMounts:
- name: notary-config - name: config
mountPath: /etc/notary mountPath: /etc/notary/server-config.postgres.json
- name: etc-localtime subPath: server.json
mountPath: /etc/localtime - name: token-service-certificate
- name: root-certificate
mountPath: /root.crt mountPath: /root.crt
subPath: tls.crt subPath: tls.crt
{{- if .Values.notary.secretName }} - name: signer-certificate
- name: notary-ca mountPath: /etc/ssl/notary/ca.crt
mountPath: /etc/ssl/notary/cert/notary-signer-ca.crt subPath: ca.crt
subPath: ca
{{- end }}
volumes: volumes:
- name: etc-localtime - name: config
hostPath: secret:
path: /etc/localtime secretName: "{{ template "harbor.notary-server" . }}"
- name: notary-config - name: token-service-certificate
configMap:
name: "{{ template "harbor.notary-server" . }}"
- name: root-certificate
secret: secret:
{{- if .Values.core.secretName }} {{- if .Values.core.secretName }}
secretName: {{ .Values.core.secretName }} secretName: {{ .Values.core.secretName }}
{{- else }} {{- else }}
secretName: {{ template "harbor.core" . }} secretName: {{ template "harbor.core" . }}
{{- end }} {{- end }}
{{- if .Values.notary.secretName }} - name: signer-certificate
- name: notary-ca
secret: secret:
{{- if .Values.notary.secretName }}
secretName: {{ .Values.notary.secretName }} secretName: {{ .Values.notary.secretName }}
{{- end }} {{- else }}
secretName: {{ template "harbor.notary-server" . }}
{{- end }}
{{- with .Values.notary.nodeSelector }} {{- with .Values.notary.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
......
...@@ -5,21 +5,30 @@ metadata: ...@@ -5,21 +5,30 @@ metadata:
name: {{ template "harbor.notary-signer" . }} name: {{ template "harbor.notary-signer" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
app: notary-signer component: notary-signer
spec: spec:
replicas: {{ .Values.notary.signer.replicas }} replicas: {{ .Values.notary.signer.replicas }}
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
app: notary-signer component: notary-signer
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
app: notary-signer component: notary-signer
annotations: annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/notary/notary-cm.yaml") . | sha256sum }} checksum/secret: {{ include (print $.Template.BasePath "/notary/notary-secret.yaml") . | sha256sum }}
spec: spec:
securityContext:
fsGroup: 10000
{{- if .Values.notary.signer.serviceAccountName }}
serviceAccountName: {{ .Values.notary.signer.serviceAccountName }}
{{- end -}}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers: containers:
- name: notary-signer - name: notary-signer
image: {{ .Values.notary.signer.image.repository }}:{{ .Values.notary.signer.image.tag }} image: {{ .Values.notary.signer.image.repository }}:{{ .Values.notary.signer.image.tag }}
...@@ -36,33 +45,26 @@ spec: ...@@ -36,33 +45,26 @@ spec:
- name: NOTARY_SIGNER_DEFAULTALIAS - name: NOTARY_SIGNER_DEFAULTALIAS
value: defaultalias value: defaultalias
volumeMounts: volumeMounts:
- name: notary-config - name: config
mountPath: /etc/notary mountPath: /etc/notary/signer-config.postgres.json
- name: etc-localtime subPath: signer.json
mountPath: /etc/localtime - name: signer-certificate
{{- if .Values.notary.secretName }} mountPath: /etc/ssl/notary/tls.crt
- name: notary-cert subPath: tls.crt
mountPath: /etc/ssl/notary/cert/notary-signer-ca.crt - name: signer-certificate
subPath: ca mountPath: /etc/ssl/notary/tls.key
- name: notary-cert subPath: tls.key
mountPath: /etc/ssl/notary/cert/notary-signer.crt
subPath: crt
- name: notary-cert
mountPath: /etc/ssl/notary/cert/notary-signer.key
subPath: key
{{- end }}
volumes: volumes:
- name: etc-localtime - name: config
hostPath: secret:
path: /etc/localtime secretName: "{{ template "harbor.notary-server" . }}"
- name: notary-config - name: signer-certificate
configMap:
name: "{{ template "harbor.notary-server" . }}"
{{- if .Values.notary.secretName }}
- name: notary-cert
secret: secret:
{{- if .Values.notary.secretName }}
secretName: {{ .Values.notary.secretName }} secretName: {{ .Values.notary.secretName }}
{{- end }} {{- else }}
secretName: {{ template "harbor.notary-server" . }}
{{- end }}
{{- with .Values.notary.nodeSelector }} {{- with .Values.notary.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
......
...@@ -13,7 +13,7 @@ spec: ...@@ -13,7 +13,7 @@ spec:
- port: 4443 - port: 4443
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
app: notary-server component: notary-server
--- ---
apiVersion: v1 apiVersion: v1
...@@ -27,5 +27,5 @@ spec: ...@@ -27,5 +27,5 @@ spec:
- port: 7899 - port: 7899
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
app: notary-signer component: notary-signer
{{ end }} {{ end }}
\ No newline at end of file
apiVersion: v1
kind: ConfigMap
metadata:
name: "{{ template "harbor.portal" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
data:
nginx.conf: |+
worker_processes auto;
pid /tmp/nginx.pid;
events {
worker_connections 1024;
}
http {
client_body_temp_path /tmp/client_body_temp;
proxy_temp_path /tmp/proxy_temp;
fastcgi_temp_path /tmp/fastcgi_temp;
uwsgi_temp_path /tmp/uwsgi_temp;
scgi_temp_path /tmp/scgi_temp;
server {
{{- if .Values.internalTLS.enabled }}
listen {{ template "harbor.portal.containerPort" . }} ssl;
# SSL
ssl_certificate /etc/harbor/ssl/portal/tls.crt;
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_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;
{{- else }}
listen {{ template "harbor.portal.containerPort" . }};
{{- end }}
server_name localhost;
root /usr/share/nginx/html;
index index.html index.htm;
include /etc/nginx/mime.types;
gzip on;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
location / {
try_files $uri $uri/ /index.html;
}
location = /index.html {
add_header Cache-Control "no-store, no-cache, must-revalidate";
}
}
}
...@@ -4,23 +4,35 @@ metadata: ...@@ -4,23 +4,35 @@ metadata:
name: "{{ template "harbor.portal" . }}" name: "{{ template "harbor.portal" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
app: portal component: portal
spec: spec:
replicas: {{ .Values.portal.replicas }} replicas: {{ .Values.portal.replicas }}
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
app: portal component: portal
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.matchLabels" . | indent 8 }} {{ include "harbor.matchLabels" . | indent 8 }}
app: portal component: portal
annotations: 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 "/portal/tls.yaml") . | sha256sum }}
{{- end }}
{{- if .Values.portal.podAnnotations }} {{- if .Values.portal.podAnnotations }}
{{ toYaml .Values.portal.podAnnotations | indent 8 }} {{ toYaml .Values.portal.podAnnotations | indent 8 }}
{{- end }} {{- end }}
spec: spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.portal.serviceAccountName }}
serviceAccountName: {{ .Values.portal.serviceAccountName }}
{{- end }}
containers: containers:
- name: portal - name: portal
image: {{ .Values.portal.image.repository }}:{{ .Values.portal.image.tag }} image: {{ .Values.portal.image.repository }}:{{ .Values.portal.image.tag }}
...@@ -32,24 +44,36 @@ spec: ...@@ -32,24 +44,36 @@ spec:
livenessProbe: livenessProbe:
httpGet: httpGet:
path: / path: /
port: 80 scheme: {{ include "harbor.component.scheme" . | upper }}
initialDelaySeconds: 1 port: {{ template "harbor.portal.containerPort" . }}
initialDelaySeconds: 300
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
httpGet: httpGet:
path: / path: /
port: 80 scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.portal.containerPort" . }}
initialDelaySeconds: 1 initialDelaySeconds: 1
periodSeconds: 10 periodSeconds: 10
ports: ports:
- containerPort: 80 - containerPort: {{ template "harbor.portal.containerPort" . }}
volumeMounts: volumeMounts:
- name: etc-localtime - name: portal-config
mountPath: /etc/localtime mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
{{- if .Values.internalTLS.enabled }}
- name: portal-internal-certs
mountPath: /etc/harbor/ssl/portal
{{- end }}
volumes: volumes:
- name: etc-localtime - name: portal-config
hostPath: configMap:
path: /etc/localtime name: "{{ template "harbor.portal" . }}"
{{- if .Values.internalTLS.enabled }}
- name: portal-internal-certs
secret:
secretName: {{ template "harbor.internalTLS.portal.secretName" . }}
{{- end }}
{{- with .Values.portal.nodeSelector }} {{- with .Values.portal.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
......
...@@ -5,12 +5,9 @@ metadata: ...@@ -5,12 +5,9 @@ metadata:
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
spec: spec:
{{- if (eq .Values.expose.ingress.controller "gce") }}
type: NodePort
{{- end }}
ports: ports:
- port: 80 - port: {{ template "harbor.portal.servicePort" . }}
targetPort: 80 targetPort: {{ template "harbor.portal.containerPort" . }}
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
app: portal component: portal
{{- if and .Values.internalTLS.enabled }}
{{- if eq .Values.internalTLS.certSource "manual" }}
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.internalTLS.portal.secretName" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls
data:
ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }}
tls.crt: {{ (required "The \"internalTLS.portal.crt\" is required!" .Values.internalTLS.portal.crt) | b64enc | quote }}
tls.key: {{ (required "The \"internalTLS.portal.key\" is required!" .Values.internalTLS.portal.key) | b64enc | quote }}
{{- end }}
{{- end }}
...@@ -10,5 +10,5 @@ spec: ...@@ -10,5 +10,5 @@ spec:
- port: 6379 - port: 6379
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
app: redis component: redis
{{- end -}} {{- end -}}
\ No newline at end of file
...@@ -6,24 +6,33 @@ metadata: ...@@ -6,24 +6,33 @@ metadata:
name: {{ template "harbor.redis" . }} name: {{ template "harbor.redis" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
app: redis component: redis
spec: spec:
replicas: 1 replicas: 1
serviceName: {{ template "harbor.redis" . }} serviceName: {{ template "harbor.redis" . }}
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
app: redis component: redis
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
app: redis component: redis
{{- if .Values.redis.podAnnotations }} {{- if .Values.redis.podAnnotations }}
annotations: annotations:
{{ toYaml .Values.redis.podAnnotations | indent 8 }} {{ toYaml .Values.redis.podAnnotations | indent 8 }}
{{- end }} {{- end }}
spec: spec:
securityContext:
fsGroup: 999
{{- if .Values.redis.internal.serviceAccountName }}
serviceAccountName: {{ .Values.redis.internal.serviceAccountName }}
{{- end -}}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers: containers:
- name: redis - name: redis
image: {{ .Values.redis.internal.image.repository }}:{{ .Values.redis.internal.image.tag }} image: {{ .Values.redis.internal.image.repository }}:{{ .Values.redis.internal.image.tag }}
...@@ -31,7 +40,7 @@ spec: ...@@ -31,7 +40,7 @@ spec:
livenessProbe: livenessProbe:
tcpSocket: tcpSocket:
port: 6379 port: 6379
initialDelaySeconds: 1 initialDelaySeconds: 300
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
tcpSocket: tcpSocket:
...@@ -45,14 +54,17 @@ spec: ...@@ -45,14 +54,17 @@ spec:
volumeMounts: volumeMounts:
- name: data - name: data
mountPath: /var/lib/redis mountPath: /var/lib/redis
- name: etc-localtime subPath: {{ $redis.subPath }}
mountPath: /etc/localtime {{- if not .Values.persistence.enabled }}
volumes: volumes:
- name: etc-localtime
hostPath:
path: /etc/localtime
- name: data - name: data
emptyDir: {} emptyDir: {}
{{- else if $redis.existingClaim }}
volumes:
- name: data
persistentVolumeClaim:
claimName: {{ $redis.existingClaim }}
{{- end -}}
{{- with .Values.redis.internal.nodeSelector }} {{- with .Values.redis.internal.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
...@@ -65,4 +77,23 @@ spec: ...@@ -65,4 +77,23 @@ spec:
tolerations: tolerations:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- end -}} {{- if and .Values.persistence.enabled (not $redis.existingClaim) }}
volumeClaimTemplates:
- metadata:
name: data
labels:
{{ include "harbor.labels" . | indent 8 }}
spec:
accessModes: [{{ $redis.accessMode | quote }}]
{{- if $redis.storageClass }}
{{- if (eq "-" $redis.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: "{{ $redis.storageClass }}"
{{- end }}
{{- end }}
resources:
requests:
storage: {{ $redis.size | quote }}
{{- end -}}
{{- end -}}
...@@ -8,7 +8,13 @@ data: ...@@ -8,7 +8,13 @@ data:
config.yml: |+ config.yml: |+
version: 0.1 version: 0.1
log: log:
{{- if eq .Values.logLevel "warning" }}
level: warn
{{- else if eq .Values.logLevel "fatal" }}
level: error
{{- else }}
level: {{ .Values.logLevel }} level: {{ .Values.logLevel }}
{{- end }}
fields: fields:
service: registry service: registry
storage: storage:
...@@ -47,9 +53,15 @@ data: ...@@ -47,9 +53,15 @@ data:
{{- if $storage.s3.encrypt }} {{- if $storage.s3.encrypt }}
encrypt: {{ $storage.s3.encrypt }} encrypt: {{ $storage.s3.encrypt }}
{{- end }} {{- end }}
{{- if $storage.s3.keyid }}
keyid: {{ $storage.s3.keyid }}
{{- end }}
{{- if $storage.s3.secure }} {{- if $storage.s3.secure }}
secure: {{ $storage.s3.secure }} secure: {{ $storage.s3.secure }}
{{- end }} {{- end }}
{{- if and $storage.s3.secure $storage.s3.skipverify }}
skipverify: {{ $storage.s3.skipverify }}
{{- end }}
{{- if $storage.s3.v4auth }} {{- if $storage.s3.v4auth }}
v4auth: {{ $storage.s3.v4auth }} v4auth: {{ $storage.s3.v4auth }}
{{- end }} {{- end }}
...@@ -62,6 +74,15 @@ data: ...@@ -62,6 +74,15 @@ data:
{{- if $storage.s3.storageclass }} {{- if $storage.s3.storageclass }}
storageclass: {{ $storage.s3.storageclass }} storageclass: {{ $storage.s3.storageclass }}
{{- end }} {{- end }}
{{- if $storage.s3.multipartcopychunksize }}
multipartcopychunksize: {{ $storage.s3.multipartcopychunksize }}
{{- end }}
{{- if $storage.s3.multipartcopymaxconcurrency }}
multipartcopymaxconcurrency: {{ $storage.s3.multipartcopymaxconcurrency }}
{{- end }}
{{- if $storage.s3.multipartcopythresholdsize }}
multipartcopythresholdsize: {{ $storage.s3.multipartcopythresholdsize }}
{{- end }}
{{- else if eq $type "swift" }} {{- else if eq $type "swift" }}
swift: swift:
authurl: {{ $storage.swift.authurl }} authurl: {{ $storage.swift.authurl }}
...@@ -140,32 +161,64 @@ data: ...@@ -140,32 +161,64 @@ data:
redirect: redirect:
disable: {{ $storage.disableredirect }} disable: {{ $storage.disableredirect }}
redis: redis:
addr: "{{ template "harbor.redis.host" . }}:{{ template "harbor.redis.port" . }}" addr: {{ template "harbor.redis.addr" . }}
db: {{ template "harbor.redis.registryDatabaseIndex" . }} {{- if eq "redis+sentinel" (include "harbor.redis.scheme" .) }}
sentinelMasterSet: {{ template "harbor.redis.masterSet" . }}
{{- end }}
db: {{ template "harbor.redis.dbForRegistry" . }}
password: {{ template "harbor.redis.password" . }}
readtimeout: 10s
writetimeout: 10s
dialtimeout: 10s
http: http:
addr: :5000 addr: :{{ template "harbor.registry.containerPort" . }}
relativeurls: {{ .Values.registry.relativeurls }}
{{- if .Values.internalTLS.enabled }}
tls:
certificate: /etc/harbor/ssl/registry/tls.crt
key: /etc/harbor/ssl/registry/tls.key
minimumtls: tls1.2
{{- end }}
# set via environment variable # set via environment variable
# secret: placeholder # secret: placeholder
debug: debug:
addr: localhost:5001 addr: localhost:5001
auth: auth:
token: htpasswd:
issuer: harbor-token-issuer realm: harbor-registry-basic-realm
realm: "{{ .Values.externalURL }}/service/token" path: /etc/registry/passwd
rootcertbundle: /etc/registry/root.crt
service: harbor-registry
validation: validation:
disabled: true disabled: true
notifications: compatibility:
endpoints: schema1:
- name: harbor enabled: true
disabled: false
url: http://{{ template "harbor.core" . }}/service/notifications {{- if .Values.registry.middleware.enabled }}
timeout: 3000ms {{- $middleware := .Values.registry.middleware }}
threshold: 5 {{- $middlewareType := $middleware.type }}
backoff: 1s {{- if eq $middlewareType "cloudFront" }}
middleware:
storage:
- name: cloudfront
options:
baseurl: {{ $middleware.cloudFront.baseurl }}
privatekey: /etc/registry/pk.pem
keypairid: {{ $middleware.cloudFront.keypairid }}
duration: {{ $middleware.cloudFront.duration }}
ipfilteredby: {{ $middleware.cloudFront.ipfilteredby }}
{{- end }}
{{- end }}
ctl-config.yml: |+ ctl-config.yml: |+
--- ---
{{- if .Values.internalTLS.enabled }}
protocol: "https"
port: 8443
https_config:
cert: "/etc/harbor/ssl/registry/tls.crt"
key: "/etc/harbor/ssl/registry/tls.key"
{{- else }}
protocol: "http" protocol: "http"
port: 8080 port: 8080
{{- end }}
log_level: {{ .Values.logLevel }} log_level: {{ .Values.logLevel }}
registry_config: "/etc/registry/config.yml"
This diff is collapsed.
{{- if .Values.persistence.enabled }}
{{- $registry := .Values.persistence.persistentVolumeClaim.registry -}}
{{- if and (not $registry.existingClaim) (eq .Values.persistence.imageChartStorage.type "filesystem") }}
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: {{ template "harbor.registry" . }}
{{- if eq .Values.persistence.resourcePolicy "keep" }}
annotations:
helm.sh/resource-policy: keep
{{- end }}
labels:
{{ include "harbor.labels" . | indent 4 }}
component: registry
spec:
accessModes:
- {{ $registry.accessMode }}
resources:
requests:
storage: {{ $registry.size }}
{{- if $registry.storageClass }}
{{- if eq "-" $registry.storageClass }}
storageClassName: ""
{{- else }}
storageClassName: {{ $registry.storageClass }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
\ No newline at end of file
...@@ -6,8 +6,9 @@ metadata: ...@@ -6,8 +6,9 @@ metadata:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: Opaque type: Opaque
data: data:
REGISTRY_HTPASSWD: {{ .Values.registry.credentials.htpasswd | b64enc | quote }}
REGISTRY_HTTP_SECRET: {{ .Values.registry.secret | default (randAlphaNum 16) | b64enc | quote }} REGISTRY_HTTP_SECRET: {{ .Values.registry.secret | default (randAlphaNum 16) | b64enc | quote }}
REGISTRY_REDIS_PASSWORD: {{ (include "harbor.redis.rawPassword" .) | b64enc | quote }} REGISTRY_REDIS_PASSWORD: {{ (include "harbor.redis.password" .) | b64enc | quote }}
{{- $storage := .Values.persistence.imageChartStorage }} {{- $storage := .Values.persistence.imageChartStorage }}
{{- $type := $storage.type }} {{- $type := $storage.type }}
{{- if eq $type "azure" }} {{- if eq $type "azure" }}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
module github.com/goharbor/harbor-helm
go 1.13
require (
github.com/gruntwork-io/terratest v0.28.2
github.com/stretchr/testify v1.6.0
k8s.io/api v0.18.3
)
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment