mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-22 18:25:56 +01:00
Merge pull request #9829 from reasonerjt/rm-k8s-install
Remove scripts to deploy Harbor on k8s
This commit is contained in:
commit
2b0ede5341
@ -1,156 +1,4 @@
|
||||
**IMPORTANT** This guide is deprecated and not updated any more. We strongly recommend using [Harbor Helm Chart](https://github.com/goharbor/harbor-helm) to deploy latest Harbor release on Kubernetes.
|
||||
Please use [Harbor Helm Chart](https://github.com/goharbor/harbor-helm) to deploy latest Harbor release on Kubernetes.
|
||||
|
||||
## Integration with Kubernetes
|
||||
This Document describes how to deploy Harbor on Kubernetes. It has been verified on **Kubernetes v1.6.5** and **Harbor v1.2.0**
|
||||
|
||||
### Prerequisite
|
||||
|
||||
* You should have domain knowledge about Kubernetes (Deployment, Service, Persistent Volume, Persistent Volume Claim, Config Map, Ingress).
|
||||
* **Optional**: Load the docker images onto worker nodes. *If you skip this step, worker node will pull images from Docker Hub when starting the pods.*
|
||||
* Download the offline installer of Harbor v1.2.0 from the [release](https://github.com/goharbor/harbor/releases) page.
|
||||
* Uncompress the offline installer and get the images tgz file harbor.*.tgz, transfer it to each of the worker nodes.
|
||||
* Load the images into docker:
|
||||
```
|
||||
docker load -i harbor.*.tgz
|
||||
```
|
||||
|
||||
### Configuration
|
||||
We provide a python script `make/kubernetes/k8s-prepare` to generate Kubernetes ConfigMap files.
|
||||
The script is written in python, so you need a version of python in your deployment environment.
|
||||
Also the script need `openssl` to generate private key and certification, make sure you have a workable `openssl`.
|
||||
|
||||
There are some args of the python script:
|
||||
|
||||
- -f: Default Value is `../harbor.cfg`. You can specify other config file of Harbor.
|
||||
- -k: Path to https private key. This arg can overwrite the value of `ssl_cert_key` in `harbor.cfg`.
|
||||
- -c: Path to https certification. This arg can overwrite the value of `ssl_cert` in `harbor.cfg`.
|
||||
|
||||
#### Basic Configuration
|
||||
These Basic Configuration must be set. Otherwise you can't deploy Harbor on Kubernetes.
|
||||
|
||||
- `make/harbor.cfg`: Basic config of Harbor. Please refer to `harbor.cfg`.
|
||||
|
||||
```
|
||||
#Hostname is the endpoint for accessing Harbor,
|
||||
#To accept access from outside of Kubernetes cluster, it should be set to a worker node.
|
||||
hostname = 10.192.168.5
|
||||
```
|
||||
- `make/kubernetes/**/*.svc.yaml`: Specify the service of pods.
|
||||
- `make/kubernetes/**/*.deploy.yaml`: Specify configs of containers.
|
||||
- `make/kubernetes/pv/*.pvc.yaml`: Persistent Volume Claim.
|
||||
You can set capacity of storage in these files. example:
|
||||
|
||||
```yaml
|
||||
resources:
|
||||
requests:
|
||||
# you can set another value to adapt to your needs
|
||||
storage: 100Gi
|
||||
```
|
||||
|
||||
- `make/kubernetes/pv/*.pv.yaml`: Persistent Volume. Be bound with `*.pvc.yaml`.
|
||||
PVs and PVCs are one to one correspondence. If you changed capacity of PVC, you need to set capacity of PV together.
|
||||
example:
|
||||
|
||||
```yaml
|
||||
capacity:
|
||||
# same value with PVC
|
||||
storage: 100Gi
|
||||
```
|
||||
|
||||
In PV, you should set another way to store data rather than `hostPath`:
|
||||
|
||||
```yaml
|
||||
# it's default value, you should use others like nfs.
|
||||
hostPath:
|
||||
path: /data/registry
|
||||
```
|
||||
|
||||
For more information about storage solution, Please check [Kubernetes Document](http://kubernetes.io/docs/user-guide/persistent-volumes/)
|
||||
|
||||
Then you can generate ConfigMap files by :
|
||||
|
||||
```shell
|
||||
python make/kubernetes/k8s-prepare
|
||||
```
|
||||
|
||||
These files will be generated:
|
||||
|
||||
- make/kubernetes/jobservice/jobservice.cm.yaml
|
||||
- make/kubernetes/mysql/mysql.cm.yaml
|
||||
- make/kubernetes/registry/registry.cm.yaml
|
||||
- make/kubernetes/ui/ui.cm.yaml
|
||||
- make/kubernetes/adminserver/adminserver.cm.yaml
|
||||
- make/kubernetes/ingress.yaml
|
||||
|
||||
#### Advanced Configuration
|
||||
If Basic Configuration was not covering your requirements, you can read this section for more details.
|
||||
|
||||
`./k8s-prepare` has a specify format of placeholder:
|
||||
|
||||
- `{{key}}`: It means we should replace the placeholder with the value in `config.cfg` which name is `key`.
|
||||
- `{{num key}}`: It's used for multiple lines text. It will add `num` spaces to the leading of every line in text.
|
||||
|
||||
You can find all configs of Harbor in `make/kubernetes/templates/`. There are specifications of these files:
|
||||
|
||||
- `jobservice.cm.yaml`: ENV and web config of jobservice
|
||||
- `mysql.cm.yaml`: Root password of MySQL
|
||||
- `ingress.yaml`: Https certification and ingress config. If you are familiar with ingress, you can modify it.
|
||||
- `registry.cm.yaml`: Token service certification and registry config
|
||||
Registry use filesystem to store data of images. You can find it like:
|
||||
|
||||
```yaml
|
||||
storage:
|
||||
filesystem:
|
||||
rootdirectory: /storage
|
||||
```
|
||||
|
||||
If you want use another storage backend, please see [Docker Doc](https://docs.docker.com/datacenter/dtr/2.1/guides/configure/configure-storage/)
|
||||
- `ui.cm.yaml`: Token service private key, ENV and web config of ui.
|
||||
- `adminserver.cm.yaml`: Initial values of configuration attributes of Harbor.
|
||||
|
||||
`ui`, `jobservice` and `adminserver` are powered by beego. If you are familiar with beego, you can modify configs in `ui.cm.yaml`, `jobservice.cm.yaml` and `adminserver.cm.yaml`.
|
||||
|
||||
|
||||
### Running
|
||||
When you finished your configuring and generated ConfigMap files, you can run Harbor on kubernetes with these commands:
|
||||
|
||||
```shell
|
||||
# create pv & pvc
|
||||
kubectl apply -f make/kubernetes/pv/log.pv.yaml
|
||||
kubectl apply -f make/kubernetes/pv/registry.pv.yaml
|
||||
kubectl apply -f make/kubernetes/pv/storage.pv.yaml
|
||||
kubectl apply -f make/kubernetes/pv/log.pvc.yaml
|
||||
kubectl apply -f make/kubernetes/pv/registry.pvc.yaml
|
||||
kubectl apply -f make/kubernetes/pv/storage.pvc.yaml
|
||||
|
||||
# create config map
|
||||
kubectl apply -f make/kubernetes/jobservice/jobservice.cm.yaml
|
||||
kubectl apply -f make/kubernetes/mysql/mysql.cm.yaml
|
||||
kubectl apply -f make/kubernetes/registry/registry.cm.yaml
|
||||
kubectl apply -f make/kubernetes/ui/ui.cm.yaml
|
||||
kubectl apply -f make/kubernetes/adminserver/adminserver.cm.yaml
|
||||
|
||||
# create service
|
||||
kubectl apply -f make/kubernetes/jobservice/jobservice.svc.yaml
|
||||
kubectl apply -f make/kubernetes/mysql/mysql.svc.yaml
|
||||
kubectl apply -f make/kubernetes/registry/registry.svc.yaml
|
||||
kubectl apply -f make/kubernetes/ui/ui.svc.yaml
|
||||
kubectl apply -f make/kubernetes/adminserver/adminserver.svc.yaml
|
||||
|
||||
# create k8s deployment
|
||||
kubectl apply -f make/kubernetes/registry/registry.deploy.yaml
|
||||
kubectl apply -f make/kubernetes/mysql/mysql.deploy.yaml
|
||||
kubectl apply -f make/kubernetes/jobservice/jobservice.deploy.yaml
|
||||
kubectl apply -f make/kubernetes/ui/ui.deploy.yaml
|
||||
kubectl apply -f make/kubernetes/adminserver/adminserver.deploy.yaml
|
||||
|
||||
# create k8s ingress
|
||||
kubectl apply -f make/kubernetes/ingress.yaml
|
||||
```
|
||||
|
||||
After the pods are running, you can access Harbor's UI via the configured endpoint `10.192.168.5` or issue docker commands such as `docker login 10.192.168.5` to interact with the registry.
|
||||
|
||||
#### Limitation
|
||||
1. Current deployment is http only, to enable https you need to either add another layer of proxy or modify the ingress.yaml to enable https and include a correct certificate
|
||||
2. Current deployment does not include Clair and Notary, which are supported in docker-compose deployment. They will be supported in near future, stay tuned.
|
||||
**NOTE** Please open issue to the `harbor-helm` repo if you see issues deploying the helm chart.
|
||||
|
||||
|
@ -1,228 +0,0 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: adminserver
|
||||
labels:
|
||||
name: adminserver
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: adminserver-apps
|
||||
spec:
|
||||
containers:
|
||||
- name: adminserver-app
|
||||
image: vmware/harbor-adminserver:v1.2.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
env:
|
||||
- name: LOG_LEVEL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: LOG_LEVEL
|
||||
- name: JSON_CFG_STORE_PATH
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: JSON_CFG_STORE_PATH
|
||||
- name: EXT_ENDPOINT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: EXT_ENDPOINT
|
||||
- name: AUTH_MODE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: AUTH_MODE
|
||||
- name: SELF_REGISTRATION
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: SELF_REGISTRATION
|
||||
- name: LDAP_URL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: LDAP_URL
|
||||
- name: LDAP_SEARCH_DN
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: LDAP_SEARCH_DN
|
||||
- name: LDAP_SEARCH_PWD
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: LDAP_SEARCH_PWD
|
||||
- name: LDAP_BASE_DN
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: LDAP_BASE_DN
|
||||
- name: LDAP_FILTER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: LDAP_FILTER
|
||||
- name: LDAP_UID
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: LDAP_UID
|
||||
- name: LDAP_SCOPE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: LDAP_SCOPE
|
||||
- name: LDAP_TIMEOUT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: LDAP_TIMEOUT
|
||||
- name: DATABASE_TYPE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: DATABASE_TYPE
|
||||
- name: MYSQL_HOST
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: MYSQL_HOST
|
||||
- name: MYSQL_PORT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: MYSQL_PORT
|
||||
- name: MYSQL_USR
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: MYSQL_USR
|
||||
- name: MYSQL_PWD
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: MYSQL_PWD
|
||||
- name: MYSQL_DATABASE
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: MYSQL_DATABASE
|
||||
- name: REGISTRY_URL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: REGISTRY_URL
|
||||
- name: TOKEN_SERVICE_URL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: TOKEN_SERVICE_URL
|
||||
- name: EMAIL_HOST
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: EMAIL_HOST
|
||||
- name: EMAIL_PORT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: EMAIL_PORT
|
||||
- name: EMAIL_USR
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: EMAIL_USR
|
||||
- name: EMAIL_PWD
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: EMAIL_PWD
|
||||
- name: EMAIL_SSL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: EMAIL_SSL
|
||||
- name: EMAIL_FROM
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: EMAIL_FROM
|
||||
- name: EMAIL_IDENTITY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: EMAIL_IDENTITY
|
||||
- name: HARBOR_ADMIN_PASSWORD
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: HARBOR_ADMIN_PASSWORD
|
||||
- name: PROJECT_CREATION_RESTRICTION
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: PROJECT_CREATION_RESTRICTION
|
||||
- name: VERIFY_REMOTE_CERT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: VERIFY_REMOTE_CERT
|
||||
- name: MAX_JOB_WORKERS
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: MAX_JOB_WORKERS
|
||||
- name: CORE_SECRET
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: CORE_SECRET
|
||||
- name: JOBSERVICE_SECRET
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: JOBSERVICE_SECRET
|
||||
- name: TOKEN_EXPIRATION
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: TOKEN_EXPIRATION
|
||||
- name: GODEBUG
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: GODEBUG
|
||||
- name: ADMIRAL_URL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: ADMIRAL_URL
|
||||
- name: WITH_NOTARY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: WITH_NOTARY
|
||||
- name: RESET
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-adminserver-config
|
||||
key: RESET
|
||||
#Workaround the volume API issue.
|
||||
- name: IMAGE_STORE_PATH
|
||||
value: "/"
|
||||
ports:
|
||||
- containerPort: 80
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /etc/adminserver/
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: harbor-adminserver-config
|
||||
items:
|
||||
- key: SECRET_KEY
|
||||
path: key
|
@ -1,9 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: adminserver
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
selector:
|
||||
name: adminserver-apps
|
@ -1,59 +0,0 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: core
|
||||
labels:
|
||||
name: core
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: core-apps
|
||||
spec:
|
||||
containers:
|
||||
- name: core-app
|
||||
image: vmware/harbor-core:v1.2.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
env:
|
||||
- name: CONFIG_PATH
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-core-config
|
||||
key: CONFIG_PATH
|
||||
- name: LOG_LEVEL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-core-config
|
||||
key: LOG_LEVEL
|
||||
- name: CORE_SECRET
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-core-config
|
||||
key: CORE_SECRET
|
||||
- name: JOBSERVICE_SECRET
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-core-config
|
||||
key: JOBSERVICE_SECRET
|
||||
- name: GODEBUG
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-core-config
|
||||
key: GODEBUG
|
||||
ports:
|
||||
- containerPort: 80
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /etc/core
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: harbor-core-config
|
||||
items:
|
||||
- key: config
|
||||
path: app.conf
|
||||
- key: pkey
|
||||
path: private_key.pem
|
||||
- key: SECRET_KEY
|
||||
path: key
|
@ -1,9 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: core
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
selector:
|
||||
name: core-apps
|
@ -1,60 +0,0 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: jobservice
|
||||
labels:
|
||||
name: jobservice
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: jobservice-apps
|
||||
spec:
|
||||
containers:
|
||||
- name: jobservice-app
|
||||
image: vmware/harbor-jobservice:v1.2.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
env:
|
||||
- name: CORE_SECRET
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-jobservice-config
|
||||
key: CORE_SECRET
|
||||
- name: JOBSERVICE_SECRET
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-jobservice-config
|
||||
key: JOBSERVICE_SECRET
|
||||
- name: CONFIG_PATH
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-jobservice-config
|
||||
key: CONFIG_PATH
|
||||
- name: LOG_LEVEL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-jobservice-config
|
||||
key: LOG_LEVEL
|
||||
- name: GODEBUG
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-jobservice-config
|
||||
key: GODEBUG
|
||||
ports:
|
||||
- containerPort: 80
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /etc/jobservice
|
||||
- name: logs
|
||||
mountPath: /var/log/jobs
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: harbor-jobservice-config
|
||||
items:
|
||||
- key: config
|
||||
path: app.conf
|
||||
- name: logs
|
||||
persistentVolumeClaim:
|
||||
claimName: log-pvc
|
@ -1,9 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: jobservice
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
selector:
|
||||
name: jobservice-apps
|
@ -1,216 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function, unicode_literals # We require Python 2.6 or later
|
||||
import sys
|
||||
import argparse
|
||||
import io
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import string
|
||||
import subprocess
|
||||
|
||||
if sys.version_info[:3][0] == 2:
|
||||
import ConfigParser as configparser
|
||||
import StringIO as io
|
||||
|
||||
if sys.version_info[:3][0] == 3:
|
||||
import configparser as configparser
|
||||
import io as io
|
||||
|
||||
|
||||
# prepare base dir
|
||||
base_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
parser = argparse.ArgumentParser(description='Generate *.cm.yaml')
|
||||
parser.add_argument('-f', default=os.path.join(base_dir, '../harbor.cfg'),
|
||||
dest='config_file', help='[Optional] path of harbor config file')
|
||||
parser.add_argument('-k', default='',
|
||||
dest='private_key', help='[Optional] path of harbor https private key(pem)')
|
||||
parser.add_argument('-c', default='',
|
||||
dest='cert', help='[Optional] harbor path of https cert(pem)')
|
||||
parser.add_argument('-j', default='',
|
||||
dest='jobservice_secret', help="[Optional] path of harbor secret key(16 characters)")
|
||||
parser.add_argument('-s', default='',
|
||||
dest='secret_key', help="[Optional] path of harbor secret key(16 characters)")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# read config file
|
||||
config_str = ''
|
||||
if os.path.isfile(args.config_file):
|
||||
with open(args.config_file) as conf:
|
||||
config_str = conf.read()
|
||||
else:
|
||||
raise Exception('Error: No such file(' + args.config_file + ')')
|
||||
|
||||
config_str = '[harbor]\n' + config_str
|
||||
fp = io.StringIO()
|
||||
fp.write(config_str)
|
||||
fp.seek(0, os.SEEK_SET)
|
||||
config = configparser.RawConfigParser()
|
||||
config.readfp(fp)
|
||||
|
||||
|
||||
def get_config(key):
|
||||
"""get value by key
|
||||
"""
|
||||
if config.has_option('harbor', key):
|
||||
return config.get('harbor', key)
|
||||
print('Warning: Key(' + key + ') is not existing. Use empty string as default')
|
||||
return ''
|
||||
|
||||
|
||||
def set_config(key, value):
|
||||
"""set key & value
|
||||
"""
|
||||
config.set('harbor', key, value)
|
||||
|
||||
# relative path with config file
|
||||
def rel_path(p):
|
||||
if p[0] == '/':
|
||||
return p
|
||||
config_path = args.config_file
|
||||
if config_path[0] != '/':
|
||||
config_path = os.path.join(os.getcwd(), config_path)
|
||||
return os.path.join(os.path.dirname(config_path), p)
|
||||
|
||||
# path of private key
|
||||
pk_path = args.private_key
|
||||
if pk_path == '':
|
||||
pk_path = get_config('ssl_cert_key')
|
||||
if pk_path != '':
|
||||
pk_path = rel_path(pk_path)
|
||||
|
||||
# path of cert
|
||||
cert_path = args.cert
|
||||
if cert_path == '':
|
||||
cert_path = get_config('ssl_cert')
|
||||
if cert_path != '':
|
||||
cert_path = rel_path(cert_path)
|
||||
|
||||
|
||||
# validate
|
||||
if get_config('ui_url_protocol') == 'https':
|
||||
if pk_path == '':
|
||||
raise Exception("Error: The protocol is https but attribute ssl_cert_key is not set")
|
||||
if cert_path == '':
|
||||
raise Exception("Error: The protocol is https but attribute ssl_cert is not set")
|
||||
else:
|
||||
pk_path = ''
|
||||
cert_path = ''
|
||||
|
||||
|
||||
# read jobservice secret key
|
||||
if args.jobservice_secret != '':
|
||||
if os.path.isfile(args.jobservice_secret):
|
||||
key = ''
|
||||
with open(args.jobservice_secret, 'r') as skey:
|
||||
key = skey.read()
|
||||
if len(key) != 16:
|
||||
raise Exception('Error: The length of secret key has to be 16 characters!')
|
||||
set_config('jobservice_secret', key)
|
||||
else:
|
||||
set_config('jobservice_secret', ''.join(random.choice(
|
||||
string.ascii_letters + string.digits) for i in range(16)))
|
||||
|
||||
# read ldap secret key
|
||||
if args.secret_key != '':
|
||||
if os.path.isfile(args.secret_key):
|
||||
key = ''
|
||||
with open(args.secret_key, 'r') as skey:
|
||||
key = skey.read()
|
||||
if len(key) != 16:
|
||||
raise Exception('Error: The length of secret key has to be 16 characters!')
|
||||
set_config('secret_key', key)
|
||||
else:
|
||||
set_config('secret_key', ''.join(random.choice(
|
||||
string.ascii_letters + string.digits) for i in range(16)))
|
||||
|
||||
# read https pkey & cert
|
||||
if pk_path != '':
|
||||
if os.path.isfile(pk_path):
|
||||
with open(pk_path, 'r') as pkey:
|
||||
set_config('https_pkey', pkey.read())
|
||||
else:
|
||||
raise Exception('Error: https private key is not existing')
|
||||
else:
|
||||
set_config('https_pkey', 'USE_HTTP')
|
||||
|
||||
if cert_path != '':
|
||||
if os.path.isfile(cert_path):
|
||||
with open(cert_path, 'r') as cert:
|
||||
set_config('https_cert', cert.read())i
|
||||
else:
|
||||
raise Exception('Error: https cert is not existing')
|
||||
else:
|
||||
set_config('https_cert', 'USE_HTTP')
|
||||
|
||||
|
||||
# add configs
|
||||
set_config('core_url', get_config('ui_url_protocol') +
|
||||
'://' + get_config('hostname'))
|
||||
set_config('core_secret', ''.join(random.choice(
|
||||
string.ascii_letters + string.digits) for i in range(16)))
|
||||
|
||||
# generate auth pkey & cert
|
||||
with open(os.devnull, 'w') as devnull:
|
||||
openssl = subprocess.call(['which','openssl'], stdout=devnull, stderr=devnull)
|
||||
if openssl == 0:
|
||||
pkey = subprocess.check_output(['openssl','genrsa','4096'], stderr=devnull)
|
||||
empty_subj = "/C=/ST=/L=/O=/CN=/"
|
||||
openssl = subprocess.Popen(['openssl', 'req', '-new', '-x509', '-key', '/dev/stdin', '-days', '3650', '-subj', empty_subj],
|
||||
stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=devnull)
|
||||
cert = openssl.communicate(input=pkey)[0]
|
||||
set_config('auth_pkey', pkey.decode())
|
||||
set_config('auth_cert', cert.decode())
|
||||
else:
|
||||
set_config('auth_pkey', 'NEED_SET')
|
||||
set_config('auth_cert', 'NEED_SET')
|
||||
print('Warning: auth_pkey and auth_cert cannot be generated automatically without openssl. Please set it manually')
|
||||
|
||||
|
||||
|
||||
variable = re.compile(r'{{.+?}}')
|
||||
detail = re.compile(r'((\d+) )?([a-zA-Z_0-9-]+)')
|
||||
def render_template(tmpl):
|
||||
"""render template
|
||||
replace {{(number of leading spaces)name}} with config
|
||||
examples:
|
||||
config:
|
||||
hostname='test\ntest'
|
||||
|
||||
{{hostname}} -> 'test\ntest'
|
||||
{{4 hostname}} -> 'test\n test'
|
||||
"""
|
||||
matches = variable.findall(tmpl)
|
||||
for match in matches:
|
||||
segs = detail.search(match)
|
||||
if segs.group() == '':
|
||||
raise Exception('Error: Invalid template item(' + match + ')')
|
||||
value = get_config(segs.group(3))
|
||||
spaces = segs.group(2)
|
||||
if spaces != '' and spaces != None:
|
||||
leading = ''.join(' ' for i in range(int(spaces)))
|
||||
value = str(value).replace('\n', '\n' + leading)
|
||||
tmpl = tmpl.replace(match, value)
|
||||
return tmpl
|
||||
|
||||
|
||||
def generate_template(tmpl, dest):
|
||||
"""generate file
|
||||
"""
|
||||
with open(tmpl) as tmpl:
|
||||
with open(dest, 'w') as dest:
|
||||
dest.write(render_template(tmpl.read()))
|
||||
|
||||
|
||||
template_dir = os.path.join(base_dir, 'templates')
|
||||
output_dir = base_dir
|
||||
generate_template(os.path.join(template_dir, 'ui.cm.yaml'), os.path.join(output_dir, 'ui/ui.cm.yaml'))
|
||||
generate_template(os.path.join(template_dir, 'jobservice.cm.yaml'), os.path.join(output_dir, 'jobservice/jobservice.cm.yaml'))
|
||||
generate_template(os.path.join(template_dir, 'mysql.cm.yaml'), os.path.join(output_dir, 'mysql/mysql.cm.yaml'))
|
||||
generate_template(os.path.join(template_dir, 'registry.cm.yaml'), os.path.join(output_dir, 'registry/registry.cm.yaml'))
|
||||
generate_template(os.path.join(template_dir, 'adminserver.cm.yaml'), os.path.join(output_dir, 'adminserver/adminserver.cm.yaml'))
|
||||
generate_template(os.path.join(template_dir, 'ingress.yaml'), os.path.join(output_dir, 'ingress.yaml'))
|
||||
|
@ -1,32 +0,0 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mysql
|
||||
labels:
|
||||
name: mysql
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: mysql-apps
|
||||
spec:
|
||||
containers:
|
||||
- name: mysql-app
|
||||
image: vmware/harbor-db:v1.2.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 3306
|
||||
env:
|
||||
- name: MYSQL_ROOT_PASSWORD
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: harbor-mysql-config
|
||||
key: MYSQL_ROOT_PASSWORD
|
||||
volumeMounts:
|
||||
- name: mysql-storage
|
||||
mountPath: /var/lib/mysql
|
||||
volumes:
|
||||
- name: mysql-storage
|
||||
persistentVolumeClaim:
|
||||
claimName: storage-pvc
|
@ -1,9 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mysql
|
||||
spec:
|
||||
ports:
|
||||
- port: 3306
|
||||
selector:
|
||||
name: mysql-apps
|
@ -1,14 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: log-pv
|
||||
labels:
|
||||
type: log
|
||||
spec:
|
||||
capacity:
|
||||
storage: 5Gi
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
hostPath:
|
||||
path: /data/logs
|
@ -1,13 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: log-pvc
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 5Gi
|
||||
selector:
|
||||
matchLabels:
|
||||
type: log
|
@ -1,14 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: registry-pv
|
||||
labels:
|
||||
type: registry
|
||||
spec:
|
||||
capacity:
|
||||
storage: 100Gi
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
hostPath:
|
||||
path: /data/registry
|
@ -1,13 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: registry-pvc
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 100Gi
|
||||
selector:
|
||||
matchLabels:
|
||||
type: registry
|
@ -1,14 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: storage-pv
|
||||
labels:
|
||||
type: storage
|
||||
spec:
|
||||
capacity:
|
||||
storage: 5Gi
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
hostPath:
|
||||
path: /data/storage
|
@ -1,13 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: storage-pvc
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 5Gi
|
||||
selector:
|
||||
matchLabels:
|
||||
type: storage
|
@ -1,37 +0,0 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: registry
|
||||
labels:
|
||||
name: registry
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: registry-apps
|
||||
spec:
|
||||
containers:
|
||||
- name: registry-app
|
||||
image: vmware/registry:2.6.2-photon
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 5000
|
||||
- containerPort: 5001
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /etc/registry
|
||||
- name: storage
|
||||
mountPath: /storage
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: harbor-registry-config
|
||||
items:
|
||||
- key: config
|
||||
path: config.yml
|
||||
- key: cert
|
||||
path: root.crt
|
||||
- name: storage
|
||||
persistentVolumeClaim:
|
||||
claimName: registry-pvc
|
@ -1,12 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: registry
|
||||
spec:
|
||||
ports:
|
||||
- name: repo
|
||||
port: 5000
|
||||
- name: debug
|
||||
port: 5001
|
||||
selector:
|
||||
name: registry-apps
|
@ -1,46 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: harbor-adminserver-config
|
||||
data:
|
||||
LOG_LEVEL: debug
|
||||
AUTH_MODE: db_auth
|
||||
SELF_REGISTRATION: "on"
|
||||
LDAP_URL: ldaps://ldap.mydomain.com
|
||||
LDAP_SEARCH_DN: ""
|
||||
LDAP_SEARCH_PWD: ""
|
||||
LDAP_BASE_DN: "ou=people,dc=mydomain,dc=com"
|
||||
LDAP_FILTER: ""
|
||||
LDAP_UID: uid
|
||||
LDAP_SCOPE: "3"
|
||||
LDAP_TIMEOUT: "5"
|
||||
DATABASE_TYPE: mysql
|
||||
MYSQL_HOST: mysql
|
||||
MYSQL_PORT: "3306"
|
||||
MYSQL_USR: root
|
||||
MYSQL_PWD: "{{db_password}}"
|
||||
MYSQL_DATABASE: registry
|
||||
REGISTRY_URL: http://registry:5000
|
||||
TOKEN_SERVICE_URL: http://core/service/token
|
||||
EMAIL_HOST: smtp.mydomain.com
|
||||
EMAIL_PORT: "25"
|
||||
EMAIL_USR: sample_admin@mydomain.com
|
||||
EMAIL_PWD: abc
|
||||
EMAIL_SSL: "false"
|
||||
EMAIL_FROM: "admin <sample_admin@mydomain.com>"
|
||||
EMAIL_IDENTITY: ""
|
||||
HARBOR_ADMIN_PASSWORD: "{{harbor_admin_password}}"
|
||||
PROJECT_CREATION_RESTRICTION: everyone
|
||||
VERIFY_REMOTE_CERT: "on"
|
||||
MAX_JOB_WORKERS: "{{max_job_workers}}"
|
||||
CORE_SECRET: "{{core_secret}}"
|
||||
JOBSERVICE_SECRET: "{{jobservice_secret}}"
|
||||
TOKEN_EXPIRATION: "30"
|
||||
GODEBUG: "netdns=cgo"
|
||||
ADMIRAL_URL: NA
|
||||
WITH_NOTARY: "False"
|
||||
RESET: "false"
|
||||
EXT_ENDPOINT: "{{core_url}}"
|
||||
TOKEN_URL: http://core
|
||||
JSON_CFG_STORE_PATH: "/etc/config/config.json"
|
||||
SECRET_KEY: "{{secret_key}}"
|
@ -1,22 +0,0 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: harbor
|
||||
spec:
|
||||
rules:
|
||||
- host: {{hostname}}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: core
|
||||
servicePort: 80
|
||||
- path: /v2
|
||||
backend:
|
||||
serviceName: registry
|
||||
servicePort: repo
|
||||
- path: /service
|
||||
backend:
|
||||
serviceName: core
|
||||
servicePort: 80
|
||||
|
@ -1,17 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: harbor-jobservice-config
|
||||
data:
|
||||
CORE_SECRET: "{{core_secret}}"
|
||||
JOBSERVICE_SECRET: "{{jobservice_secret}}"
|
||||
SECRET_KEY: "{{secret_key}}"
|
||||
MAX_JOB_WORKERS: "{{max_job_workers}}"
|
||||
LOG_LEVEL: debug
|
||||
GODEBUG: netdns=cgo
|
||||
CONFIG_PATH: /etc/jobservice/app.conf
|
||||
config: |
|
||||
appname = jobservice
|
||||
runmode = dev
|
||||
[dev]
|
||||
httpport = 80
|
@ -1,6 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: harbor-mysql-config
|
||||
data:
|
||||
MYSQL_ROOT_PASSWORD: "{{db_password}}"
|
@ -1,44 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: harbor-registry-config
|
||||
data:
|
||||
config: |
|
||||
version: 0.1
|
||||
log:
|
||||
level: debug
|
||||
fields:
|
||||
service: registry
|
||||
storage:
|
||||
filesystem:
|
||||
rootdirectory: /storage
|
||||
cache:
|
||||
layerinfo: inmemory
|
||||
maintenance:
|
||||
uploadpurging:
|
||||
enabled: false
|
||||
delete:
|
||||
enabled: true
|
||||
http:
|
||||
addr: :5000
|
||||
secret: placeholder
|
||||
debug:
|
||||
addr: localhost:5001
|
||||
auth:
|
||||
token:
|
||||
issuer: harbor-token-issuer
|
||||
realm: {{core_url}}/service/token
|
||||
rootcertbundle: /etc/registry/root.crt
|
||||
service: harbor-registry
|
||||
notifications:
|
||||
endpoints:
|
||||
- name: harbor
|
||||
disabled: false
|
||||
url: http://core/service/notifications
|
||||
timeout: 3000ms
|
||||
threshold: 5
|
||||
backoff: 1s
|
||||
|
||||
cert: |
|
||||
{{4 auth_cert}}
|
||||
|
@ -1,30 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: harbor-core-config
|
||||
data:
|
||||
CONFIG_PATH: /etc/core/app.conf
|
||||
LOG_LEVEL: debug
|
||||
CORE_SECRET: "{{core_secret}}"
|
||||
JOBSERVICE_SECRET: "{{jobservice_secret}}"
|
||||
GODEBUG: netdns=cgo
|
||||
SECRET_KEY: "{{secret_key}}"
|
||||
config: |
|
||||
appname = registry
|
||||
runmode = dev
|
||||
[lang]
|
||||
types = en-US|zh-CN
|
||||
names = en-US|zh-CN
|
||||
[dev]
|
||||
httpport = 80
|
||||
[mail]
|
||||
host = {{email_server}}
|
||||
port = {{email_server_port}}
|
||||
username = {{email_username}}
|
||||
password = {{email_password}}
|
||||
from = {{email_from}}
|
||||
ssl = {{email_ssl}}
|
||||
pkey: |
|
||||
{{4 auth_pkey}}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user