Install Harbor
Os requisitos de instalação dependem do tamanho. O recomendado é 4 vCPUs e 160GB de disco para repositórios maiores, mas para um propósito menor 2 vCPUs é suficiente e o espaço é bom usar pelo menos uns 100GB, mas deve ser levado em consideração a quantidade de tags que gostaria de ser mantida por imagem, tamanho das imagens e variedade.
O Harbor é deployado como container, logo é necessário que o host tenha um container runtime disponível. Para instalação em máquinas exclusivas é necessário ter o Docker e o Docker Compose pois o instalador necessitará desses recursos.
As portas utilizadas são as padrões 80 para HTTP e 443 para HTTPS.
Instalação no Host
Caso queira instalar direto no host é necessário fazer o download do arquivos de instalação em release harbor, extrair e rodar o install.
# Mude a versão se necessário
wget https://github.com/goharbor/harbor/releases/download/v2.11.1/harbor-online-installer-v2.11.1.tgz
tar -xzvf harbor-online-installer-v2.11.1.tgz
# Não execute ainda, leia antes o que está abaixo
sudo ./harbor/install.sh --with-trivy
Para um ambiente em produção será necessário configurar o HTTPS e para melhorar a segurança habilitar o internal TLS entre os os componentes internos do Harbor.
O install irá buscar as preferências da instalação no arquivo harbor.yml. Caso não exista, irá seguir com os parâmetros padrão. Se precisar mudar alguma coisa, utilize o template disponível para definir o harbor.yml.
Vou remover um pouco de configuração e deixar as partes mais importantes. Confira o arquivo na íntegra quando for instalar.
cat harbor.yml.tmpl
# Configuration file of Harbor
hostname: reg.mydomain.com
# http related config
http:
port: 80
https:
port: 443
# The path of cert and key files for nginx
certificate: /your/certificate/path
private_key: /your/private/key/path
# enable strong ssl ciphers (default: false)
# strong_ssl_ciphers: false
###### INTERNAL TLS #####
# internal_tls:
# # set enabled to true means internal tls is enabled
# enabled: true
# # put your cert and key files on dir
# dir: /etc/harbor/tls/internal
##### INICIAL PASSWORD #####
harbor_admin_password: Harbor12345
##### CONFIGURAÇÃO DO BANCO DE DADOS #####
database:
password: root123
max_idle_conns: 100
max_open_conns: 900
conn_max_lifetime: 5m
conn_max_idle_time: 0
##### CONFIGURAÇÃO DE STORAGE #####
data_volume: /data
# storage_service:
# ca_bundle:
# filesystem:
# maxthreads: 100
# redirect:
# disable: false
##### CONFIGURAÇÃO DO TRIVY #####
# Trivy configuration
trivy:
ignore_unfixed: false
skip_update: false
skip_java_db_update: false
offline_scan: false
security_check: vuln
insecure: false
timeout: 5m0s
# github_token: xxx
##### CONFIGURAÇÃO DE CONCORRÊNCIA #####
jobservice:
max_job_workers: 10
job_loggers:
- STD_OUTPUT
- FILE
logger_sweeper_duration: 1 #days
notification:
webhook_job_max_retry: 3
webhook_job_http_client_timeout: 3
##### CONFIGURAÇÃO DE LOGS #####
log:
level: info #debug, info, warning, error, fatal
local:
rotate_count: 50
rotate_size: 200M
location: /var/log/harbor
# external_endpoint:
# protocol: tcp
# host: localhost
# port: 5140
_version: 2.11.0
#### CASO USE UM BANCO DE DADOS EXTERNO #####
# external_database:
# harbor:
# host: harbor_db_host
# port: harbor_db_port
# db_name: harbor_db_name
# username: harbor_db_username
# password: harbor_db_password
# ssl_mode: disable
# max_idle_conns: 2
# max_open_conns: 0
#### CUSTOMIZAÇÃO DO REDIS #####
# redis:
# # registry_db_index: 1
# # jobservice_db_index: 2
# # trivy_db_index: 5
# # harbor_db_index: 6
# # cache_layer_db_index: 7
# external_redis:
# host: redis:6379
# # password:
# # username:
# #sentinel_master_set:
# registry_db_index: 1
# jobservice_db_index: 2
# trivy_db_index: 5
# idle_timeout_seconds: 30
# # harbor_db_index: 6
# # cache_layer_db_index: 7
##### CONFIGURAÇÃO DE CACHE #####
cache:
# not enabled by default
enabled: false
# keep cache for one day by default
expire_hours: 24
Instalação no Kubernetes
No Kubernetes temos um Helm chart para auxiliar e tornar tudo mais fácil.
helm repo add harbor https://helm.goharbor.io
helm repo update
helm fetch harbor/harbor --untar
ls harbor
total 252K
drwxr-xr-x 1 david david 114 out 24 10:41 .
drwxr-x--- 1 david david 1,4K out 24 10:41 ..
-rw-r--r-- 1 david david 637 out 24 10:41 Chart.yaml
-rw-r--r-- 1 david david 57 out 24 10:41 .helmignore
-rw-r--r-- 1 david david 12K out 24 10:41 LICENSE
-rw-r--r-- 1 david david 190K out 24 10:41 README.md
drwxr-xr-x 1 david david 204 out 24 10:41 templates
-rw-r--r-- 1 david david 38K out 24 10:41 values.yaml
Todas as configurações agora estarão em values.yaml para ajustes.
Se for fazer a instalação em um cluster local para estudo utilize o kind com a seguinte configuração.
apiVersion: kind.x-k8s.io/v1alpha4
kind: Cluster
name: "study"
networking:
ipFamily: ipv4
# disableDefaultCNI: true
kubeProxyMode: "ipvs"
podSubnet: "10.244.0.0/16"
serviceSubnet: "10.96.0.0/12"
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
- role: worker
- role: worker
- role: worker
Essa configuração é importante pois sem ela, o pod nginx interno do harbor não irá subir.
Aplicando o helm temos
helm install harbor harbor/harbor --namespace harbor --create-namespace --set expose.type=clusterIP --set expose.tls.enabled=false
NAME: harbor
LAST DEPLOYED: Thu Oct 24 22:56:08 2024
NAMESPACE: harbor
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Please wait for several minutes for Harbor deployment to complete.
Then you should be able to visit the Harbor portal at https://core.harbor.domain
For more details, please visit https://github.com/goharbor/harbor
# Recursos criados
kubectl get all -n harbor
NAME READY STATUS RESTARTS AGE
pod/harbor-core-956b455c5-dvshj 1/1 Running 0 6m37s
pod/harbor-database-0 1/1 Running 0 6m37s
pod/harbor-jobservice-cb67f855c-6dhbc 1/1 Running 3 (6m1s ago) 6m37s
pod/harbor-nginx-6cbd4bc77d-8chh9 1/1 Running 0 6m37s
pod/harbor-portal-5cc9d5cc7-czq55 1/1 Running 0 6m37s
pod/harbor-redis-0 1/1 Running 0 6m37s
pod/harbor-registry-86bd7dd86c-tntsk 2/2 Running 0 6m37s
pod/harbor-trivy-0 1/1 Running 0 6m37s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/harbor ClusterIP 10.98.62.126 <none> 80/TCP 6m37s
service/harbor-core ClusterIP 10.110.208.69 <none> 80/TCP 6m37s
service/harbor-database ClusterIP 10.97.47.50 <none> 5432/TCP 6m37s
service/harbor-jobservice ClusterIP 10.104.191.97 <none> 80/TCP 6m37s
service/harbor-portal ClusterIP 10.96.187.79 <none> 80/TCP 6m37s
service/harbor-redis ClusterIP 10.97.190.109 <none> 6379/TCP 6m37s
service/harbor-registry ClusterIP 10.97.250.10 <none> 5000/TCP,8080/TCP 6m37s
service/harbor-trivy ClusterIP 10.110.193.106 <none> 8080/TCP 6m37s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/harbor-core 1/1 1 1 6m37s
deployment.apps/harbor-jobservice 1/1 1 1 6m37s
deployment.apps/harbor-nginx 1/1 1 1 6m37s
deployment.apps/harbor-portal 1/1 1 1 6m37s
deployment.apps/harbor-registry 1/1 1 1 6m37s
NAME DESIRED CURRENT READY AGE
replicaset.apps/harbor-core-956b455c5 1 1 1 6m37s
replicaset.apps/harbor-jobservice-cb67f855c 1 1 1 6m37s
replicaset.apps/harbor-nginx-6cbd4bc77d 1 1 1 6m37s
replicaset.apps/harbor-portal-5cc9d5cc7 1 1 1 6m37s
replicaset.apps/harbor-registry-86bd7dd86c 1 1 1 6m37s
NAME READY AGE
statefulset.apps/harbor-database 1/1 6m37s
statefulset.apps/harbor-redis 1/1 6m37s
statefulset.apps/harbor-trivy 1/1 6m37s
Temos o database, Redis e Trivy como StatefulSet e o conjunto de pods que formam o Harbor (core, nginx, portal, registry, jobservice) como Deployments.
O service que precisamos fazer um port-forward é o service/harbor; o restante dos services são endpoints para comunicação entre os pods.
Como não alteramos nada no values.yaml, os dados para login são username=admin e password=Harbor12345.
E temos nosso sistema.
É claro que o values.yaml precisa ser ajustado para produção, com um externalURL válido, certificados válidos, etc.
Configurações Globais
Um projeto possui vários repositórios. Não acredito ser boa prática liberar que qualquer usuário possa criar um projeto, a não ser que a cota seja bem pequena. Geralmente o que eu vejo é o administrador criando os projetos e definindo mantenedores.
É possível transformar todos os projetos em somente leitura de uma única vez marcando nas opções de configurações globais.
Isso pode ser uma solução para quem tem várias instâncias do Harbor, sendo uma para produção que sofre sincronismo com uma de staging, por exemplo.