Initial helm chart for Harbor (#4271)

This commit is contained in:
Paul Czarkowski 2018-02-16 21:29:52 -06:00 committed by Jesse Hu
parent bd12a3f958
commit be397eb157
34 changed files with 1395 additions and 0 deletions

2
.gitignore vendored
View File

@ -1,4 +1,6 @@
harbor
!/contrib/helm/harbor
make/docker-compose.yml
make/common/config/*
make/dev/adminserver/harbor_adminserver

View File

@ -0,0 +1,21 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj

View File

@ -0,0 +1,17 @@
name: harbor
version: 0.0.1
appVersion: 1.3.0
description: An Enterprise-class Docker Registry Harbor by VMware
keywords:
- vmware
- docker
- registry
- harbor
home: https://github.com/vmware/harbor
icon: https://github.com/vmware/harbor/blob/master/docs/img/harbor_logo.png
sources:
- https://github.com/vmware/harbor
maintainers:
- name: paulczar
email: username.taken@gmail.com
engine: gotpl

View File

@ -0,0 +1,130 @@
# Project Harbor by VMware
[Harbor](http://vmware.github.io/harbor/) is an enterprise-class registry server that stores and distributes Docker images. Harbor extends the open source Docker Distribution by adding the functionalities usually required by an enterprise, such as security, identity and management. As an enterprise private registry, Harbor offers better performance and security. Having a registry closer to the build and run environment improves the image transfer efficiency. Harbor supports the setup of multiple registries and has images replicated between them. In addition, Harbor offers advanced security features, such as user management, access control and activity auditing.
## Introduction
This is an experimental monolithic chart that installs and configures VMWare Harbor and its dependencies. The initial implementation of this includes all of the components required to run Harbor. As upstream harbor becomes more cloud native we will be able to break apart the monolith and utitlize helm dependencies.
## Prerequisites
- Kubernetes 1.7+ with Beta APIs enabled
- PV provisioner support in the underlying infrastructure
## Installing the Chart
To install the chart with the release name `my-release`:
```bash
$ git clone https://github.com/vmware/harbor.git
$ cd harbor/contrib/helm/harbor
$ helm install --name my-release incubator/harbor
```
The command deploys Harbor on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation.
> **Tip**: List all releases using `helm list`
## Uninstalling the Chart
To uninstall/delete the `my-release` deployment:
```bash
$ helm delete my-release
```
The command removes all the Kubernetes components associated with the chart and deletes the release.
## Configuration
The following tables lists the configurable parameters of the Percona chart and their default values.
| Parameter | Description | Default |
| ----------------------- | ---------------------------------- | ----------------------- |
| **Harbor** |
| `externalDomain` | domain harbor will run on (https://*harbor.url*/) |`harbor.192.168.99.100.xip.io` |
| `tls_crt` | TLS certificate to use for Harbor's https endpoint | see values.yaml |
| `tls_key` | TLS key to use for Harbor's https endpoint | see values.yaml |
| `ca_crt` | CA Cert for self signed TLS cert | see values.yaml |
| `persistence.enabled` | enable persistent data storage | `false` |
| **Adminserver** |
| `adminserver.image.repository` | Repository for adminserver image | `vmware/harbor-adminserver` |
| `adminserver.image.tag` | Tag for adminserver image | `v1.3.0` |
| `adminserver.image.pullPolicy` | Pull Policy for adminserver image | `IfNotPresent` |
| `adminserver.emailHost` | email server | `smtp.mydomain.com` |
| `adminserver.emailPort` | email port | `25` |
| `adminserver.emailUser` | email username | `sample_admin@mydomain.com` |
| `adminserver.emailSsl` | email uses SSL? | `false` |
| `adminserver.emailFrom` | send email from address | `admin <sample_admin@mydomain.com>` |
| `adminserver.emailIdentity` | | "" |
| `adminserver.key` | adminsever key | `not-a-secure-key` |
| `adminserver.emailPwd` | password for email | `not-a-secure-password` |
| `adminserver.harborAdminPassword` | password for admin user | `Harbor12345` |
| `adminserver.resources` | [resources](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) to allocate for container | undefined |
| `adminserver.volumes` | used to create PVCs if persistence is enabled (see instructions in values.yaml) | see values.yaml |
| **Jobservice** |
| `jobservice.image.repository` | Repository for jobservice image | `vmware/harbor-jobservice` |
| `jobservice.image.tag` | Tag for jobservice image | `v1.3.0` |
| `jobservice.image.pullPolicy` | Pull Policy for jobservice image | `IfNotPresent` |
| `jobservice.key` | jobservice key | `not-a-secure-key` |
| `jobservice.secret` | jobservice secret | `not-a-secure-secret` |
| `jobservice.resources` | [resources](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) to allocate for container | undefined |
| **UI** |
| `ui.image.repository` | Repository for ui image | `vmware/harbor-ui` |
| `ui.image.tag` | Tag for ui image | `v1.3.0` |
| `ui.image.pullPolicy` | Pull Policy for ui image | `IfNotPresent` |
| `ui.key` | ui key | `not-a-secure-key` |
| `ui.secret` | ui secret | `not-a-secure-secret` |
| `ui.privateKeyPem` | ui private key | see values.yaml |
| `ui.resources` | [resources](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) to allocate for container | undefined |
| **MySQL** |
| `mysql.image.repository` | Repository for mysql image | `vmware/harbor-mysql` |
| `mysql.image.tag` | Tag for mysql image | `v1.3.0` |
| `mysql.image.pullPolicy` | Pull Policy for mysql image | `IfNotPresent` |
| `mysql.host` | MySQL Server | `~` |
| `mysql.port` | MySQL Port | `3306` |
| `mysql.user` | MySQL Username | `root` |
| `mysql.pass` | MySQL Password | `registry` |
| `mysql.database` | MySQL Database | `registry` |
| `mysql.resources` | [resources](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) to allocate for container | undefined |
| `mysql.volumes` | used to create PVCs if persistence is enabled (see instructions in values.yaml) | see values.yaml |
| **Registry** |
| `registry.image.repository` | Repository for registry image | `vmware/harbor-registry` |
| `registry.image.tag` | Tag for registry image | `v1.3.0` |
| `registry.image.pullPolicy` | Pull Policy for registry image | `IfNotPresent` |
| `registry.rootCrt` | registry root cert | see values.yaml |
| `registry.httpSecret` | registry secret | `not-a-secure-secret` |
| `registry.resources` | [resources](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) to allocate for container | undefined |
| `registry.volumes` | used to create PVCs if persistence is enabled (see instructions in values.yaml) | see values.yaml |
| **Clair** |
| `clair.enabled` | Enable clair? | `false` |
| `clair.postgresPassword` | password for clair postgres | see values.yaml |
| `clair.image.repository` | Repository for clair image | `vmware/clair` |
| `clair.image.tag` | Tag for clair image | `v2.0.1-photon` |
| `clair.image.pullPolicy` | Pull Policy for clair image | `IfNotPresent` |
| `clair.pgImage.repository` | Repository for clair postgres image | `postgres` |
| `clair.pgImage.tag` | Tag for clair postgres image | `9.6.4` |
| `clair.pgImage.pullPolicy` | Pull Policy for clair postgres image | `IfNotPresent` |
| `clair.resources` | [resources](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) to allocate for container | undefined | `clair.pgResources` | [resources](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) to allocate for container | undefined |
| | | |
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example:
```bash
$ helm install --name my-release --set mysql.pass=baconeggs .
```
Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example,
```bash
$ helm install --name my-release -f /path/to/values.yaml .
```
> **Tip**: You can use the default [values.yaml](values.yaml)
## Persistence
VMWare Harbor stores the data and configurations in emptyDir volumes. You can change the values.yaml to enable persistence and use a PersistentVolumeClaim instead.
> *"An emptyDir volume is first created when a Pod is assigned to a Node, and exists as long as that Pod is running on that node. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted forever."*

View File

@ -0,0 +1,15 @@
To add the CA certificate to docker copy the contents of the following command into /etc/docker/certs.d/{{ .Values.externalDomain }}:
$ kubectl get secret \
--namespace {{ .Release.Namespace }} {{ template "harbor.fullname" . }}-ingress \
-o jsonpath="{.data.ca\.crt}" | base64 --decode
Access Harbor via: https://{{ .Values.externalDomain }}
login to harbor with docker cli:
docker login {{ .Values.externalDomain }}
To get your admin password run the following (not yet ready):
$ kubectl get secret --namespace {{ .Release.Namespace }} {{ template "harbor.fullname" . }} -o jsonpath="{.data.}" | base64 --decode; echo

View File

@ -0,0 +1,31 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
*/}}
{{- define "harbor.name" -}}
{{- default "harbor" .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
*/}}
{{- define "harbor.fullname" -}}
{{- $name := default "harbor" .Values.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/* Helm required labels */}}
{{- define "helm.labels" -}}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
app: "{{ template "harbor.name" . }}"
{{- end -}}
{{/* matchLabels */}}
{{- define "helm.matchLabels" -}}
release: {{ .Release.Name }}
app: "{{ template "harbor.name" . }}"
{{- end -}}

View File

@ -0,0 +1,47 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: "{{ template "harbor.fullname" . }}-adminserver"
labels:
{{ include "helm.labels" . | indent 4 }}
data:
{{ if .Values.mysql.host -}}
MYSQL_HOST: "{{ .Values.mysql.host }}"
{{ else -}}
MYSQL_HOST: "{{ template "harbor.fullname" . }}-mysql"
{{ end -}}
MYSQL_PORT: "{{ .Values.mysql.port }}"
MYSQL_USR: "{{ .Values.mysql.user }}"
MYSQL_DATABASE: "{{ .Values.mysql.database }}"
EMAIL_HOST: "{{ .Values.adminserver.emailHost }}"
EMAIL_PORT: "{{ .Values.adminserver.emailPort }}"
EMAIL_USR: "{{ .Values.adminserver.emailUser }}"
EMAIL_SSL: "{{ .Values.adminserver.emailSsl }}"
EMAIL_FROM: "{{ .Values.adminserver.emailFrom }}"
EMAIL_IDENTITY: "{{ .Values.adminserver.emailIdentity }}"
EXT_ENDPOINT: "https://{{ .Values.externalDomain }}"
REGISTRY_URL: "http://{{ template "harbor.fullname" . }}-registry:5000"
TOKEN_SERVICE_URL: "http://{{ template "harbor.fullname" . }}-ui/service/token"
WITH_NOTARY: "{{ .Values.notary.enabled }}"
LOG_LEVEL: "info"
IMAGE_STORE_PATH: "/"
AUTH_MODE: "database"
SELF_REGISTRATION: "on"
LDAP_URL: "ldaps://ldapserver"
LDAP_SEARCH_DN: ""
LDAP_BASE_DN: ""
LDAP_FILTER: "(objectClass=person)"
LDAP_UID: "uid"
LDAP_SCOPE: "3"
LDAP_TIMEOUT: "5"
DATABASE_TYPE: "mysql"
PROJECT_CREATION_RESTRICTION: "everyone"
VERIFY_REMOTE_CERT: "off"
MAX_JOB_WORKERS: "3"
TOKEN_EXPIRATION: "30"
CFG_EXPIRATION: "5"
GODEBUG: "netdns=cgo"
ADMIRAL_URL: "NA"
RESET: "false"
WITH_CLAIR: "{{ .Values.clair.enabled }}"
CLAIR_DB_HOST: "{{ template "harbor.fullname" . }}-clair-pg"

View File

@ -0,0 +1,18 @@
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.fullname" . }}-adminserver"
labels:
{{ include "helm.labels" . | indent 4 }}
type: Opaque
data:
key: {{ .Values.adminserver.key | b64enc | quote }}
EMAIL_PWD: {{ .Values.adminserver.emailPwd | b64enc | quote }}
HARBOR_ADMIN_PASSWORD: {{ .Values.adminserver.harborAdminPassword | b64enc | quote }}
MYSQL_PWD: {{ .Values.mysql.pass | b64enc | quote }}
JOBSERVICE_SECRET: {{ .Values.jobservice.secret | b64enc | quote }}
UI_SECRET: {{ .Values.ui.secret | b64enc | quote }}
{{ if .Values.clair.enabled }}
CLAIR_DB_PASSWORD: {{ .Values.clair.postgresPassword | b64enc | quote }}
{{ end }}
#LDAP_SEARCH_PWD: not-a-secure-password

View File

@ -0,0 +1,74 @@
apiVersion: apps/v1beta2
kind: StatefulSet
metadata:
name: "{{ template "harbor.fullname" . }}-adminserver"
labels:
{{ include "helm.labels" . | indent 4 }}
component: adminserver
spec:
replicas: 1
serviceName: "{{ template "harbor.fullname" . }}"
selector:
matchLabels:
{{ include "helm.matchLabels" . | indent 6 }}
component: adminserver
template:
metadata:
labels:
{{ include "helm.labels" . | indent 8 }}
component: adminserver
spec:
containers:
- name: adminserver
image: "{{ .Values.adminserver.image.repository }}:{{ .Values.adminserver.image.tag }}"
imagePullPolicy: "{{ .Values.adminserver.image.pullPolicy }}"
resources:
{{ toYaml .Values.adminserver.resources | indent 10 }}
envFrom:
- configMapRef:
name: "{{ template "harbor.fullname" . }}-adminserver"
- secretRef:
name: "{{ template "harbor.fullname" . }}-adminserver"
env:
- name: PORT
value: "8080"
- name: JSON_CFG_STORE_PATH
value: /etc/adminserver/config/config.json
- name: KEY_PATH
value: /etc/adminserver/key
ports:
- containerPort: 8080
volumeMounts:
- name: adminserver-config
mountPath: /etc/adminserver/config
- name: adminserver-key
mountPath: /etc/adminserver/key
subPath: key
volumes:
{{- if not .Values.persistence.enabled }}
- name: adminserver-config
emptyDir: {}
{{- end }}
- name: adminserver-key
secret:
secretName: "{{ template "harbor.fullname" . }}-adminserver"
items:
- key: key
path: key
{{- if .Values.persistence.enabled }}
volumeClaimTemplates:
- metadata:
name: adminserver-config
spec:
accessModes: [{{ .Values.adminserver.volumes.config.accessMode | quote }}]
{{- if .Values.adminserver.volumes.config.storageClass }}
{{- if (eq "-" .Values.adminserver.volumes.config.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: "{{ .Values.adminserver.volumes.config.storageClass }}"
{{- end }}
{{- end }}
resources:
requests:
storage: {{ .Values.adminserver.volumes.config.size | quote }}
{{- end -}}

View File

@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: "{{ template "harbor.fullname" . }}-adminserver"
labels:
{{ include "helm.labels" . | indent 4 }}
spec:
ports:
- port: 80
targetPort: 8080
selector:
{{ include "helm.matchLabels" . | indent 4 }}
component: adminserver

View File

@ -0,0 +1,35 @@
{{ if .Values.clair.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "harbor.fullname" . }}
labels:
{{ include "helm.labels" . | indent 4 }}
data:
config.yaml: |
clair:
database:
type: pgsql
options:
source: "postgresql://postgres:{{ .Values.clair.postgresPassword }}@{{ template "harbor.fullname" . }}-clair-pg:5432?sslmode=disable"
# 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: 12h
notifier:
attempts: 3
renotifyinterval: 2h
http:
endpoint: "http://{{ template "harbor.fullname" . }}-ui/service/notifications/clair"
{{ end }}

View File

@ -0,0 +1,37 @@
{{ if .Values.clair.enabled }}
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: {{ template "harbor.fullname" . }}-clair
labels:
{{ include "helm.labels" . | indent 4 }}
component: clair
spec:
replicas: 1
template:
metadata:
labels:
{{ include "helm.labels" . | indent 8 }}
component: clair
spec:
containers:
- name: clair
image: {{ .Values.clair.image.repository }}:{{ .Values.clair.image.tag }}
imagePullPolicy: {{ .Values.clair.image.pullPolicy }}
args: ["-insecure-tls", "-config", "/config/config.yaml"]
resources:
{{ toYaml .Values.clair.resources | indent 10 }}
ports:
- containerPort: 6060
volumeMounts:
- name: clair-config
mountPath: /config/config.yaml
subPath: config.yaml
volumes:
- name: clair-config
configMap:
name: "{{ template "harbor.fullname" . }}"
items:
- key: config.yaml
path: config.yaml
{{ end }}

View File

@ -0,0 +1,31 @@
{{ if .Values.clair.enabled }}
apiVersion: v1
kind: Service
metadata:
name: "{{ template "harbor.fullname" . }}-clair"
labels:
{{ include "helm.labels" . | indent 4 }}
spec:
ports:
- port: 6060
selector:
app: "{{ template "harbor.fullname" . }}"
component: adminserver
release: {{ .Release.Name }}
---
---
# clair host isn't configurable yet. this creates a service
# to get it working for now.
# see https://github.com/vmware/harbor/issues/3250
apiVersion: v1
kind: Service
metadata:
name: clair
spec:
ports:
- port: 6060
selector:
app: "{{ template "harbor.fullname" . }}"
component: adminserver
release: {{ .Release.Name }}
{{ end }}

View File

@ -0,0 +1,11 @@
{{ if .Values.clair.enabled }}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "harbor.fullname" . }}-clair-pg-config
labels:
{{ include "helm.labels" . | indent 4 }}
type: Opaque
data:
POSTGRES_PASSWORD: {{ .Values.clair.postgresPassword | b64enc | quote }}
{{ end }}

View File

@ -0,0 +1,72 @@
{{ if .Values.clair.enabled }}
apiVersion: apps/v1beta2
kind: StatefulSet
metadata:
name: {{ template "harbor.fullname" . }}-clair-pg
labels:
{{ include "helm.labels" . | indent 4 }}
component: clair-pg
spec:
serviceName: "{{ template "harbor.fullname" . }}-clair-pg"
selector:
matchLabels:
{{ include "helm.matchLabels" . | indent 6 }}
component: clair-pg
template:
metadata:
name: {{ template "harbor.fullname" . }}-clair-pg
labels:
{{ include "helm.labels" . | indent 8 }}
component: clair-pg
spec:
containers:
- name: postgres
image: {{ .Values.clair.pgImage.repository }}:{{ .Values.clair.pgImage.tag }}
imagePullPolicy: {{ .Values.clair.pgImage.pullPolicy }}
resources:
{{ toYaml .Values.clair.pgResources | indent 10 }}
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: {{ template "harbor.fullname" . }}-clair-pg-config
key: POSTGRES_PASSWORD
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 100m
memory: 512Mi
volumeMounts:
- name: pgdata
mountPath: /var/lib/postgresql
ports:
- containerPort: 5432
name: postgres-port
protocol: TCP
{{- if not .Values.persistence.enabled }}
volumes:
- name: pgdata
emptyDir: {}
{{- end }}
{{- if .Values.persistence.enabled }}
volumeClaimTemplates:
- metadata:
name: pgdata
labels:
{{ include "helm.labels" . | indent 8 }}
spec:
accessModes: [{{ .Values.clair.volumes.pgData.accessMode | quote }}]
{{- if .Values.clair.volumes.pgData.storageClass }}
{{- if (eq "-" .Values.clair.volumes.pgData.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: "{{ .Values.clair.volumes.pgData.storageClass }}"
{{- end }}
{{- end }}
resources:
requests:
storage: {{ .Values.clair.volumes.pgData.size | quote }}
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,30 @@
{{ if .Values.clair.enabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ template "harbor.fullname" . }}-clair-pg
labels:
{{ include "helm.labels" . | indent 4 }}
spec:
ports:
- port: 5432
selector:
{{ include "helm.matchLabels" . | indent 4 }}
component: clair-pg
---
# clairdb host isn't configurable yet. this creates a service
# to get it working for now.
# see https://github.com/vmware/harbor/commit/f63588855f8d3b1b138d3be63ca165bb52ab930c
apiVersion: v1
kind: Service
metadata:
name: postgres
labels:
{{ include "helm.labels" . | indent 4 }}
spec:
ports:
- port: 5432
selector:
{{ include "helm.matchLabels" . | indent 4 }}
component: clair-pg
{{ end }}

View File

@ -0,0 +1,31 @@
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: "{{ template "harbor.fullname" . }}-ingress"
labels:
{{ include "helm.labels" . | indent 4 }}
annotations:
ingress.kubernetes.io/ssl-redirect: "true"
ingress.kubernetes.io/body-size: "0"
ingress.kubernetes.io/proxy-body-size: "0"
spec:
tls:
- hosts:
- "{{ .Values.externalDomain }}"
secretName: "{{ template "harbor.fullname" . }}-ingress"
rules:
- host: "{{ .Values.externalDomain }}"
http:
paths:
- path: /
backend:
serviceName: {{ template "harbor.fullname" . }}-ui
servicePort: 80
- path: /v2
backend:
serviceName: {{ template "harbor.fullname" . }}-registry
servicePort: 5000
- path: /v1
backend:
serviceName: {{ template "harbor.fullname" . }}-fake-service
servicePort: 5000

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.fullname" . }}-ingress"
labels:
{{ include "helm.labels" . | indent 4 }}
type: kubernetes.io/tls
data:
tls.crt: {{ .Values.tlsCrt | b64enc | quote }}
tls.key: {{ .Values.tlsKey | b64enc | quote }}
ca.crt: {{ .Values.caCrt | b64enc | quote }}

View File

@ -0,0 +1,13 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: "{{ template "harbor.fullname" . }}-jobservice"
labels:
{{ include "helm.labels" . | indent 4 }}
data:
app.conf: |+
appname = jobservice
runmode = prod
[prod]
httpport = 8080

View File

@ -0,0 +1,56 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: "{{ template "harbor.fullname" . }}-jobservice"
labels:
{{ include "helm.labels" . | indent 4 }}
component: jobservice
spec:
replicas: 1
template:
metadata:
labels:
{{ include "helm.labels" . | indent 8 }}
component: jobservice
spec:
containers:
- name: jobservice
image: {{ .Values.jobservice.image.repository }}:{{ .Values.jobservice.image.tag }}
imagePullPolicy: {{ .Values.jobservice.image.pullPolicy }}
resources:
{{ toYaml .Values.jobservice.resources | indent 10 }}
envFrom:
- secretRef:
name: "{{ template "harbor.fullname" . }}-jobservice"
env:
- name: LOG_LEVEL
value: debug
- name: CONFIG_PATH
value: /etc/jobservice/app.conf
- name: GODEBUG
value: netdns=cgo
- name: ADMINSERVER_URL
value: "http://{{ template "harbor.fullname" . }}-adminserver"
ports:
- containerPort: 8080
volumeMounts:
- name: jobservice-config
mountPath: /etc/jobservice/app.conf
subPath: app.conf
- name: jobservice-secrets
mountPath: /etc/jobservice/key
subPath: key
- name: job-logs
mountPath: /var/log/jobs
volumes:
- name: jobservice-config
configMap:
name: "{{ template "harbor.fullname" . }}-jobservice"
- name: jobservice-secrets
secret:
secretName: "{{ template "harbor.fullname" . }}-jobservice"
items:
- key: key
path: key
- name: job-logs
emptyDir: {}

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.fullname" . }}-jobservice"
labels:
{{ include "helm.labels" . | indent 4 }}
type: Opaque
data:
JOBSERVICE_SECRET: {{ .Values.jobservice.secret | b64enc | quote }}
key: {{ .Values.jobservice.key | b64enc | quote }}
UI_SECRET: {{ .Values.ui.secret | b64enc | quote }}

View File

@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: "{{ template "harbor.fullname" . }}-jobservice"
labels:
{{ include "helm.labels" . | indent 4 }}
spec:
ports:
- port: 80
targetPort: 8080
selector:
{{ include "helm.matchLabels" . | indent 4 }}
component: jobservice

View File

@ -0,0 +1,9 @@
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.fullname" . }}-mysql"
labels:
{{ include "helm.labels" . | indent 4 }}
type: Opaque
data:
mysqlRootPassword: {{ .Values.mysql.pass | b64enc | quote }}

View File

@ -0,0 +1,59 @@
apiVersion: apps/v1beta2
kind: StatefulSet
metadata:
name: "{{ template "harbor.fullname" . }}-mysql"
labels:
{{ include "helm.labels" . | indent 4 }}
component: mysql
spec:
replicas: 1
serviceName: "{{ template "harbor.fullname" . }}-mysql"
selector:
matchLabels:
{{ include "helm.matchLabels" . | indent 6 }}
component: mysql
template:
metadata:
labels:
{{ include "helm.labels" . | indent 8 }}
component: mysql
spec:
containers:
- name: mysql
image: {{ .Values.mysql.image.repository }}:{{ .Values.mysql.image.tag }}
imagePullPolicy: {{ .Values.mysql.image.pullPolicy }}
resources:
{{ toYaml .Values.mysql.resources | indent 10 }}
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: "{{ template "harbor.fullname" . }}-mysql"
key: mysqlRootPassword
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
{{- if not .Values.persistence.enabled }}
volumes:
- name: "mysql-data"
emptyDir: {}
{{- end -}}
{{- if .Values.persistence.enabled }}
volumeClaimTemplates:
- metadata:
name: "mysql-data"
labels:
{{ include "helm.labels" . | indent 8 }}
spec:
accessModes: [{{ .Values.mysql.volumes.data.accessMode | quote }}]
{{- if .Values.mysql.volumes.data.storageClass }}
{{- if (eq "-" .Values.mysql.volumes.data.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: "{{ .Values.mysql.volumes.data.storageClass }}"
{{- end }}
{{- end }}
resources:
requests:
storage: {{ .Values.mysql.volumes.data.size | quote }}
{{- end -}}

View File

@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: "{{ template "harbor.fullname" . }}-mysql"
labels:
{{ include "helm.labels" . | indent 4 }}
spec:
ports:
- port: 3306
selector:
{{ include "helm.matchLabels" . | indent 4 }}
component: mysql

View File

@ -0,0 +1,47 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: "{{ template "harbor.fullname" . }}-registry"
labels:
{{ include "helm.labels" . | indent 4 }}
data:
config.yml: |+
version: 0.1
log:
level: info
fields:
service: registry
storage:
{{- if .Values.registry.objectStorage }}
{{ toYaml .Values.registry.objectStorage | indent 6 }}
{{- end }}
cache:
layerinfo: inmemory
filesystem:
rootdirectory: /var/lib/registry
maintenance:
uploadpurging:
enabled: false
delete:
enabled: true
http:
addr: :5000
# set via environment variable
# secret: placeholder
debug:
addr: localhost:5001
auth:
token:
issuer: harbor-token-issuer
realm: "https://{{ .Values.externalDomain }}/service/token"
rootcertbundle: /etc/registry/root.crt
service: harbor-registry
notifications:
endpoints:
- name: harbor
disabled: false
url: http://{{ template "harbor.fullname" . }}-ui/service/notifications
timeout: 3000ms
threshold: 5
backoff: 1s

View File

@ -0,0 +1,10 @@
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.fullname" . }}-registry"
labels:
{{ include "helm.labels" . | indent 4 }}
type: Opaque
data:
httpSecret: {{ .Values.registry.httpSecret | b64enc | quote }}
root.crt: {{ .Values.registry.rootCrt | b64enc | quote }}

View File

@ -0,0 +1,79 @@
apiVersion: apps/v1beta2
kind: StatefulSet
metadata:
name: "{{ template "harbor.fullname" . }}-registry"
labels:
{{ include "helm.labels" . | indent 4 }}
component: registry
spec:
replicas: 1
serviceName: "{{ template "harbor.fullname" . }}-registry"
selector:
matchLabels:
{{ include "helm.matchLabels" . | indent 6 }}
component: registry
template:
metadata:
labels:
{{ include "helm.labels" . | indent 8 }}
component: registry
spec:
containers:
- name: registry
image: {{ .Values.registry.image.repository }}:{{ .Values.registry.image.tag }}
imagePullPolicy: {{ .Values.registry.image.pullPolicy }}
resources:
{{ toYaml .Values.mysql.resources | indent 10 }}
args: ["serve", "/etc/registry/config.yml"]
env:
- name: REGISTRY_HTTP_SECRET
valueFrom:
secretKeyRef:
name: "{{ template "harbor.fullname" . }}-registry"
key: httpSecret
ports:
- containerPort: 5000
- containerPort: 5001
volumeMounts:
- name: registry-data
mountPath: /var/lib/registry
- name: registry-root-certificate
mountPath: /etc/registry/root.crt
subPath: root.crt
- name: registry-config
mountPath: /etc/registry/config.yml
subPath: config.yml
volumes:
{{- if not .Values.registry.objectStorage }}
{{- if not .Values.persistence.enabled }}
- name: registry-data
emptyDir: {}
{{- end }}
{{- end }}
- name: registry-root-certificate
secret:
secretName: "{{ template "harbor.fullname" . }}-registry"
- name: registry-config
configMap:
name: "{{ template "harbor.fullname" . }}-registry"
{{- if not .Values.registry.objectStorage }}
{{- if .Values.persistence.enabled }}
volumeClaimTemplates:
- metadata:
name: "registry-data"
labels:
{{ include "helm.labels" . | indent 8 }}
spec:
accessModes: [{{ .Values.registry.volumes.data.accessMode | quote }}]
{{- if .Values.registry.volumes.data.storageClass }}
{{- if (eq "-" .Values.registry.volumes.data.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: "{{ .Values.registry.volumes.data.storageClass }}"
{{- end }}
{{- end }}
resources:
requests:
storage: {{ .Values.registry.volumes.data.size | quote }}
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: "{{ template "harbor.fullname" . }}-registry"
labels:
{{ include "helm.labels" . | indent 4 }}
spec:
ports:
- port: 5000
selector:
{{ include "helm.matchLabels" . | indent 4 }}
component: registry

View File

@ -0,0 +1,14 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: "{{ template "harbor.fullname" . }}-ui"
labels:
{{ include "helm.labels" . | indent 4 }}
data:
app.conf: |+
appname = Harbor
runmode = prod
enablegzip = true
[prod]
httpport = 8080

View File

@ -0,0 +1,78 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: "{{ template "harbor.fullname" . }}-ui"
labels:
{{ include "helm.labels" . | indent 4 }}
component: ui
spec:
replicas: 1
template:
metadata:
labels:
{{ include "helm.labels" . | indent 8 }}
component: ui
spec:
containers:
- name: ui
image: {{ .Values.ui.image.repository }}:{{ .Values.ui.image.tag }}
imagePullPolicy: {{ .Values.ui.image.pullPolicy }}
env:
- name: UI_SECRET
valueFrom:
secretKeyRef:
name: "{{ template "harbor.fullname" . }}-ui"
key: secret
- name: JOBSERVICE_SECRET
valueFrom:
secretKeyRef:
name: "{{ template "harbor.fullname" . }}-ui"
key: jobserviceSecret
- name: GODEBUG
value: netdns=cgo
- name: LOG_LEVEL
value: debug
- name: CONFIG_PATH
value: /etc/ui/app.conf
- name: ENABLE_HARBOR_SCAN_ON_PUSH
value: "1"
- name: ADMINSERVER_URL
value: "http://{{ template "harbor.fullname" . }}-adminserver"
- name: CLAIR_DB_HOST
value: "{{ template "harbor.fullname" . }}-clair-pg"
ports:
- containerPort: 8080
volumeMounts:
- name: ui-config
mountPath: /etc/ui/app.conf
subPath: app.conf
- name: ui-secrets-key
mountPath: /etc/ui/key
subPath: key
- name: ui-secrets-private-key
mountPath: /etc/ui/private_key.pem
subPath: private_key.pem
- name: ca-download
mountPath: /etc/ui/ca
- name: psc
mountPath: /etc/ui/token
volumes:
- name: ui-config
configMap:
name: "{{ template "harbor.fullname" . }}-ui"
- name: ui-secrets-key
secret:
secretName: "{{ template "harbor.fullname" . }}-ui"
items:
- key: key
path: key
- name: ui-secrets-private-key
secret:
secretName: "{{ template "harbor.fullname" . }}-ui"
items:
- key: private_key.pem
path: private_key.pem
- name: ca-download
emptyDir: {}
- name: psc
emptyDir: {}

View File

@ -0,0 +1,12 @@
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.fullname" . }}-ui"
labels:
{{ include "helm.labels" . | indent 4 }}
type: Opaque
data:
secret: {{ .Values.ui.secret | b64enc | quote }}
key: {{ .Values.ui.key | b64enc | quote }}
private_key.pem: {{ .Values.ui.privateKeyPem | b64enc | quote }}
jobserviceSecret: {{ .Values.jobservice.secret | b64enc | quote }}

View File

@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: "{{ template "harbor.fullname" . }}-ui"
labels:
{{ include "helm.labels" . | indent 4 }}
spec:
ports:
- port: 80
targetPort: 8080
selector:
{{ include "helm.matchLabels" . | indent 4 }}
component: ui

View File

@ -0,0 +1,331 @@
# Configure persisten Volumes per application
## Applications that require storage have a `volumes` defintion which will be used
## when `persistence.enabled` is set to true.
## example
# mysql:
# volumes:
# data:
## Persistent Volume Storage Class
## If defined, storageClassName: <storageClass>
## If set to "-", storageClassName: "", which disables dynamic provisioning
## If undefined (the default) or set to null, no storageClassName spec is
## set, choosing the default provisioner. (gp2 on AWS, standard on
## GKE, AWS & OpenStack)
##
# storageClass: "-"
# accessMode: ReadWriteOnce
# size: 1Gi
## Configure resource requests and limits per application
## ref: http://kubernetes.io/docs/user-guide/compute-resources/
##
# mysql:
# resources:
# requests:
# memory: 256Mi
# cpu: 100m
persistence:
enabled: false
externalDomain: harbor.192.168.99.100.xip.io
## tls_crt, tls_key, ca_crt should match the domain above
tlsCrt: |
-----BEGIN CERTIFICATE-----
MIIDJDCCAgygAwIBAgIJAKNSg1jp3l2oMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV
BAMMB3Rlc3QtY2EwHhcNMTgwMTEzMTg1NTIwWhcNMTgwMzE0MTg1NTIwWjAnMSUw
IwYDVQQDDBxoYXJib3IuMTkyLjE2OC45OS4xMDAueGlwLmlvMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxlAD8tlryoGsweXCwDgfyPGkaM9hXsVLW2PH
/vGWBVMXOdxpFhuvH7tXmqN3Ek39YQjcsb+nHAGx7ynx6KFtvzcXCjGfeI1yuoN0
8H2sfV7yxtkVLu/uJGb8mSfsw9ubOR/zMbrsD1oH0tzi3cnW0kcbY0u0Xp/5g0PP
+tig0X+PDfumK/W6KnTOAmnfNTJwhhlljako+lveT5EjVtQMdJmV16PZJwCDA4b9
2U8EkLOjXcSg2ad03XxASGUuG8oMLHNXF0zcJ9421DviaRQGJUSjR571t/YCc2KK
AQVZ/zSI5duQVysfMZrjiuvSQfKSWRVY6z0JAWH7+Dx+1u8ilwIDAQABo2gwZjAJ
BgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYB
BQUHAwEwLQYDVR0RBCYwJIIcaGFyYm9yLjE5Mi4xNjguOTkuMTAwLnhpcC5pb4cE
wKhjZDANBgkqhkiG9w0BAQsFAAOCAQEATgS0Y2wQiCQrVfiDFSIxtIBK2af0qtoA
J4DZ/1Jo01uGycFCyt9KOKbmFubrJu9NHuACL9od3RI37k6L73lV2zB3sS4NEcH2
SvF+rOE7gmtgJULHCDFEWSMxHdUFwcdG1trRVe+9Gyp/LGdC4yyycmwquz7YXf+r
7b5r26rFAYmO8rWYtDt4clC3JSR3O1BmF5ktRNzUtRvrzr3UuwYz0Wy72S/Sa+Iu
RnassP8mg6PCppeGccYFcFihL9kDl4g4Xu/PaMiKdxjdeAV6xAd7VbKBZSi/ljnF
OUUUi7MDJuUWbHEb0XrEXNzihBzf7bu4I2MftQidIg6LwWjiYZRHmw==
-----END CERTIFICATE-----
tlsKey: |
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAxlAD8tlryoGsweXCwDgfyPGkaM9hXsVLW2PH/vGWBVMXOdxp
FhuvH7tXmqN3Ek39YQjcsb+nHAGx7ynx6KFtvzcXCjGfeI1yuoN08H2sfV7yxtkV
Lu/uJGb8mSfsw9ubOR/zMbrsD1oH0tzi3cnW0kcbY0u0Xp/5g0PP+tig0X+PDfum
K/W6KnTOAmnfNTJwhhlljako+lveT5EjVtQMdJmV16PZJwCDA4b92U8EkLOjXcSg
2ad03XxASGUuG8oMLHNXF0zcJ9421DviaRQGJUSjR571t/YCc2KKAQVZ/zSI5duQ
VysfMZrjiuvSQfKSWRVY6z0JAWH7+Dx+1u8ilwIDAQABAoIBAQC2QDDwzRm/2N6w
r3wEdU/YtyJWZEfi9cRkb9YMGW+64vrUZRh6heSyb9R5vEKgouX6eE+CV1S3a2Ng
HZdBKKIYegOFjcc13iCTAl7E6WpNKaZKUpSiN0QPVkpMYqG3+am0nQU+Lb/l9+J6
yh8Anw763vhvj9Jqp/CBzx9jNBTPkh6u02Ayhegn7BBIpxk3LmdWSFn4IBXSxnMs
6B9h8motQFXRJDFm37YFl3834jNWilJT2Z/MCumoAGwNhOFFd5wZM5St1jvfFQlw
A44+AbnOf9sArukXa2NA/HHs6hZHt9GN10kbMBj9wbQRN960OKK4P6+8vVrJ+gUu
iodHLiaxAoGBAP+hlsJvqatgLJmqrODpWrhRqXxWNYs3VJXR5XEEtygVMe2FT7a6
pu5GWgjpQUHFqgqSNpRiJnxdI+AELH6AkeTMg4EyCoaJJKaitMslnCvQHL5oQjIb
IjJrxk/EObxh/7NuSf/nzUBfmhJhZ/pz6LbBLqiy35Cpq106XVC/XSMJAoGBAMaZ
Qd2nUQPhR7+wxDT38duKRIendYd4BiGqc7z9M91+HLjNg9W7cRPx6bUCaN5E4uwx
PzixsHmWc5H1bDgf9ymAMvexfB3BTXfO9tRn6nZu+XbcN6eJejKYj2iVMjDZrVHu
FZzrusRwPXI1I+b8rnKvNF+wf9DQcIVl7VW1G2CfAoGBAMLPSizzG8JWkKaqwwTD
0TcWRKtUp4loqTVjuA7hIROS03HHXnBK3lxHkOWpnOma0XMs6hs6kUnFUUmu5Jmj
MYvDr5QNpqfQa/XxmQYXq2RYPQ9+NLQqqWzzZTX0vGsr48nCCvLSnECqmqfXQ35C
Rt6/aed2KZn9M3Lgv6yBqWDBAoGAIEXjeDuqZLEFUddN6zWnrf+IJ2tFJCCTDoF+
kWWsOgA2dqmfFOqC87TKP8oGdKhJIAzYs0Pc48VZPozdazl2lt3oamwDOWqiRifx
4I6KgXiDPZeHy8gBfZthIqOsJlgZXEkOZhPApA+BTL/p9610Q9rI7gvmmW5l+qeX
q+fkbQ0CgYBYwF4lcMrON5k8cwZMTyPMwOsY+TsxpsoqUqPPHm9JW2DZDQ1f7oEm
1b6zTkwtqbnQX7vKosEivCbeQLN0XOZms+BM/KIwcuZjKxy/rkMNaFcqWlOvktug
hk8Jkkt1dANV5rNPYEkt7G+PiL7ApOV6fGvJRA4f8+RFrfPFtku4Sw==
-----END RSA PRIVATE KEY-----
caCrt: |
-----BEGIN CERTIFICATE-----
MIIC9zCCAd+gAwIBAgIJAPRSQQK2Q7dsMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV
BAMMB3Rlc3QtY2EwHhcNMTgwMTEzMTg1NTIwWhcNMjgwMTExMTg1NTIwWjASMRAw
DgYDVQQDDAd0ZXN0LWNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
znp0w37dGXlUgAXx5p4cwQ/XEiZGA1NorbcV3RTox3wX4b0bFJwKij8hLFMRZrEd
f40AxvQnyTcoX80c0w1M+3fG/pq5PhsfjrphX/EZ/rYJDZkO4vz60H8uc2g9AgVR
IvYbMobX7KcRruyi2dnt22q6O6Xy0pCkTE/+UAgcbwUCNDA9H/+8RhmXkAEaIyc8
y5vIpwfjiSdX6Kqv5zg0ZRESE+s9g6+U4NfwHbeUqfl6/ZuP8xXy2az3tdTqN8l0
dCMjv/dpLzPAOaZhzj+BYN1iVMTFhm6FzszkdTuvJliCIUJeyIqvzqz+k+ai8xR9
s0hrZrTzmN2id5J5cWSWawIDAQABo1AwTjAdBgNVHQ4EFgQU1L/db3zQjJW8ycmd
3D3jh4/HtJEwHwYDVR0jBBgwFoAU1L/db3zQjJW8ycmd3D3jh4/HtJEwDAYDVR0T
BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAJrNwGShGJhmVSoBsSi+4tEa98UC8
7ULKyvaK+RPYKb4K2igMFHZD3KhaayShEG3rw/Y53hdmU+3I82tQ+txGmQoqicxg
BwAODdvixH5gP4idh7G1Q6tDvgJGGl2HvcE8fzbVIO3qDKefPlif20eX2gUc/Ut5
gyiyJutOQKVjEUb5bmUaeRyTXo8Vf2TIhIRfdXHg2ueWj2lDWbtVxQbn/m7aSqON
9YN5xfXY36tpVp40RV1J36FUskkhgc/DZcgEMYdAr2XrjDS1A0TnEaDatQUgYgpd
J0oP9V+2FMfDFvIhX5tNrEuIIFMyO+HR0wxV7huTUeus4knyXBZur3If+g==
-----END CERTIFICATE-----
adminserver:
image:
repository: vmware/harbor-adminserver
tag: v1.3.0
pullPolicy: IfNotPresent
emailHost: "smtp.mydomain.com"
emailPort: "25"
emailUser: "sample_admin@mydomain.com"
emailSsl: "false"
emailFrom: "admin <sample_admin@mydomain.com>"
emailIdentity: ""
key: not-a-secure-key
emailPwd: not-a-secure-password
harborAdminPassword: Harbor12345
## Persist data to a persistent volume
volumes:
config:
# storageClass: "-"
accessMode: ReadWriteOnce
size: 1Gi
# resources:
# requests:
# memory: 256Mi
# cpu: 100m
## jobservice
#
jobservice:
image:
repository: vmware/harbor-jobservice
tag: v1.3.0
pullPolicy: IfNotPresent
key: not-a-secure-key
secret: not-a-secure-secret
# resources:
# requests:
# memory: 256Mi
# cpu: 100m
## UI
#
ui:
image:
repository: vmware/harbor-ui
tag: v1.3.0
pullPolicy: IfNotPresent
secret: not-a-secure-secret
key: not-a-secure-key
privateKeyPem: |
-----BEGIN RSA PRIVATE KEY-----
MIIJKAIBAAKCAgEA4WYbxdrFGG6RnfyYKlHYML3lEqtA9cYWWOynE9BeaEr/cMnM
bBr1dd91/Nm6RiYhQvTDU2Kc6NejqjdliW5B9xUoVKayri8OU81a8ViXeNgKwCPR
AiTTla1zoX5DnvoxpO9G3lxyNvTKXc0cw8NjQDAXpaDbzJYLkshCeuyD9bco8R96
/zrpBEX8tADN3+3yA3fMcZzVXsBm4BTpHJRk/qBpHYEPSHzxyH3iGMNKk3vMUBZz
e0EYkK8NCA2CuEKMnC3acx9IdRwkx10abGvHQCLRCVY7rGoak+b0oZ99RJIRQ9Iq
YXsn8fsMBQly6xxvSeY5XuSP7Xb6JKDt3y8Spi4gR1M/5aEzhuOyu201rMna7Rs/
GPfaKjBlbX0jiLDa7v4zjsBPsPaf/c4uooz3ICLsdukaom+E538R0EiOkXt/wyw2
2YmaWNCsYlEpke7cVC33e/0dPBq4IHsVflawSF9OWS23ikVAs/n+76KjuucEDmbT
aKUYAJjvAmZL14j+EKc/CoplhCe6pKhavjmNIOfCSdlreIPBhOVbf1f817wKoSIZ
qVyCA1AYNkI9RYS00axtJGBGMlKbdQqCNpLL58c6To2awmckIZCEcATKOp++NoGm
Ib0bhdSasdGB5VCtwZVluN8bLl13zBKoxTGjNlEatUGDRnDAnLdZbXXffjsCAwEA
AQKCAgBEUigO8/4UJse6xKr3APHv7E94NjKtjMqPT8RhDCLhqAH/lRuClTVb8k0Y
RILi6oHggsKGDvkS1vJEESCU5LfYBjDAX/r/M0I7gp6TU1AukAXKMdETvkfoMbg/
9j7W/G152hF4KztvjwmcHyUd7aay+SDh0n1taPm/FzaXfgONwmQFmo40uQ2SfwhX
I3tD6iMWjASLV4eRfe5w88WpJQ3r5IGYMNuKFF1RcV7MNL3xMHBAwl1kudmRWY4w
p6+83Gc0m+2AQbY70TkQuRbeUFkIBsWn99yEqXC+7h2us+JLm57iGN1ByQvVnEwL
Zs7Pl0Hge4leSxeZWhv+aE1R/jm/VdG4dglInuhED0ug8WAJg58IkDYfMKOOALHx
+0CNHE02XqqUIFwboZJSYTjMYvFL1i14L30FWnqH/0kDs4whXHbnGWhVustsMSK9
iyIGepuGhMnvtUF1wa/SrBd12qfDj68QHDXsKKbs6eTNYHfn3QL9uisrfMIa5HAt
nX2YOsAVxg+yvxkWD6n1DU+a/+pAu6iAgiwyxSZiyn6vJUE2zO6pJNbk1kJW6jU3
A69srtbO4jQn4EM859XYSqdqwXgJL+XJEYNbBcHalmiIOvRg9CCvDSKS7M5rJ0M1
L7oCzl6EW+zUb4JHkSO7V5uxIZu2sEduw5gofQ3OT9L/qDhDIQKCAQEA8T/8okF2
Q7SOj3su6KKX6H/ab31SvHECf/oeJtH8ZfLBYL55Yof0pZwq8iXQ26d8cH7FPKBo
hz0RZ9i2S3bYkzEVCPv9ISFg1NACxL3dU0PMBnmbmg2vPhMzEuQI2JOUu6ILOXEN
mImvfjZXps/b8OjQgzicH0skBBcbUlXT3a4fF52ktC8FiXgBG9JYg5CsXmfPRxci
ITa4w4ZLEuECmtJieS0MdKXPLwUVv3e2BlNS6c1JzXyp6EyX/euJ8cCe3n/GHbTY
2j1OO+xTQfQJVf6S9f2mSzjdHe9KZwWKgyxQ9dZ9Qtho2z/gUN9/UkL52fdljjlw
++b/z9Ppcl9K0QKCAQEA7y4Fv8dPFLLnr0R/S7eoAKa0S95xVe97EJHVUhWyOI09
K9VdZHp6be8W0Yd9h/Ks8Zi4EPRiTTaF3yA3iADwdKFeZt49jGzeM+Gl7Q2Ll98W
I5gOdJkHSVAP2uK7qSjZ8lPCu4iUYRsae+Psam7Yd6X17RP0M966PlUFj1nnrJjQ
EN4zeh/m01q9vqebB9C1W/ZiJ6rpt6VVHAcOQQ69F/lKdTif4XCvbMIhIXTYNifk
1oIv2qTDnfzzv+bgrlvpBJPpPYR0Oc7WoEpyd1Y9IzienLZi8RnujV//FXEmJ45E
F9GE1HOmoERdEWA1bMYhOO5OfRY1HSMuFMA4+5ojSwKCAQEAmwubio/1uMemw3HQ
kPRGGsdolDR/4tniWGtfy2UzCDY+r7Vaf8eOpIy8UQmatEBsykO+8RrKcvf9Yrc1
WUSVJevqb+67HPq9p6fTz6uSPXwZ+KNZLGXVFVjzfxWM1dvrP7eB7TXKHhmG7t9v
76Yw3SBTObI9LCN3jyVmisDcO+E23E+VVbPOpC260K2b81ocXUPsQ+0LIztu/UIm
p4hyyxug6+3WznTttXNYKch+9IvCgr5Ly0NuUvw+xpMFAZjgwXBu3BKpN4Ek8YAN
dhqnkVveCTguErQF78IlGBbIkUr+8TAbKsW4hggEWxV4V17yAnJsEz65bTtldqTj
qHyzsQKCAQBGhv6g/2d9Rgf1cbBLpns+vel6Wbx3x6c1SptpmgY0kMlR7JeeclM5
qX/EBzzn4pJGp27XaQi3lfVBxyE41HYTHiZVFQF3L/8Rs18XGKBqBxljI4pXrWwt
nRMfyy3lAqvJvhM082A1hiV4FMx40fi4x1JON00SIoIusSlzjOI4zdLEtpDdWRza
g+5hktCvLEbeODfXVJmYUoNXQWldm7f8osDm8eyLMIw5+MCGOgsrZPYgnsD3qxAX
vSgvFSh5oZaDiA4F2tHe3fQBzhIUyHQ8t4xlz447ZBcozv7L1tKWZWgE0f5mGzgu
GBqNbh4y1fWj8Plp/ytoTSBgdBIZdukjAoIBAELJPSVFnlf/gv6OWRCHyKxquGjv
fEn/E8bw5WSqMcj/7wiSJozr0Y8oyWjtWXObliLRQXcEhC8w3lLMjNqnFzQOAI7s
Oa6BQPigqyXZPXG5GK+V0TlUYvZQn9sfCq4YCxUBNtQ4GHbKKl3FGQL3rJiuFr6G
fVcetuDFNCiIGYbUF+giJ2cEN3a/Q+7fR6V4xC7VDdL+BqM09wZ6R98G48XzCKKp
ekNpEfmvJiuk9tFFQwDPWcQ6uyHqesK/Wiweo5nh5y2ZPipwcb0uBoYOQH60NqEL
6MXRVNdtKujjl1XZkG053Nvcz/YfF6lFjDekwgfd9m49b/s0EGTrl7z9z8Y=
-----END RSA PRIVATE KEY-----
# resources:
# requests:
# memory: 256Mi
# cpu: 100m
## MySQL Settings. Currently Harbor does not support an external
## MySQL server, only their own image. Until this is fixed, do not
## Change the settings below.
#
mysql:
image:
repository: vmware/harbor-db
tag: v1.3.0
pullPolicy: IfNotPresent
# If left blank will use the included mysql service name.
host: ~
port: 3306
user: "root"
pass: "registry"
database: "registry"
volumes:
data:
# storageClass: "-"
accessMode: ReadWriteOnce
size: 1Gi
# resources:
# requests:
# memory: 256Mi
# cpu: 100m
registry:
image:
repository: registry
tag: "2.6.2"
pullPolicy: IfNotPresent
httpSecret: not-a-secure-secret
logLevel:
# comment out one of the below to use your cloud's object storage.
# objectStorage:
# gcs:
# keyfile: ""
# bucket: ""
# chunksize: "5242880"
# s3:
# region: ""
# accesskey: ""
# secretkey: ""
# bucket: ""
# encrypt: "true"
# azure:
# accountname: ""
# accountkey: ""
# container: ""
rootCrt: |
-----BEGIN CERTIFICATE-----
MIIE0zCCArugAwIBAgIJAIgs3S+hsjhmMA0GCSqGSIb3DQEBCwUAMAAwHhcNMTcx
MTA5MTcyNzQ5WhcNMjcxMTA3MTcyNzQ5WjAAMIICIjANBgkqhkiG9w0BAQEFAAOC
Ag8AMIICCgKCAgEA4WYbxdrFGG6RnfyYKlHYML3lEqtA9cYWWOynE9BeaEr/cMnM
bBr1dd91/Nm6RiYhQvTDU2Kc6NejqjdliW5B9xUoVKayri8OU81a8ViXeNgKwCPR
AiTTla1zoX5DnvoxpO9G3lxyNvTKXc0cw8NjQDAXpaDbzJYLkshCeuyD9bco8R96
/zrpBEX8tADN3+3yA3fMcZzVXsBm4BTpHJRk/qBpHYEPSHzxyH3iGMNKk3vMUBZz
e0EYkK8NCA2CuEKMnC3acx9IdRwkx10abGvHQCLRCVY7rGoak+b0oZ99RJIRQ9Iq
YXsn8fsMBQly6xxvSeY5XuSP7Xb6JKDt3y8Spi4gR1M/5aEzhuOyu201rMna7Rs/
GPfaKjBlbX0jiLDa7v4zjsBPsPaf/c4uooz3ICLsdukaom+E538R0EiOkXt/wyw2
2YmaWNCsYlEpke7cVC33e/0dPBq4IHsVflawSF9OWS23ikVAs/n+76KjuucEDmbT
aKUYAJjvAmZL14j+EKc/CoplhCe6pKhavjmNIOfCSdlreIPBhOVbf1f817wKoSIZ
qVyCA1AYNkI9RYS00axtJGBGMlKbdQqCNpLL58c6To2awmckIZCEcATKOp++NoGm
Ib0bhdSasdGB5VCtwZVluN8bLl13zBKoxTGjNlEatUGDRnDAnLdZbXXffjsCAwEA
AaNQME4wHQYDVR0OBBYEFCMYYMOL0E/Uyj5wseDfIl7o4ELsMB8GA1UdIwQYMBaA
FCMYYMOL0E/Uyj5wseDfIl7o4ELsMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEL
BQADggIBABG8fPvrrR+erpwQFuB/56j2i6sO+qoOJPpAMYwkzICrT0eerWAavwoy
f0UAKN7cUeEJXjIR7s7CogGFijWdaWaQsXUD0zJq5aotLYZLimEc1O0uAmJEsfYC
v7mG07eU6ge22sSo5hxhVplGt52hnXnT0DdgSRZpq2mvgd9lcopAidM+KHlaasXk
IecHKM99KX9D8smr0AcQ6M/Ygbf2qjO9YRmpBIjyQWEake4y/4LWm+3+v08ecg4B
g+iMC0Rw1QcPqgwaGaWu71RtYhyTg7SnAknb5nBcHIbLb0hdLgQTa3ZdtXgqchIi
GuFlEBmHFZP6bLJORRUQ0ari5wpXIsYfrB4T8PybTzva3OCMlEsMjuysFr9ewhzM
9UGLiSQNDyKA10J8WwlzbeD0AAW944hW4Dbg6SWv4gAo51T+6AukRdup5y6lfQ5a
h4Lbo6pzaA369IsJBntvKvia6hUf/SghnbG7pCHX/AEilcgTb13HndF/G+7aZgKR
mi9qvNRSDsE/BrgZawovp81+j6aL4y6UtXYspHr+SuWsKYsaH7pl5HspNCyJ5vV6
dpJAwosFBqSEnI333wAunpMYmi/jKHH/j4WqjLnCInp0/wouzYu42l8Pmz591BSp
Jag500bEBxqI2RLELgMt/bUdjp4N2M7mrxdrN+2579HTzb6Hviu9
-----END CERTIFICATE-----
## Persist data to a persistent volume
volumes:
data:
# storageClass: "-"
accessMode: ReadWriteOnce
size: 5Gi
# resources:
# requests:
# memory: 256Mi
# cpu: 100m
## Clair support is not yet fully implemented in the Helm Charts
## Enabling it will just break things.
#
clair:
enabled: false
postgresPassword: not-a-secure-password
image:
repository: vmware/clair
tag: v2.0.1-photon
pullPolicy: IfNotPresent
pgImage:
repository: postgres
tag: "9.6.4"
pullPolicy: IfNotPresent
# resources:
# requests:
# memory: 256Mi
# cpu: 100m
# pgResources:
# requests:
# memory: 256Mi
# cpu: 100m
volumes:
pgData:
# storageClass: "-"
accessMode: ReadWriteOnce
size: 1Gi
# resources:
# requests:
# memory: 256Mi
# cpu: 100m
## Notary support is not yet fully implemented in the Helm Charts
## Enabling it will just break things.
#
notary:
enabled: false