Commit 75fc385a authored by 吕永新's avatar 吕永新

Add version v2.1.0

parent 577a521f
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
......@@ -2,3 +2,5 @@ docs/*
.git/*
.gitignore
CONTRIBUTING.md
.travis.yaml
test/*
\ No newline at end of file
......@@ -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.
# Contributers
## Contributers
Thanks very much to all contributers who submitted pull requests to Helm Chart for Harbor.
......
apiVersion: v1
name: harbor
version: 1.1.1
appVersion: 1.8.1
version: 1.4.0-dev
appVersion: dev
description: An open source trusted cloud native registry that stores, signs, and scans content
keywords:
- docker
- registry
- harbor
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:
- https://github.com/goharbor/harbor
- https://github.com/goharbor/harbor-helm
maintainers:
- name: Jesse Hu
email: huh@vmware.com
- name: paulczar
email: username.taken@gmail.com
- name: Wenkai Yin
email: yinw@vmware.com
- name: Weiwei He
email: hweiwei@vmware.com
- name: Qian Deng
email: dengq@vmware.com
engine: gotpl
# harbor
## install
```bash
# 1.install
# label node
kubectl label node <nodename> harbor=enabled
helm install \
/etc/kubernetes/helm/harbor \
--name=harbor \
--namespace=devops \
-f /etc/kubernetes/helm/harbor/values-overrides.yaml
# uninstall
helm delete harbor --purge
# update
helm upgrade harbor /etc/kubernetes/helm/harbor \
-f /etc/kubernetes/helm/harbor/values-overrides.yaml
# template
helm template \
/etc/kubernetes/helm/harbor \
--name=harbor \
--namespace=harbor \
-f /etc/kubernetes/helm/harbor/values-overrides.yaml > /etc/kubernetes/helm/harbor/dist.yaml
```
## images
```bash
# goharbor/harbor-portal
docker pull goharbor/harbor-portal:v1.8.2 && \
docker tag goharbor/harbor-portal:v1.8.2 registry-vpc.cn-qingdao.aliyuncs.com/wod/harbor-portal:v1.8.2 && \
docker push registry-vpc.cn-qingdao.aliyuncs.com/wod/harbor-portal:v1.8.2
# goharbor/harbor-core
docker pull goharbor/harbor-core:v1.8.2 && \
docker tag goharbor/harbor-core:v1.8.2 registry-vpc.cn-qingdao.aliyuncs.com/wod/harbor-core:v1.8.2 && \
docker push registry-vpc.cn-qingdao.aliyuncs.com/wod/harbor-core:v1.8.2
# goharbor/harbor-jobservice
docker pull goharbor/harbor-jobservice:v1.8.2 && \
docker tag goharbor/harbor-jobservice:v1.8.2 registry-vpc.cn-qingdao.aliyuncs.com/wod/harbor-jobservice:v1.8.2 && \
docker push registry-vpc.cn-qingdao.aliyuncs.com/wod/harbor-jobservice:v1.8.2
# goharbor/harbor-db
docker pull goharbor/harbor-db:v1.8.2 && \
docker tag goharbor/harbor-db:v1.8.2 registry-vpc.cn-qingdao.aliyuncs.com/wod/harbor-db:v1.8.2 && \
docker push registry-vpc.cn-qingdao.aliyuncs.com/wod/harbor-db:v1.8.2
# registry
docker pull registry:2.7.1 && \
docker tag registry:2.7.1 registry-vpc.cn-qingdao.aliyuncs.com/wod/registry:2.7.1 && \
docker push registry-vpc.cn-qingdao.aliyuncs.com/wod/registry:2.7.1
# goharbor/harbor-registryctl
docker pull goharbor/harbor-registryctl:v1.8.2 && \
docker tag goharbor/harbor-registryctl:v1.8.2 registry-vpc.cn-qingdao.aliyuncs.com/wod/harbor-registryctl:v1.8.2 && \
docker push registry-vpc.cn-qingdao.aliyuncs.com/wod/harbor-registryctl:v1.8.2
# goharbor/chartmuseum-photon
docker pull goharbor/chartmuseum-photon:v0.9.0-v1.8.2 && \
docker tag goharbor/chartmuseum-photon:v0.9.0-v1.8.2 registry-vpc.cn-qingdao.aliyuncs.com/wod/chartmuseum-photon:v0.9.0-v1.8.2 && \
docker push registry-vpc.cn-qingdao.aliyuncs.com/wod/chartmuseum-photon:v0.9.0-v1.8.2
# goharbor/clair-photon
docker pull goharbor/clair-photon:v2.0.8-v1.8.2 && \
docker tag goharbor/clair-photon:v2.0.8-v1.8.2 registry-vpc.cn-qingdao.aliyuncs.com/wod/clair-photon:v2.0.8-v1.8.2 && \
docker push registry-vpc.cn-qingdao.aliyuncs.com/wod/clair-photon:v2.0.8-v1.8.2
# goharbor/notary-server-photon
docker pull goharbor/notary-server-photon:v0.6.1-v1.8.2 && \
docker tag goharbor/notary-server-photon:v0.6.1-v1.8.2 registry-vpc.cn-qingdao.aliyuncs.com/wod/notary-server-photon:v0.6.1-v1.8.2 && \
docker push registry-vpc.cn-qingdao.aliyuncs.com/wod/notary-server-photon:v0.6.1-v1.8.2
# goharbor/notary-signer-photon
docker pull goharbor/notary-signer-photon:v0.6.1-v1.8.2 && \
docker tag goharbor/notary-signer-photon:v0.6.1-v1.8.2 registry-vpc.cn-qingdao.aliyuncs.com/wod/notary-signer-photon:v0.6.1-v1.8.2 && \
docker push registry-vpc.cn-qingdao.aliyuncs.com/wod/notary-signer-photon:v0.6.1-v1.8.2
```
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
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
- 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 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)
- PVC that can be shared across nodes or external object storage
## 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.
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)
## Installation
## Usage
### Download Chart
Download Harbor helm chart code.
Download Harbor helm chart:
```bash
git clone https://github.com/goharbor/harbor-helm
cd harbor-helm
helm repo add harbor https://helm.goharbor.io
helm fetch harbor/harbor --untar
```
### Configuration
Configure the followings items in `values.yaml`, you can also set them as parameters via `--set` flag during running `helm install`:
- **Ingress rule**
Configure the `expose.ingress.hosts.core` and `expose.ingress.hosts.notary`.
- **External URL**
......@@ -56,8 +65,14 @@ Configure the followings items in `values.yaml`, you can also set them as parame
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
Install the Harbor helm chart with a release name `my-release`:
helm 2:
```bash
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.
**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
## Upgrade
1. **Backup database**
### 1. Backup database
Backup the database used by Harbor in case the upgrade process fails.
2. **Download new chart**
### 2. Download new chart
Download the latest version of Harbor chart.
3. **Configure new chart**
### 3. Configure new chart
Configure the new chart to make sure that the configuration items have the same values with the old one.
**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:
> 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:
1) Get the secret name which certificate is stored in:
```
1) Get the secret name which certificate is stored in:
```bash
kubectl get secret
```
Find the secret whose name ends with `-harbor-ingress`(expose service via `Ingress`) or `-harbor-nginx`(expose service via `ClusterIP` or `NodePort`)
2) Export the secret as yaml file:
```
kubectl get secret secret-name -o yaml > secret.yaml
```
Replace the `secret-name` with the one got in step i
Find the secret whose name ends with `-harbor-ingress` (expose service via `Ingress`) or `-harbor-nginx`(expose service via `ClusterIP` or `NodePort`)
2) Export the secret as yaml file:
3) Rename the secret by setting `metadata.name` in `secret.yaml`
4) Create a new secret:
```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 iii
5) Configure the chart to use the new secret by setting `expose.tls.secretName` as the value you set in step **3**
### 4. Upgrade
4. **Upgrade**
Run upgrade command:
```
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).
```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
- 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.
Then you should be able to visit the Harbor portal at {{ .Values.externalURL }}.
For more details, please visit https://github.com/goharbor/harbor.
\ No newline at end of file
Then you should be able to visit the Harbor portal at {{ .Values.externalURL }}
For more details, please visit https://github.com/goharbor/harbor
This diff is collapsed.
......@@ -6,11 +6,23 @@ metadata:
labels:
{{ include "harbor.labels" . | indent 4 }}
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_ADDR: "{{ template "harbor.redis.host" . }}:{{ template "harbor.redis.port" . }}"
CACHE_REDIS_DB: "{{ template "harbor.redis.chartmuseumDatabaseIndex" . }}"
{{- else }}
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"
{{- if .Values.chartmuseum.absoluteUrl }}
CHART_URL: {{ .Values.externalURL }}/chartrepo
{{- end }}
DEPTH: "1"
{{- if eq .Values.logLevel "debug" }}
DEBUG: "true"
......@@ -22,10 +34,7 @@ data:
DISABLE_API: "false"
DISABLE_STATEFILES: "false"
ALLOW_OVERWRITE: "true"
#CHART_URL: {{ .Values.externalURL }}/chartrepo
AUTH_ANONYMOUS_GET: "false"
TLS_CERT: ""
TLS_KEY: ""
CONTEXT_PATH: ""
INDEX_LIMIT: "0"
MAX_STORAGE_OBJECTS: "0"
......@@ -41,6 +50,7 @@ data:
STORAGE: "microsoft"
STORAGE_MICROSOFT_CONTAINER: {{ $storage.azure.container }}
AZURE_STORAGE_ACCOUNT: {{ $storage.azure.accountname }}
AZURE_BASE_URL: {{ $storage.azure.realm }}
STORAGE_MICROSOFT_PREFIX: "/azure/harbor/charts"
{{- else if eq $storageType "gcs" }}
STORAGE: "google"
......@@ -62,36 +72,39 @@ data:
{{- if $storage.s3.accesskey }}
AWS_ACCESS_KEY_ID: {{ $storage.s3.accesskey }}
{{- end }}
{{- if $storage.s3.keyid }}
STORAGE_AMAZON_SSE: aws:kms
{{- end }}
{{- else if eq $storageType "swift" }}
STORAGE: "openstack"
STORAGE_OPENSTACK_CONTAINER: {{ $storage.swift.container }}
{{- if $storage.swift.secretkey }}
{{- if $storage.swift.prefix }}
STORAGE_OPENSTACK_PREFIX: {{ $storage.swift.prefix }}
{{- end }}
{{- if $storage.swift.secretkey }}
{{- if $storage.swift.region }}
STORAGE_OPENSTACK_REGION: {{ $storage.swift.region }}
{{- end }}
OS_AUTH_URL: {{ $storage.swift.authurl }}
OS_USERNAME: {{ $storage.swift.username }}
{{- if $storage.swift.secretkey }}
{{- if $storage.swift.tenantid }}
OS_PROJECT_ID: {{ $storage.swift.tenantid }}
{{- end }}
{{- if $storage.swift.secretkey }}
{{- if $storage.swift.tenant }}
OS_PROJECT_NAME: {{ $storage.swift.tenant }}
{{- end }}
{{- if $storage.swift.secretkey }}
{{- if $storage.swift.domainid }}
OS_DOMAIN_ID: {{ $storage.swift.domainid }}
{{- end }}
{{- if $storage.swift.secretkey }}
{{- if $storage.swift.domain }}
OS_DOMAIN_NAME: {{ $storage.swift.domain }}
{{- end }}
{{- else if eq $storageType "oss" }}
STORAGE: "alibaba"
STORAGE_ALIBABA_BUCKET: {{ $storage.oss.bucket }}
{{- if $storage.oss.secretkey }}
{{- if $storage.oss.rootdirectory }}
STORAGE_ALIBABA_PREFIX: {{ $storage.oss.rootdirectory }}
{{- end }}
{{- if $storage.oss.secretkey }}
{{- if $storage.oss.endpoint }}
STORAGE_ALIBABA_ENDPOINT: {{ $storage.oss.endpoint }}
{{- end }}
ALIBABA_CLOUD_ACCESS_KEY_ID: {{ $storage.oss.accesskeyid }}
......
......@@ -5,26 +5,45 @@ metadata:
name: "{{ template "harbor.chartmuseum" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
app: chartmuseum
component: chartmuseum
spec:
replicas: {{ .Values.chartmuseum.replicas }}
strategy:
type: {{ .Values.updateStrategy.type }}
{{- if eq .Values.updateStrategy.type "Recreate" }}
rollingUpdate: null
{{- end }}
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
app: chartmuseum
component: chartmuseum
template:
metadata:
labels:
{{ include "harbor.labels" . | indent 8 }}
app: chartmuseum
component: chartmuseum
annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/chartmuseum/chartmuseum-cm.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 }}
{{- 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 }}
{{ toYaml .Values.chartmuseum.podAnnotations | indent 8 }}
{{- end }}
spec:
securityContext:
fsGroup: 10000
{{- if .Values.chartmuseum.serviceAccountName }}
serviceAccountName: {{ .Values.chartmuseum.serviceAccountName }}
{{- end -}}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: chartmuseum
image: {{ .Values.chartmuseum.image.repository }}:{{ .Values.chartmuseum.image.tag }}
......@@ -32,13 +51,15 @@ spec:
livenessProbe:
httpGet:
path: /health
port: 9999
initialDelaySeconds: 1
scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.chartmuseum.containerPort" . }}
initialDelaySeconds: 300
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 9999
scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.chartmuseum.containerPort" . }}
initialDelaySeconds: 1
periodSeconds: 10
{{- if .Values.chartmuseum.resources }}
......@@ -51,30 +72,90 @@ spec:
- secretRef:
name: "{{ template "harbor.chartmuseum" . }}"
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
valueFrom:
secretKeyRef:
name: {{ template "harbor.core" . }}
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:
- containerPort: 9999
- containerPort: {{ template "harbor.chartmuseum.containerPort" . }}
volumeMounts:
- name: data
- name: chartmuseum-data
mountPath: /chart_storage
- name: etc-localtime
mountPath: /etc/localtime
subPath: {{ .Values.persistence.persistentVolumeClaim.chartmuseum.subPath }}
{{- 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:
- name: etc-localtime
hostPath:
path: /etc/localtime
{{- if eq .Values.chartmuseum.storageSpec.type "hostPath" }}
- name: data
- name: chartmuseum-data
hostPath:
path: {{.Values.chartmuseum.storageSpec.hostPath.root | default "/data" }}/{{ .Release.Namespace }}/{{ .Release.Name }}/chartmuseum
{{- else if eq .Values.chartmuseum.storageSpec.type "emptyDir" }}
- name: data
- name: chartmuseum-data
emptyDir: {}
{{- 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 }}
nodeSelector:
{{ toYaml . | indent 8 }}
......
......@@ -7,7 +7,7 @@ metadata:
{{ include "harbor.labels" . | indent 4 }}
type: Opaque
data:
CACHE_REDIS_PASSWORD: {{ include "harbor.redis.rawPassword" . | b64enc | quote }}
CACHE_REDIS_PASSWORD: {{ include "harbor.redis.password" . | b64enc | quote }}
{{- $storage := .Values.persistence.imageChartStorage }}
{{- $storageType := $storage.type }}
{{- if eq $storageType "azure" }}
......
......@@ -7,9 +7,9 @@ metadata:
{{ include "harbor.labels" . | indent 4 }}
spec:
ports:
- port: 80
targetPort: 9999
- port: {{ template "harbor.chartmuseum.servicePort" . }}
targetPort: {{ template "harbor.chartmuseum.containerPort" . }}
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
app: chartmuseum
component: chartmuseum
{{- end }}
\ No newline at end of file
{{ 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:
name: {{ template "harbor.clair" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
app: clair
component: clair
spec:
replicas: {{ .Values.clair.replicas }}
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
app: clair
component: clair
template:
metadata:
labels:
{{ include "harbor.labels" . | indent 8 }}
app: clair
component: clair
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 }}
{{ toYaml .Values.clair.podAnnotations | indent 8 }}
{{- end }}
spec:
securityContext:
fsGroup: 10000
{{- if .Values.clair.serviceAccountName }}
serviceAccountName: {{ .Values.clair.serviceAccountName }}
{{- end -}}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- 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 }}
livenessProbe:
httpGet:
path: /health
port: 6061
initialDelaySeconds: 30
initialDelaySeconds: 300
periodSeconds: 10
readinessProbe:
httpGet:
......@@ -41,38 +55,107 @@ spec:
periodSeconds: 10
args: ["-log-level", "{{ .Values.logLevel }}"]
env:
{{- if .Values.clair.httpProxy }}
{{- if has "clair" .Values.proxy.components }}
- name: HTTP_PROXY
value: {{ .Values.clair.httpProxy }}
{{- end }}
{{- if .Values.clair.httpsProxy }}
value: "{{ .Values.proxy.httpProxy }}"
- name: HTTPS_PROXY
value: {{ .Values.clair.httpsProxy }}
{{- end }}
value: "{{ .Values.proxy.httpsProxy }}"
- name: NO_PROXY
value: "{{ template "harbor.registry" . }},{{ template "harbor.core" . }}"
{{- if .Values.clair.resources }}
value: "{{ template "harbor.noProxy" . }}"
{{- end }}
{{- if .Values.clair.clair.resources }}
resources:
{{ toYaml .Values.clair.resources | indent 10 }}
{{ toYaml .Values.clair.clair.resources | indent 10 }}
{{- end }}
ports:
- containerPort: 6060
volumeMounts:
- name: clair-config
- name: config
mountPath: /etc/clair/config.yaml
subPath: config.yaml
{{- if .Values.internalTLS.enabled }}
- 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 }}
- name: etc-localtime
mountPath: /etc/localtime
volumes:
- name: etc-localtime
hostPath:
path: /etc/localtime
- name: clair-config
configMap:
name: "{{ template "harbor.clair" . }}"
items:
- key: config.yaml
path: config.yaml
- name: config
secret:
secretName: "{{ template "harbor.clair" . }}"
{{- if .Values.internalTLS.enabled }}
- name: clair-internal-certs
secret:
secretName: {{ template "harbor.internalTLS.clair.secretName" . }}
{{- end }}
{{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolume" . | indent 6 }}
{{- end }}
{{- with .Values.clair.nodeSelector }}
nodeSelector:
{{ 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:
{{ include "harbor.labels" . | indent 4 }}
spec:
ports:
- name: clair
port: 6060
- name: health
port: 6061
- name: adapter
port: {{ include "harbor.clairAdapter.servicePort" . }}
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
app: clair
component: clair
{{ end }}
......@@ -7,41 +7,53 @@ metadata:
data:
app.conf: |+
appname = Harbor
runmode = dev
runmode = prod
enablegzip = true
[dev]
httpport = 8080
[prod]
httpport = {{ ternary "8443" "8080" .Values.internalTLS.enabled }}
PORT: "{{ ternary "8443" "8080" .Values.internalTLS.enabled }}"
DATABASE_TYPE: "postgresql"
POSTGRESQL_HOST: "{{ template "harbor.database.host" . }}"
POSTGRESQL_PORT: "{{ template "harbor.database.port" . }}"
POSTGRESQL_USERNAME: "{{ template "harbor.database.username" . }}"
POSTGRESQL_DATABASE: "{{ template "harbor.database.coreDatabase" . }}"
POSTGRESQL_SSLMODE: "{{ template "harbor.database.sslmode" . }}"
POSTGRESQL_MAX_IDLE_CONNS: "{{ .Values.database.maxIdleConns }}"
POSTGRESQL_MAX_OPEN_CONNS: "{{ .Values.database.maxOpenConns }}"
EXT_ENDPOINT: "{{ .Values.externalURL }}"
CORE_URL: "http://{{ template "harbor.core" . }}"
JOBSERVICE_URL: "http://{{ template "harbor.fullname" . }}-jobservice"
REGISTRY_URL: "http://{{ template "harbor.registry" . }}:5000"
TOKEN_SERVICE_URL: "http://{{ template "harbor.core" . }}/service/token"
CORE_URL: "{{ template "harbor.coreURL" . }}"
JOBSERVICE_URL: "{{ template "harbor.jobserviceURL" . }}"
REGISTRY_URL: "{{ template "harbor.registryURL" . }}"
TOKEN_SERVICE_URL: "{{ template "harbor.tokenServiceURL" . }}"
WITH_NOTARY: "{{ .Values.notary.enabled }}"
NOTARY_URL: "http://{{ template "harbor.notary-server" . }}:4443"
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 }}"
CLAIR_DB_HOST: "{{ template "harbor.database.host" . }}"
CLAIR_DB_PORT: "{{ template "harbor.database.port" . }}"
CLAIR_DB_USERNAME: "{{ template "harbor.database.username" . }}"
CLAIR_DB: "{{ template "harbor.database.clairDatabase" . }}"
CLAIR_DB_SSLMODE: "{{ template "harbor.database.sslmode" . }}"
CLAIR_URL: "http://{{ template "harbor.fullname" . }}-clair:6060"
CLAIR_ADAPTER_URL: "{{ template "harbor.clairAdapterURL" . }}"
WITH_TRIVY: {{ .Values.trivy.enabled | quote }}
TRIVY_ADAPTER_URL: "{{ template "harbor.trivyAdapterURL" . }}"
REGISTRY_STORAGE_PROVIDER_NAME: "{{ .Values.persistence.imageChartStorage.type }}"
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 }}"
CONFIG_PATH: "/etc/core/app.conf"
SYNC_REGISTRY: "false"
CHART_CACHE_DRIVER: "redis"
_REDIS_URL: "{{ template "harbor.redisForCore" . }}"
_REDIS_URL_REG: "{{ template "harbor.redisForGC" . }}"
PORTAL_URL: "http://{{ template "harbor.portal" . }}"
REGISTRYCTL_URL: "http://{{ template "harbor.registry" . }}:8080"
CLAIR_HEALTH_CHECK_SERVER_URL: "http://{{ template "harbor.clair" . }}:6061"
\ No newline at end of file
_REDIS_URL_CORE: "{{ template "harbor.redis.urlForCore" . }}"
_REDIS_URL_REG: "{{ template "harbor.redis.urlForRegistry" . }}"
PORTAL_URL: "{{ template "harbor.portalURL" . }}"
REGISTRY_CONTROLLER_URL: "{{ template "harbor.registryControllerURL" . }}"
REGISTRY_CREDENTIAL_USERNAME: "{{ .Values.registry.credentials.username }}"
{{- 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:
name: {{ template "harbor.core" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
app: core
component: core
spec:
replicas: {{ .Values.core.replicas }}
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
app: core
component: core
template:
metadata:
labels:
{{ include "harbor.matchLabels" . | indent 8 }}
app: core
component: core
annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/core/core-cm.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 }}
{{- 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 }}
{{ toYaml .Values.core.podAnnotations | indent 8 }}
{{- end }}
spec:
securityContext:
fsGroup: 10000
{{- if .Values.core.serviceAccountName }}
serviceAccountName: {{ .Values.core.serviceAccountName }}
{{- end -}}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: core
image: {{ .Values.core.image.repository }}:{{ .Values.core.image.tag }}
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:
httpGet:
path: /api/ping
port: 8080
initialDelaySeconds: 20
path: /api/v2.0/ping
scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.core.containerPort" . }}
failureThreshold: 2
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/ping
port: 8080
initialDelaySeconds: 20
path: /api/v2.0/ping
scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.core.containerPort" . }}
failureThreshold: 2
periodSeconds: 10
envFrom:
- configMapRef:
......@@ -55,9 +79,19 @@ spec:
valueFrom:
secretKeyRef:
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:
- containerPort: 8080
- containerPort: {{ template "harbor.core.containerPort" . }}
volumeMounts:
- name: etc-localtime
mountPath: /etc/localtime
......@@ -72,11 +106,22 @@ spec:
subPath: tls.key
{{- if .Values.expose.tls.enabled }}
- name: ca-download
mountPath: /etc/core/ca/ca.crt
subPath: ca.crt
mountPath: /etc/core/ca
{{- 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 }}
- name: psc
mountPath: /etc/core/token
{{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolumeMount" . | indent 8 }}
{{- end }}
{{- if .Values.core.resources }}
resources:
{{ toYaml .Values.core.resources | indent 10 }}
......@@ -88,6 +133,9 @@ spec:
- name: config
configMap:
name: {{ template "harbor.core" . }}
items:
- key: app.conf
path: app.conf
- name: secret-key
secret:
secretName: {{ template "harbor.core" . }}
......@@ -104,19 +152,32 @@ spec:
{{- if .Values.expose.tls.enabled }}
- name: ca-download
secret:
{{- if eq (include "harbor.autoGenCertForIngress" .) "true" }}
{{- if .Values.caSecretName }}
secretName: {{ .Values.caSecretName }}
{{- else if eq (include "harbor.autoGenCertForIngress" .) "true" }}
secretName: "{{ template "harbor.ingress" . }}"
{{- else if eq (include "harbor.autoGenCertForNginx" .) "true" }}
secretName: {{ template "harbor.nginx" . }}
{{- else }}
secretName: {{ .Values.expose.tls.secretName }}
secretName: {{ template "harbor.tlsSecretForNginx" . }}
{{- end }}
{{- end }}
{{- if .Values.uaaSecretName }}
- name: auth-ca-cert
secret:
secretName: {{ .Values.uaaSecretName }}
items:
- 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 }}
- name: psc
emptyDir: {}
{{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolume" . | indent 6 }}
{{- end }}
{{- with .Values.core.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 8 }}
......
......@@ -14,6 +14,5 @@ data:
{{- end }}
HARBOR_ADMIN_PASSWORD: {{ .Values.harborAdminPassword | b64enc | quote }}
POSTGRESQL_PASSWORD: {{ template "harbor.database.encryptedPassword" . }}
{{- if .Values.clair.enabled }}
CLAIR_DB_PASSWORD: {{ template "harbor.database.encryptedPassword" . }}
{{- end }}
\ No newline at end of file
REGISTRY_CREDENTIAL_PASSWORD: {{ .Values.registry.credentials.password | b64enc | quote }}
CSRF_KEY: {{ .Values.core.xsrfKey | default (randAlphaNum 32) | b64enc | quote }}
......@@ -9,8 +9,8 @@ spec:
type: NodePort
{{- end }}
ports:
- port: 80
targetPort: 8080
- port: {{ template "harbor.core.servicePort" . }}
targetPort: {{ template "harbor.core.containerPort" . }}
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
app: core
component: core
......@@ -6,36 +6,52 @@ metadata:
name: "{{ template "harbor.database" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
app: database
component: database
spec:
replicas: 1
serviceName: "{{ template "harbor.database" . }}"
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
app: database
component: database
template:
metadata:
labels:
{{ include "harbor.labels" . | indent 8 }}
app: database
component: database
annotations:
checksum/secret: {{ include (print $.Template.BasePath "/database/database-secret.yaml") . | sha256sum }}
{{- if .Values.database.podAnnotations }}
{{ toYaml .Values.database.podAnnotations | indent 8 }}
{{- end }}
spec:
tolerations:
- effect: NoSchedule
operator: Exists
{{- if .Values.database.internal.serviceAccountName }}
serviceAccountName: {{ .Values.database.internal.serviceAccountName }}
{{- end -}}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
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"
image: {{ .Values.database.internal.image.repository }}:{{ .Values.database.internal.image.tag }}
imagePullPolicy: {{ .Values.imagePullPolicy }}
command: ["rm", "-Rf", "/var/lib/postgresql/data/lost+found"]
volumeMounts:
- name: data
- name: database-data
mountPath: /var/lib/postgresql/data
subPath: {{ $database.subPath }}
containers:
- name: database
image: {{ .Values.database.internal.image.repository }}:{{ .Values.database.internal.image.tag }}
......@@ -44,7 +60,7 @@ spec:
exec:
command:
- /docker-healthcheck.sh
initialDelaySeconds: 60
initialDelaySeconds: 300
periodSeconds: 10
readinessProbe:
exec:
......@@ -62,18 +78,20 @@ spec:
volumeMounts:
- name: etc-localtime
mountPath: /etc/localtime
- name: data
- name: database-data
mountPath: /var/lib/postgresql/data
subPath: {{ $database.subPath }}
{{- if not .Values.persistence.enabled }}
volumes:
- name: etc-localtime
hostPath:
path: /etc/localtime
{{- if eq .Values.database.internal.storageSpec.type "hostPath" }}
- name: data
- name: "database-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
- name: "database-data"
emptyDir: {}
{{- end }}
{{- with .Values.database.internal.nodeSelector }}
......@@ -91,11 +109,11 @@ spec:
{{- if eq .Values.database.internal.storageSpec.type "volumeClaimTemplate" }}
volumeClaimTemplates:
- metadata:
name: "data"
name: "database-data"
labels:
{{ include "harbor.labels" . | indent 8 }}
app: database
spec:
{{ toYaml $.Values.database.internal.storageSpec.volumeClaimTemplate.spec | indent 6 }}
{{- end }}
{{- end -}}
{{- end -}}
{{- end -}}
......@@ -10,5 +10,5 @@ spec:
- port: 5432
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
app: database
component: database
{{- end -}}
\ No newline at end of file
......@@ -8,13 +8,15 @@
{{- $_ := set . "v2_path" "/v2/*" -}}
{{- $_ := set . "chartrepo_path" "/chartrepo/*" -}}
{{- $_ := set . "controller_path" "/c/*" -}}
{{- $_ := set . "notary_path" "/" -}}
{{- else if eq .Values.expose.ingress.controller "ncp" }}
{{- $_ := set . "portal_path" "/" -}}
{{- $_ := set . "portal_path" "/.*" -}}
{{- $_ := set . "api_path" "/api/.*" -}}
{{- $_ := set . "service_path" "/service/.*" -}}
{{- $_ := set . "v2_path" "/v2/.*" -}}
{{- $_ := set . "chartrepo_path" "/chartrepo/.*" -}}
{{- $_ := set . "controller_path" "/c/.*" -}}
{{- $_ := set . "notary_path" "/.*" -}}
{{- else }}
{{- $_ := set . "portal_path" "/" -}}
{{- $_ := set . "api_path" "/api/" -}}
......@@ -22,8 +24,15 @@
{{- $_ := set . "v2_path" "/v2/" -}}
{{- $_ := set . "chartrepo_path" "/chartrepo/" -}}
{{- $_ := set . "controller_path" "/c/" -}}
{{- $_ := set . "notary_path" "/" -}}
{{- end }}
---
{{- 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" . }}"
......@@ -31,36 +40,23 @@ metadata:
{{ include "harbor.labels" . | indent 4 }}
annotations:
{{ 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:
{{- if $tls.enabled }}
tls:
{{- if $tls.secretName }}
- secretName: {{ $tls.secretName }}
{{- else }}
- secretName: "{{ template "harbor.ingress" . }}"
{{- end }}
- secretName: {{ template "harbor.tlsCoreSecretForIngress" . }}
{{- if $ingress.hosts.core }}
hosts:
- {{ $ingress.hosts.core }}
{{- 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 }}
rules:
- http:
......@@ -68,41 +64,72 @@ spec:
- path: {{ .portal_path }}
backend:
serviceName: {{ template "harbor.portal" . }}
servicePort: 80
servicePort: {{ template "harbor.portal.servicePort" . }}
- path: {{ .api_path }}
backend:
serviceName: {{ template "harbor.core" . }}
servicePort: 80
servicePort: {{ template "harbor.core.servicePort" . }}
- path: {{ .service_path }}
backend:
serviceName: {{ template "harbor.core" . }}
servicePort: 80
servicePort: {{ template "harbor.core.servicePort" . }}
- path: {{ .v2_path }}
backend:
serviceName: {{ template "harbor.core" . }}
servicePort: 80
servicePort: {{ template "harbor.core.servicePort" . }}
- path: {{ .chartrepo_path }}
backend:
serviceName: {{ template "harbor.core" . }}
servicePort: 80
servicePort: {{ template "harbor.core.servicePort" . }}
- path: {{ .controller_path }}
backend:
serviceName: {{ template "harbor.core" . }}
servicePort: 80
servicePort: {{ template "harbor.core.servicePort" . }}
{{- if $ingress.hosts.core }}
host: {{ $ingress.hosts.core }}
{{- 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:
paths:
- path: /
- path: {{ .notary_path }}
backend:
serviceName: {{ template "harbor.notary-server" . }}
servicePort: 4443
{{- if $ingress.hosts.notary }}
host: {{ $ingress.hosts.notary }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
---
apiVersion: bcc.bd-apaas.com/v1alpha1
......@@ -120,7 +147,7 @@ spec:
priority: 0
services:
- kind: Service
name: harbor-portal
name: {{ template "harbor.portal" . }}
namespace: devops
port: 80
- kind: Rule
......@@ -129,7 +156,7 @@ spec:
priority: 0
services:
- kind: Service
name: harbor-core
name: {{ template "harbor.core" . }}
namespace: devops
port: 80
- kind: Rule
......@@ -138,7 +165,7 @@ spec:
priority: 0
services:
- kind: Service
name: harbor-core
name: {{ template "harbor.core" . }}
namespace: devops
port: 80
- kind: Rule
......@@ -147,7 +174,7 @@ spec:
priority: 0
services:
- kind: Service
name: harbor-core
name: {{ template "harbor.core" . }}
namespace: devops
port: 80
- kind: Rule
......@@ -156,7 +183,7 @@ spec:
priority: 0
services:
- kind: Service
name: harbor-core
name: {{ template "harbor.core" . }}
namespace: devops
port: 80
- kind: Rule
......@@ -165,7 +192,7 @@ spec:
priority: 0
services:
- kind: Service
name: harbor-core
name: {{ template "harbor.core" . }}
namespace: devops
port: 80
- kind: Rule
......@@ -174,7 +201,7 @@ spec:
priority: 0
services:
- kind: Service
name: harbor-notary-server
name: {{ template "harbor.notary-server" . }}
namespace: devops
port: 4443
tls:
......@@ -191,7 +218,7 @@ spec:
apiVersion: bcc.bd-apaas.com/v1alpha1
kind: IngressHost
metadata:
name: harbor-natory
name: harbor-notary
namespace: {{ .Release.Namespace }}
spec:
host: {{ .Values.expose.ingress.hosts.notary }}
{{- 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:
{{ include "harbor.labels" . | indent 4 }}
data:
config.yml: |+
protocol: "http"
port: 8080
#Server listening port
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:
workers: {{ .Values.jobservice.maxJobWorkers }}
backend: "redis"
redis_pool:
redis_url: "{{ template "harbor.redisForJobservice" . }}"
redis_url: "{{ template "harbor.redis.urlForJobservice" . }}"
namespace: "harbor_job_service_namespace"
idle_timeout_second: 3600
job_loggers:
{{- if eq .Values.jobservice.jobLogger "file" }}
- name: "FILE"
......
......@@ -4,26 +4,46 @@ metadata:
name: "{{ template "harbor.jobservice" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
app: jobservice
component: jobservice
spec:
replicas: {{ .Values.jobservice.replicas }}
strategy:
type: {{ .Values.updateStrategy.type }}
{{- if eq .Values.updateStrategy.type "Recreate" }}
rollingUpdate: null
{{- end }}
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
app: jobservice
component: jobservice
template:
metadata:
labels:
{{ include "harbor.labels" . | indent 8 }}
app: jobservice
component: jobservice
annotations:
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-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 }}
{{ toYaml .Values.jobservice.podAnnotations | indent 8 }}
{{- end }}
spec:
securityContext:
fsGroup: 10000
{{- if .Values.jobservice.serviceAccountName }}
serviceAccountName: {{ .Values.jobservice.serviceAccountName }}
{{- end -}}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: jobservice
image: {{ .Values.jobservice.image.repository }}:{{ .Values.jobservice.image.tag }}
......@@ -31,13 +51,15 @@ spec:
livenessProbe:
httpGet:
path: /api/v1/stats
port: 8080
initialDelaySeconds: 20
scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.jobservice.containerPort" . }}
initialDelaySeconds: 300
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/v1/stats
port: 8080
scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.jobservice.containerPort" . }}
initialDelaySeconds: 20
periodSeconds: 10
{{- if .Values.jobservice.resources }}
......@@ -50,25 +72,36 @@ spec:
secretKeyRef:
name: {{ template "harbor.core" . }}
key: secret
- name: JOBSERVICE_SECRET
valueFrom:
secretKeyRef:
{{- if .Values.internalTLS.enabled }}
- name: INTERNAL_TLS_ENABLED
value: "true"
- name: INTERNAL_TLS_KEY_PATH
value: /etc/harbor/ssl/jobservice/tls.key
- name: INTERNAL_TLS_CERT_PATH
value: /etc/harbor/ssl/jobservice/tls.crt
- name: INTERNAL_TLS_TRUST_CA_PATH
value: /etc/harbor/ssl/jobservice/ca.crt
{{- end }}
envFrom:
- configMapRef:
name: "{{ template "harbor.jobservice" . }}-env"
- secretRef:
name: "{{ template "harbor.jobservice" . }}"
key: secret
- name: CORE_URL
value: "http://{{ template "harbor.core" . }}"
- name: REGISTRY_CONTROLLER_URL
value: "http://{{ template "harbor.registry" . }}:8080"
- name: LOG_LEVEL
value: debug
ports:
- containerPort: 8080
- containerPort: {{ template "harbor.jobservice.containerPort" . }}
volumeMounts:
- name: jobservice-config
mountPath: /etc/jobservice/config.yml
subPath: config.yml
- name: data
- name: job-logs
mountPath: /var/log/jobs
{{- if .Values.internalTLS.enabled }}
- name: jobservice-internal-certs
mountPath: /etc/harbor/ssl/jobservice
{{- end }}
{{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolumeMount" . | indent 8 }}
{{- end }}
- name: etc-localtime
mountPath: /etc/localtime
volumes:
......@@ -78,8 +111,16 @@ spec:
- name: jobservice-config
configMap:
name: "{{ template "harbor.jobservice" . }}"
- name: data
- name: job-logs
emptyDir: {}
{{- 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 }}
nodeSelector:
{{ toYaml . | indent 8 }}
......
......@@ -6,4 +6,5 @@ metadata:
{{ include "harbor.labels" . | indent 4 }}
type: Opaque
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:
{{ include "harbor.labels" . | indent 4 }}
spec:
ports:
- port: 80
targetPort: 8080
- port: {{ template "harbor.jobservice.servicePort" . }}
targetPort: {{ template "harbor.jobservice.containerPort" . }}
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
app: jobservice
component: jobservice
{{- if and (ne .Values.expose.type "ingress") (not .Values.expose.tls.enabled) }}
{{- $scheme := (include "harbor.component.scheme" .) -}}
apiVersion: v1
kind: ConfigMap
metadata:
......@@ -8,6 +9,7 @@ metadata:
data:
nginx.conf: |+
worker_processes auto;
pid /tmp/nginx.pid;
events {
worker_connections 1024;
......@@ -16,20 +18,25 @@ data:
}
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;
# this is necessary for us to be able to disable request buffering in all cases
proxy_http_version 1.1;
upstream core {
server {{ template "harbor.core" . }};
server "{{ template "harbor.core" . }}:{{ template "harbor.core.servicePort" . }}";
}
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 '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time $pipe';
......@@ -37,13 +44,17 @@ data:
access_log /dev/stdout timed_combined;
server {
listen 80;
listen 8080;
server_tokens off;
# disable any limits to avoid HTTP 413 for large image uploads
client_max_body_size 0;
# Add extra headers
add_header X-Frame-Options DENY;
add_header Content-Security-Policy "frame-ancestors 'none'";
location / {
proxy_pass http://portal/;
proxy_pass {{ $scheme }}://portal/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
......@@ -56,7 +67,11 @@ data:
}
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 X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
......@@ -69,7 +84,11 @@ data:
}
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 X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
......@@ -82,7 +101,7 @@ data:
}
location /c/ {
proxy_pass http://core/c/;
proxy_pass {{ $scheme }}://core/c/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
......@@ -99,7 +118,7 @@ data:
}
location /v2/ {
proxy_pass http://core/v2/;
proxy_pass {{ $scheme }}://core/v2/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
......@@ -111,7 +130,7 @@ data:
}
location /service/ {
proxy_pass http://core/service/;
proxy_pass {{ $scheme }}://core/service/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
......@@ -129,4 +148,3 @@ data:
}
}
{{- end }}
\ No newline at end of file
{{- if and (ne .Values.expose.type "ingress") .Values.expose.tls.enabled }}
{{- $scheme := (include "harbor.component.scheme" .) -}}
apiVersion: v1
kind: ConfigMap
metadata:
......@@ -8,6 +9,7 @@ metadata:
data:
nginx.conf: |+
worker_processes auto;
pid /tmp/nginx.pid;
events {
worker_connections 1024;
......@@ -16,17 +18,22 @@ data:
}
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;
# this is necessary for us to be able to disable request buffering in all cases
proxy_http_version 1.1;
upstream core {
server {{ template "harbor.core" . }};
server "{{ template "harbor.core" . }}:{{ template "harbor.core.servicePort" . }}";
}
upstream portal {
server {{ template "harbor.portal" . }};
server "{{ template "harbor.portal" . }}:{{ template "harbor.portal.servicePort" . }}";
}
{{- if .Values.notary.enabled }}
......@@ -35,7 +42,7 @@ data:
}
{{- end }}
log_format timed_combined 'remote_addr - '
log_format timed_combined '[$time_local]:$remote_addr - '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time $pipe';
......@@ -78,7 +85,7 @@ data:
{{- end }}
server {
listen 443 ssl;
listen 8443 ssl;
# server_name harbordomain.com;
server_tokens off;
# SSL
......@@ -97,8 +104,13 @@ data:
# required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
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 / {
proxy_pass http://portal/;
proxy_pass {{ $scheme }}://portal/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
......@@ -106,15 +118,18 @@ data:
# 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;
# Add Secure flag when serving HTTPS
proxy_cookie_path / "/; secure";
proxy_cookie_path / "/; HttpOnly; Secure";
proxy_buffering off;
proxy_request_buffering off;
}
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 X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
......@@ -122,12 +137,18 @@ data:
# 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_cookie_path / "/; Secure";
proxy_buffering off;
proxy_request_buffering off;
}
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 X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
......@@ -135,12 +156,14 @@ data:
# 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_cookie_path / "/; Secure";
proxy_buffering off;
proxy_request_buffering off;
}
location /c/ {
proxy_pass http://core/c/;
proxy_pass {{ $scheme }}://core/c/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
......@@ -148,6 +171,8 @@ data:
# 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_cookie_path / "/; Secure";
proxy_buffering off;
proxy_request_buffering off;
}
......@@ -157,7 +182,7 @@ data:
}
location /v2/ {
proxy_pass http://core/v2/;
proxy_pass {{ $scheme }}://core/v2/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
......@@ -169,7 +194,7 @@ data:
}
location /service/ {
proxy_pass http://core/service/;
proxy_pass {{ $scheme }}://core/service/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
......@@ -177,6 +202,8 @@ data:
# 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_cookie_path / "/; Secure";
proxy_buffering off;
proxy_request_buffering off;
}
......@@ -186,10 +213,9 @@ data:
}
}
server {
listen 80;
listen 8080;
#server_name harbordomain.com;
return 301 https://$host$request_uri;
}
}
{{- end }}
\ No newline at end of file
{{- if ne .Values.expose.type "ingress" }}
apiVersion: extensions/v1beta1
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "harbor.nginx" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
app: nginx
component: nginx
spec:
replicas: 1
replicas: {{ .Values.nginx.replicas }}
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
app: nginx
component: nginx
template:
metadata:
labels:
{{ include "harbor.labels" . | indent 8 }}
app: nginx
component: nginx
annotations:
{{- if not .Values.expose.tls.enabled }}
checksum/configmap: {{ include (print $.Template.BasePath "/nginx/configmap-http.yaml") . | sha256sum }}
......@@ -30,20 +30,37 @@ spec:
{{ toYaml .Values.nginx.podAnnotations | indent 8 }}
{{- end }}
spec:
{{- if .Values.nginx.serviceAccountName }}
serviceAccountName: {{ .Values.nginx.serviceAccountName }}
{{- end }}
securityContext:
fsGroup: 10000
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: nginx
image: "{{ .Values.nginx.image.repository }}:{{ .Values.nginx.image.tag }}"
imagePullPolicy: "{{ .Values.imagePullPolicy }}"
{{- $_ := set . "scheme" "HTTP" -}}
{{- $_ := set . "port" "8080" -}}
{{- if .Values.expose.tls.enabled }}
{{- $_ := set . "scheme" "HTTPS" -}}
{{- $_ := set . "port" "8443" -}}
{{- end }}
livenessProbe:
httpGet:
scheme: {{ .scheme }}
path: /
port: 80
initialDelaySeconds: 1
port: {{ .port }}
initialDelaySeconds: 300
periodSeconds: 10
readinessProbe:
httpGet:
scheme: {{ .scheme }}
path: /
port: 80
port: {{ .port }}
initialDelaySeconds: 1
periodSeconds: 10
{{- if .Values.nginx.resources }}
......@@ -51,8 +68,8 @@ spec:
{{ toYaml .Values.nginx.resources | indent 10 }}
{{- end }}
ports:
- containerPort: 80
- containerPort: 443
- containerPort: 8080
- containerPort: 8443
- containerPort: 4443
volumeMounts:
- name: config
......@@ -69,11 +86,7 @@ spec:
{{- if .Values.expose.tls.enabled }}
- name: certificate
secret:
{{- if .Values.expose.tls.secretName }}
secretName: {{ .Values.expose.tls.secretName }}
{{- else }}
secretName: {{ template "harbor.nginx" . }}
{{- end }}
secretName: {{ template "harbor.tlsSecretForNginx" . }}
{{- end }}
{{- with .Values.nginx.nodeSelector }}
nodeSelector:
......
{{- if eq (include "harbor.autoGenCertForNginx" .) "true" }}
{{- $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
kind: Secret
metadata:
......
......@@ -5,7 +5,6 @@ metadata:
{{- if eq .Values.expose.type "clusterIP" }}
{{- $clusterIP := .Values.expose.clusterIP }}
name: {{ $clusterIP.name }}
labels:
{{ include "harbor.labels" . | indent 4 }}
spec:
......@@ -13,11 +12,11 @@ spec:
ports:
- name: http
port: {{ $clusterIP.ports.httpPort }}
targetPort: 80
targetPort: 8080
{{- if .Values.expose.tls.enabled }}
- name: https
port: {{ $clusterIP.ports.httpsPort }}
targetPort: 443
targetPort: 8443
{{- end }}
{{- if .Values.notary.enabled }}
- name: notary
......@@ -34,14 +33,14 @@ spec:
ports:
- name: http
port: {{ $nodePort.ports.http.port }}
targetPort: 80
targetPort: 8080
{{- if $nodePort.ports.http.nodePort }}
nodePort: {{ $nodePort.ports.http.nodePort }}
{{- end }}
{{- if .Values.expose.tls.enabled }}
- name: https
port: {{ $nodePort.ports.https.port }}
targetPort: 443
targetPort: 8443
{{- if $nodePort.ports.https.nodePort }}
nodePort: {{ $nodePort.ports.https.nodePort }}
{{- end }}
......@@ -59,19 +58,27 @@ spec:
name: {{ $loadBalancer.name }}
labels:
{{ include "harbor.labels" . | indent 4 }}
{{- with $loadBalancer.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: LoadBalancer
{{- with $loadBalancer.sourceRanges }}
loadBalancerSourceRanges:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- if $loadBalancer.IP }}
loadBalancerIP: {{ $loadBalancer.IP }}
{{- end }}
ports:
- name: http
port: {{ $loadBalancer.ports.httpPort }}
targetPort: 80
targetPort: 8080
{{- if .Values.expose.tls.enabled }}
- name: https
port: {{ $loadBalancer.ports.httpsPort }}
targetPort: 443
targetPort: 8443
{{- end }}
{{- if .Values.notary.enabled }}
- name: notary
......@@ -81,5 +88,5 @@ spec:
{{- end }}
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
app: nginx
component: nginx
{{- end }}
{{ 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:
name: {{ template "harbor.notary-server" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
app: notary-server
component: notary-server
spec:
replicas: {{ .Values.notary.server.replicas }}
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
app: notary-server
component: notary-server
template:
metadata:
labels:
{{ include "harbor.labels" . | indent 8 }}
app: notary-server
component: notary-server
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 }}
{{- if .Values.notary.podAnnotations }}
{{ toYaml .Values.notary.podAnnotations | indent 8 }}
{{- end }}
spec:
securityContext:
fsGroup: 10000
{{- if .Values.notary.server.serviceAccountName }}
serviceAccountName: {{ .Values.notary.server.serviceAccountName }}
{{- end -}}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: notary-server
image: {{ .Values.notary.server.image.repository }}:{{ .Values.notary.server.image.tag }}
......@@ -38,36 +47,37 @@ spec:
- name: DB_URL
value: {{ template "harbor.database.notaryServer" . }}
volumeMounts:
- name: notary-config
mountPath: /etc/notary
- name: etc-localtime
mountPath: /etc/localtime
- name: root-certificate
- name: config
mountPath: /etc/notary/server-config.postgres.json
subPath: server.json
- name: token-service-certificate
mountPath: /root.crt
subPath: tls.crt
{{- if .Values.notary.secretName }}
- name: notary-ca
mountPath: /etc/ssl/notary/cert/notary-signer-ca.crt
subPath: ca
{{- end }}
- name: signer-certificate
mountPath: /etc/ssl/notary/ca.crt
subPath: ca.crt
- name: etc-localtime
mountPath: /etc/localtime
volumes:
- name: etc-localtime
hostPath:
path: /etc/localtime
- name: notary-config
configMap:
name: "{{ template "harbor.notary-server" . }}"
- name: root-certificate
- name: config
secret:
secretName: "{{ template "harbor.notary-server" . }}"
- name: token-service-certificate
secret:
{{- if .Values.core.secretName }}
secretName: {{ .Values.core.secretName }}
{{- else }}
secretName: {{ template "harbor.core" . }}
{{- end }}
{{- if .Values.notary.secretName }}
- name: notary-ca
- name: signer-certificate
secret:
{{- if .Values.notary.secretName }}
secretName: {{ .Values.notary.secretName }}
{{- else }}
secretName: {{ template "harbor.notary-server" . }}
{{- end }}
{{- with .Values.notary.nodeSelector }}
nodeSelector:
......
......@@ -5,21 +5,30 @@ metadata:
name: {{ template "harbor.notary-signer" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
app: notary-signer
component: notary-signer
spec:
replicas: {{ .Values.notary.signer.replicas }}
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
app: notary-signer
component: notary-signer
template:
metadata:
labels:
{{ include "harbor.labels" . | indent 8 }}
app: notary-signer
component: notary-signer
annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/notary/notary-cm.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/notary/notary-secret.yaml") . | sha256sum }}
spec:
securityContext:
fsGroup: 10000
{{- if .Values.notary.signer.serviceAccountName }}
serviceAccountName: {{ .Values.notary.signer.serviceAccountName }}
{{- end -}}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: notary-signer
image: {{ .Values.notary.signer.image.repository }}:{{ .Values.notary.signer.image.tag }}
......@@ -36,32 +45,30 @@ spec:
- name: NOTARY_SIGNER_DEFAULTALIAS
value: defaultalias
volumeMounts:
- name: notary-config
mountPath: /etc/notary
- name: config
mountPath: /etc/notary/signer-config.postgres.json
subPath: signer.json
- name: signer-certificate
mountPath: /etc/ssl/notary/tls.crt
subPath: tls.crt
- name: signer-certificate
mountPath: /etc/ssl/notary/tls.key
subPath: tls.key
- name: etc-localtime
mountPath: /etc/localtime
{{- if .Values.notary.secretName }}
- name: notary-cert
mountPath: /etc/ssl/notary/cert/notary-signer-ca.crt
subPath: ca
- name: notary-cert
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:
- name: etc-localtime
hostPath:
path: /etc/localtime
- name: notary-config
configMap:
name: "{{ template "harbor.notary-server" . }}"
{{- if .Values.notary.secretName }}
- name: notary-cert
- name: config
secret:
secretName: "{{ template "harbor.notary-server" . }}"
- name: signer-certificate
secret:
{{- if .Values.notary.secretName }}
secretName: {{ .Values.notary.secretName }}
{{- else }}
secretName: {{ template "harbor.notary-server" . }}
{{- end }}
{{- with .Values.notary.nodeSelector }}
nodeSelector:
......
......@@ -13,7 +13,7 @@ spec:
- port: 4443
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
app: notary-server
component: notary-server
---
apiVersion: v1
......@@ -27,5 +27,5 @@ spec:
- port: 7899
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
app: notary-signer
component: notary-signer
{{ 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:
name: "{{ template "harbor.portal" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
app: portal
component: portal
spec:
replicas: {{ .Values.portal.replicas }}
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
app: portal
component: portal
template:
metadata:
labels:
{{ include "harbor.matchLabels" . | indent 8 }}
app: portal
component: portal
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 }}
{{ toYaml .Values.portal.podAnnotations | indent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.portal.serviceAccountName }}
serviceAccountName: {{ .Values.portal.serviceAccountName }}
{{- end }}
containers:
- name: portal
image: {{ .Values.portal.image.repository }}:{{ .Values.portal.image.tag }}
......@@ -32,24 +44,41 @@ spec:
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 1
scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.portal.containerPort" . }}
initialDelaySeconds: 300
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.portal.containerPort" . }}
initialDelaySeconds: 1
periodSeconds: 10
ports:
- containerPort: 80
- containerPort: {{ template "harbor.portal.containerPort" . }}
volumeMounts:
- name: portal-config
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
{{- if .Values.internalTLS.enabled }}
- name: portal-internal-certs
mountPath: /etc/harbor/ssl/portal
{{- end }}
- name: etc-localtime
mountPath: /etc/localtime
volumes:
- name: etc-localtime
hostPath:
path: /etc/localtime
- name: portal-config
configMap:
name: "{{ template "harbor.portal" . }}"
{{- if .Values.internalTLS.enabled }}
- name: portal-internal-certs
secret:
secretName: {{ template "harbor.internalTLS.portal.secretName" . }}
{{- end }}
{{- with .Values.portal.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 8 }}
......
......@@ -5,12 +5,9 @@ metadata:
labels:
{{ include "harbor.labels" . | indent 4 }}
spec:
{{- if (eq .Values.expose.ingress.controller "gce") }}
type: NodePort
{{- end }}
ports:
- port: 80
targetPort: 80
- port: {{ template "harbor.portal.servicePort" . }}
targetPort: {{ template "harbor.portal.containerPort" . }}
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
app: portal
component: portal
......@@ -10,5 +10,5 @@ spec:
- port: 6379
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
app: redis
component: redis
{{- end -}}
\ No newline at end of file
......@@ -6,24 +6,33 @@ metadata:
name: {{ template "harbor.redis" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
app: redis
component: redis
spec:
replicas: 1
serviceName: {{ template "harbor.redis" . }}
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
app: redis
component: redis
template:
metadata:
labels:
{{ include "harbor.labels" . | indent 8 }}
app: redis
component: redis
{{- if .Values.redis.podAnnotations }}
annotations:
{{ toYaml .Values.redis.podAnnotations | indent 8 }}
{{- end }}
spec:
securityContext:
fsGroup: 999
{{- if .Values.redis.internal.serviceAccountName }}
serviceAccountName: {{ .Values.redis.internal.serviceAccountName }}
{{- end -}}
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: redis
image: {{ .Values.redis.internal.image.repository }}:{{ .Values.redis.internal.image.tag }}
......@@ -31,7 +40,7 @@ spec:
livenessProbe:
tcpSocket:
port: 6379
initialDelaySeconds: 1
initialDelaySeconds: 300
periodSeconds: 10
readinessProbe:
tcpSocket:
......@@ -43,16 +52,24 @@ spec:
{{ toYaml .Values.redis.internal.resources | indent 10 }}
{{- end }}
volumeMounts:
- name: data
mountPath: /var/lib/redis
- name: etc-localtime
mountPath: /etc/localtime
- name: data
mountPath: /var/lib/redis
subPath: {{ $redis.subPath }}
{{- if not .Values.persistence.enabled }}
volumes:
- name: etc-localtime
hostPath:
path: /etc/localtime
- name: data
emptyDir: {}
{{- else if $redis.existingClaim }}
volumes:
- name: data
persistentVolumeClaim:
claimName: {{ $redis.existingClaim }}
{{- end -}}
{{- with .Values.redis.internal.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 8 }}
......@@ -65,4 +82,23 @@ spec:
tolerations:
{{ toYaml . | indent 8 }}
{{- 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:
config.yml: |+
version: 0.1
log:
{{- if eq .Values.logLevel "warning" }}
level: warn
{{- else if eq .Values.logLevel "fatal" }}
level: error
{{- else }}
level: {{ .Values.logLevel }}
{{- end }}
fields:
service: registry
storage:
......@@ -47,9 +53,15 @@ data:
{{- if $storage.s3.encrypt }}
encrypt: {{ $storage.s3.encrypt }}
{{- end }}
{{- if $storage.s3.keyid }}
keyid: {{ $storage.s3.keyid }}
{{- end }}
{{- if $storage.s3.secure }}
secure: {{ $storage.s3.secure }}
{{- end }}
{{- if and $storage.s3.secure $storage.s3.skipverify }}
skipverify: {{ $storage.s3.skipverify }}
{{- end }}
{{- if $storage.s3.v4auth }}
v4auth: {{ $storage.s3.v4auth }}
{{- end }}
......@@ -62,6 +74,15 @@ data:
{{- if $storage.s3.storageclass }}
storageclass: {{ $storage.s3.storageclass }}
{{- 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" }}
swift:
authurl: {{ $storage.swift.authurl }}
......@@ -140,32 +161,64 @@ data:
redirect:
disable: {{ $storage.disableredirect }}
redis:
addr: "{{ template "harbor.redis.host" . }}:{{ template "harbor.redis.port" . }}"
db: {{ template "harbor.redis.registryDatabaseIndex" . }}
addr: {{ template "harbor.redis.addr" . }}
{{- 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:
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
# secret: placeholder
debug:
addr: localhost:5001
auth:
token:
issuer: harbor-token-issuer
realm: "{{ .Values.externalURL }}/service/token"
rootcertbundle: /etc/registry/root.crt
service: harbor-registry
htpasswd:
realm: harbor-registry-basic-realm
path: /etc/registry/passwd
validation:
disabled: true
notifications:
endpoints:
- name: harbor
disabled: false
url: http://{{ template "harbor.core" . }}/service/notifications
timeout: 3000ms
threshold: 5
backoff: 1s
compatibility:
schema1:
enabled: true
{{- if .Values.registry.middleware.enabled }}
{{- $middleware := .Values.registry.middleware }}
{{- $middlewareType := $middleware.type }}
{{- 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: |+
---
{{- 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"
port: 8080
{{- end }}
log_level: {{ .Values.logLevel }}
registry_config: "/etc/registry/config.yml"
......@@ -6,8 +6,9 @@ metadata:
{{ include "harbor.labels" . | indent 4 }}
type: Opaque
data:
REGISTRY_HTPASSWD: {{ .Values.registry.credentials.htpasswd | 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 }}
{{- $type := $storage.type }}
{{- if eq $type "azure" }}
......
......@@ -7,9 +7,9 @@ metadata:
spec:
ports:
- name: registry
port: 5000
port: {{ template "harbor.registry.servicePort" . }}
- name: controller
port: 8080
port: {{ template "harbor.registryctl.servicePort" . }}
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
app: registry
\ No newline at end of file
component: registry
\ No newline at end of file
{{- if .Values.trivy.enabled }}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "harbor.trivy" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
type: Opaque
data:
redisURL: {{ include "harbor.redis.urlForTrivy" . | b64enc }}
gitHubToken: {{ .Values.trivy.gitHubToken | default "" | b64enc | quote }}
{{- end }}
{{- if .Values.trivy.enabled }}
{{- $trivy := .Values.persistence.persistentVolumeClaim.trivy }}
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ template "harbor.trivy" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
component: trivy
spec:
replicas: {{ .Values.trivy.replicas }}
serviceName: {{ template "harbor.trivy" . }}
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
component: trivy
template:
metadata:
labels:
{{ include "harbor.labels" . | indent 8 }}
component: trivy
annotations:
checksum/secret: {{ include (print $.Template.BasePath "/trivy/trivy-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 "/trivy/trivy-tls.yaml") . | sha256sum }}
{{- end }}
{{- if .Values.trivy.podAnnotations }}
{{ toYaml .Values.trivy.podAnnotations | indent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.trivy.serviceAccountName }}
serviceAccountName: {{ .Values.trivy.serviceAccountName }}
{{- end }}
securityContext:
runAsNonRoot: true
runAsUser: 10000
fsGroup: 10000
automountServiceAccountToken: false
containers:
- name: trivy
image: {{ .Values.trivy.image.repository }}:{{ .Values.trivy.image.tag }}
imagePullPolicy: {{ .Values.imagePullPolicy }}
securityContext:
privileged: false
allowPrivilegeEscalation: false
env:
{{- if has "trivy" .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 }}
- name: "SCANNER_LOG_LEVEL"
value: {{ .Values.logLevel | quote }}
- name: "SCANNER_TRIVY_CACHE_DIR"
value: "/home/scanner/.cache/trivy"
- name: "SCANNER_TRIVY_REPORTS_DIR"
value: "/home/scanner/.cache/reports"
- name: "SCANNER_TRIVY_DEBUG_MODE"
value: {{ .Values.trivy.debugMode | quote }}
- name: "SCANNER_TRIVY_VULN_TYPE"
value: {{ .Values.trivy.vulnType | quote }}
- name: "SCANNER_TRIVY_GITHUB_TOKEN"
valueFrom:
secretKeyRef:
name: {{ template "harbor.trivy" . }}
key: gitHubToken
- name: "SCANNER_TRIVY_SEVERITY"
value: {{ .Values.trivy.severity | quote }}
- name: "SCANNER_TRIVY_IGNORE_UNFIXED"
value: {{ .Values.trivy.ignoreUnfixed | default false | quote }}
- name: "SCANNER_TRIVY_SKIP_UPDATE"
value: {{ .Values.trivy.skipUpdate | default false | quote }}
- name: "SCANNER_TRIVY_INSECURE"
value: {{ .Values.trivy.insecure | default false | quote }}
- name: SCANNER_API_SERVER_ADDR
value: ":{{ template "harbor.trivy.containerPort" . }}"
{{- if .Values.internalTLS.enabled }}
- name: INTERNAL_TLS_ENABLED
value: "true"
- name: SCANNER_API_SERVER_TLS_KEY
value: /etc/harbor/ssl/trivy/tls.key
- name: SCANNER_API_SERVER_TLS_CERTIFICATE
value: /etc/harbor/ssl/trivy/tls.crt
{{- end }}
- name: "SCANNER_REDIS_URL"
valueFrom:
secretKeyRef:
name: {{ template "harbor.trivy" . }}
key: redisURL
- name: "SCANNER_STORE_REDIS_URL"
valueFrom:
secretKeyRef:
name: {{ template "harbor.trivy" . }}
key: redisURL
- name: "SCANNER_JOB_QUEUE_REDIS_URL"
valueFrom:
secretKeyRef:
name: {{ template "harbor.trivy" . }}
key: redisURL
ports:
- name: api-server
containerPort: {{ template "harbor.trivy.containerPort" . }}
volumeMounts:
- name: etc-localtime
mountPath: /etc/localtime
- name: data
mountPath: /home/scanner/.cache
subPath: {{ .Values.persistence.persistentVolumeClaim.trivy.subPath }}
readOnly: false
{{- if .Values.internalTLS.enabled }}
- name: trivy-internal-certs
mountPath: /etc/harbor/ssl/trivy
{{- end }}
{{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolumeMount" . | indent 10 }}
{{- end }}
livenessProbe:
httpGet:
scheme: {{ include "harbor.component.scheme" . | upper }}
path: /probe/healthy
port: api-server
initialDelaySeconds: 5
periodSeconds: 10
successThreshold: 1
failureThreshold: 10
readinessProbe:
httpGet:
scheme: {{ include "harbor.component.scheme" . | upper }}
path: /probe/ready
port: api-server
initialDelaySeconds: 5
periodSeconds: 10
successThreshold: 1
failureThreshold: 3
resources:
{{ toYaml .Values.trivy.resources | indent 12 }}
{{- if or (or .Values.internalTLS.enabled .Values.caBundleSecretName) (or (not .Values.persistence.enabled) $trivy.existingClaim) }}
volumes:
- name: etc-localtime
hostPath:
path: /etc/localtime
{{- if .Values.internalTLS.enabled }}
- name: trivy-internal-certs
secret:
secretName: {{ template "harbor.internalTLS.trivy.secretName" . }}
{{- end }}
{{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolume" . | indent 6 }}
{{- end }}
{{- if not .Values.persistence.enabled }}
- name: "data"
emptyDir: {}
{{- else if $trivy.existingClaim }}
- name: "data"
persistentVolumeClaim:
claimName: {{ $trivy.existingClaim }}
{{- end }}
{{- end }}
{{- with .Values.trivy.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.trivy.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.trivy.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
{{- if and .Values.persistence.enabled (not $trivy.existingClaim) }}
volumeClaimTemplates:
- metadata:
name: data
labels:
{{ include "harbor.labels" . | indent 8 }}
spec:
accessModes: [{{ $trivy.accessMode | quote }}]
{{- if $trivy.storageClass }}
{{- if (eq "-" $trivy.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: "{{ $trivy.storageClass }}"
{{- end }}
{{- end }}
resources:
requests:
storage: {{ $trivy.size | quote }}
{{- end }}
{{- end }}
{{ if .Values.trivy.enabled }}
apiVersion: v1
kind: Service
metadata:
name: "{{ template "harbor.trivy" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
spec:
ports:
- name: api-server
protocol: TCP
port: {{ template "harbor.trivy.servicePort" . }}
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
component: trivy
{{ end }}
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.
#/bin/bash
set -e
version=${HELM_VERSION}
if [ "$version" = "2" ]
then
dist="helm-v2.8.0-linux-amd64.tar.gz"
# as the helm v3 removes tiller, here appends the "-c" option
# to args only when running helm v2 to display the client version
version_args="-c"
elif [ "$version" = "3" ]
then
# the "template" command doesn't work for helm beta3:
# https://github.com/helm/helm/issues/6404, use the beta2 for now
dist="helm-v3.0.0-beta.2-linux-amd64.tar.gz"
else
echo "unsupported helm version: $version"
exit 1
fi
wget -O /tmp/${dist} https://get.helm.sh/${dist}
tar -zxvf /tmp/${dist} -C /tmp/
sudo mv /tmp/linux-amd64/helm /usr/local/bin/helm
helm version $version_args
echo "Helm installed"
\ No newline at end of file
This diff is collapsed.
package integration
import (
"fmt"
"testing"
"github.com/gruntwork-io/terratest/modules/k8s"
"github.com/stretchr/testify/suite"
)
type IngressTestSuite struct {
BaseTestSuite
}
func (i *IngressTestSuite) TestIngress() {
k8s.GetIngress(i.T(), i.Options.KubectlOptions, fmt.Sprintf("%s-harbor-ingress", i.ReleaseName))
k8s.GetIngress(i.T(), i.Options.KubectlOptions, fmt.Sprintf("%s-harbor-ingress-notary", i.ReleaseName))
}
func TestIngressTestSuite(t *testing.T) {
suite.Run(t, &IngressTestSuite{
BaseTestSuite: NewBaseTestSuite(map[string]string{
"expose.ingress.hosts.core": "harbor.local",
"expose.ingress.hosts.notary": "notary.harbor.local",
"externalURL": "https://harbor.local",
}),
})
}
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP
- containerPort: 30003
hostPort: 30003
protocol: TCP
This diff is collapsed.
package test
This diff is collapsed.
#/bin/bash
set -e
helm lint .
# expose the service via ingress, this disables the deployment of nginx
helm template --set "expose.type=ingress" --output-dir /tmp/ .
# expose the service via node port, this enables the deployment of nginx
helm template --set "expose.type=nodePort,expose.tls.commonName=127.0.0.1" --output-dir /tmp/ .
\ No newline at end of file
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