# Install Harbor using Podman ## 先決條件 - [x] 已安裝 `podman`,版本 4.9.x 或以上 - [x] 已安裝 `curl`, `wget`, `jq`, `apache2-utils` 工具 ## Setp1: 建立 podman network ``` sudo podman network create --subnet 10.8.0.0/16 harbor ``` > 若不想建立網路,可以使用預設 podman 網路,但需要將 dns 解析打開 > 預設網路目前版本沒有開啟 dns 解析,要不然容器之間沒法透過主機名稱進行互訪。 > 修改設定檔後需要將網路介面刪除或重新啟動主機才能生效。 ## Step2: 下載 Harbor 離線安裝所需的檔案 1. 下載官方發布的離線版本 ``` HARBOR_VERSION=$(curl -s https://api.github.com/repos/goharbor/harbor/releases/latest | jq -r .tag_name) wget https://github.com/goharbor/harbor/releases/download/${HARBOR_VERSION}/harbor-offline-installer-${HARBOR_VERSION}.tgz ``` > 第一行命令會直接到 github 抓 Harbor 官方最新 release 的版本,如果要安裝其他版本,請自行定義 2. 解壓縮檔案,並切換工作目錄 ``` tar zxf harbor-offline-installer-${HARBOR_VERSION}.tgz; cd harbor ``` 3. 匯入 image ``` sudo podman load -i harbor.${HARBOR_VERSION}.tar.gz ``` 4. 檢查是否成功 ``` sudo podman images ``` 執行結果如下 : ``` REPOSITORY TAG IMAGE ID CREATED SIZE localhost/goharbor/harbor-exporter v2.13.1 8323e56fa034 2 months ago 130 MB localhost/goharbor/redis-photon v2.13.1 27079bef6812 2 months ago 168 MB localhost/goharbor/trivy-adapter-photon v2.13.1 9d2de710e1bc 2 months ago 388 MB localhost/goharbor/harbor-registryctl v2.13.1 1ca7f7dffcb8 2 months ago 163 MB localhost/goharbor/registry-photon v2.13.1 251eb949b8fc 2 months ago 86.8 MB localhost/goharbor/nginx-photon v2.13.1 3a0ac2771512 2 months ago 153 MB localhost/goharbor/harbor-log v2.13.1 49f7cdb104f3 2 months ago 166 MB localhost/goharbor/harbor-jobservice v2.13.1 b964386ce624 2 months ago 176 MB localhost/goharbor/harbor-core v2.13.1 701038c9f9cf 2 months ago 200 MB localhost/goharbor/harbor-portal v2.13.1 254c145df624 2 months ago 162 MB localhost/goharbor/harbor-db v2.13.1 8645cd204f13 2 months ago 278 MB localhost/goharbor/prepare v2.13.1 eeb5b545352d 2 months ago 214 MB ``` ## Step3: 部署 Harbor 各元件 注意,Harbor 各別的元件相互依賴,需要依照順序部署,否則元件無法啟動 ### 3.1. 部署 redis 1. 建立 redis container ``` # 定義 Redis 資料永存目錄區 REDIS_PV="/data/redis" [ ! -d ${REDIS_PV} ] && sudo mkdir -p ${REDIS_PV} sudo chown 999:999 ${REDIS_PV} sudo podman run --name redis --detach \ --network=harbor \ --cap-add=chown --cap-add=setuid \ --cap-add=setgid --cap-drop=all \ --volume=${REDIS_PV}:/var/lib/redis:z \ goharbor/redis-photon:${HARBOR_VERSION} ``` ### 3.2. 部署 postgresql 1. 建立 secrt:資料庫 root 使用者的密碼,這裡使用隨機密碼 ``` tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 16 | sudo podman secret create db-secret - ``` 2. 建立 pg container ``` # 定義 Redis 資料永存目錄區 PG_PV="/data/database" [ ! -d ${PG_PV} ] && sudo mkdir -p ${PG_PV} sudo chown -R 999:999 ${PG_PV} sudo podman run --name postgresql \ --detach --network=harbor \ --cap-add=chown --cap-add=setuid \ --cap-add=setgid --cap-add=dac_override \ --cap-drop=all --shm-size=1gb \ --secret=db-secret,type=env,target=POSTGRES_PASSWORD \ --volume=${PG_PV}:/var/lib/postgresql/data:z \ goharbor/harbor-db:${HARBOR_VERSION} ``` ### 3.3. 部署 Registry 1. 編輯 registry 設定檔 ``` sudo mkdir -p /etc/harbor sudo nano /etc/harbor/registry.yml ``` 檔案內容如下 : ``` version: 0.1 log: level: info fields: service: registry storage: cache: layerinfo: redis filesystem: rootdirectory: /storage maintenance: uploadpurging: enabled: true age: 168h interval: 24h dryrun: false delete: enabled: true redis: addr: redis:6379 readtimeout: 10s writetimeout: 10s dialtimeout: 10s password: db: 1 enableTLS: false pool: maxidle: 100 maxactive: 500 idletimeout: 60s http: addr: :5000 secret: placeholder debug: addr: :9090 prometheus: enabled: true path: /metrics auth: htpasswd: realm: harbor-registry-basic-realm path: /etc/registry/passwd validation: disabled: true compatibility: schema1: enabled: true ``` 2. 建立密碼 ``` USERNAME="harbor_registry_user" PASSWORD="password" HASH=$(htpasswd -nbB -C 5 "$USERNAME" "$PASSWORD" | cut -d: -f2) echo "$USERNAME:$HASH" | sudo podman secret create registry-auth - ``` 3. 啟動 registry container ``` # 定義 REGISTRY 資料永存目錄區 REGISTRY_PV="/data/registry" [ ! -d ${REGISTRY_PV} ] && sudo mkdir -p ${REGISTRY_PV} sudo chown 10000:10000 ${REGISTRY_PV} sudo podman run --name=registry \ --detach --network=harbor \ --cap-add=chown --cap-add=setuid \ --cap-add=setgid --cap-drop=all \ --secret=registry-auth,target=/etc/registry/passwd \ --volume=${REGISTRY_PV}:/storage:z \ --volume=/etc/harbor/registry.yml:/etc/registry/config.yml:ro \ --volume=/etc/ssl/certs/ca-certificates.crt:/etc/registry/root.crt:ro \ goharbor/registry-photon:${HARBOR_VERSION} ``` ### 3.4. 部署 portal 1. 建立設定檔 ``` sudo nano /etc/harbor/portal.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 { listen 8080; 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 /devcenter-api-2.0 { try_files $uri $uri/ /swagger-ui-index.html; } location / { try_files $uri $uri/ /index.html; } location = /index.html { add_header Cache-Control "no-store, no-cache, must-revalidate"; } } } ``` 2. 建立 portal container ``` sudo podman run --name=portal \ --detach --network=harbor \ --cap-add=setuid --cap-add=setgid \ --cap-add=net_bind_service --cap-drop=all \ --volume=/etc/harbor/portal.conf:/etc/nginx/nginx.conf:ro \ goharbor/harbor-portal:${HARBOR_VERSION} ``` ### 3.5. 部署 registryctl 1. 編輯設定檔 ``` sudo nano /etc/harbor/registryctl.yml ``` 檔案內容如下 : ``` --- protocol: "http" port: 8080 log_level: info registry_config: "/etc/registry/config.yml" ``` 2. 建立密碼 ``` # 產生 harbor 私鑰: 用於建立 token openssl genrsa 4096 | openssl pkey -traditional | sudo podman secret create harbor-key - # 產生 harbor secretkey openssl rand -base64 12 | head -c 16| sudo podman secret create harbor-secretkey - # harbor 密碼:用於其他元件與 harbor 通訊認證 openssl rand -base64 12 | head -c 16 | sudo podman secret create harbor-secret - # jobservice 密碼: 用於與 jobservice 通訊認證 openssl rand -base64 12 | head -c 16 | sudo podman secret create jobservice-secret - # registry 密碼: 主要給 harbor 和 jobservice 使用 printf "password" | sudo podman secret create registry-passwd - ``` 3. 建立 registryctl container ``` sudo podman run --name=registryctl \ --detach --network=harbor \ --cap-add=setuid --cap-add=setgid --cap-drop=all \ --secret=harbor-secret,type=env,target=CORE_SECRET \ --secret=jobservice-secret,type=env,target=JOBSERVICE_SECRET \ --volume=${REGISTRY_PV}:/storage:z \ --volume=/etc/harbor/registry.yml:/etc/registry/config.yml:ro \ --volume=/etc/harbor/registryctl.yml:/etc/registryctl/config.yml:ro \ --volume=/etc/ssl/certs/ca-certificates.crt:/etc/registry/root.crt:ro \ goharbor/harbor-registryctl:${HARBOR_VERSION} ``` ### 3.6. 部署 harbor 1. 編輯設定檔 ``` sudo nano /etc/harbor/harbor.conf ``` 檔案內容如下 : ``` appname = Harbor runmode = prod enablegzip = true [prod] httpport = 8080 ``` 2. 編輯 Harbor 運作所需之環境變數 ``` sudo nano /etc/harbor/coreenv ``` 檔案內容如下 : ``` CONFIG_PATH=/etc/core/app.conf UAA_CA_ROOT=/etc/core/certificates/uaa_ca.pem _REDIS_URL_CORE=redis://redis:6379?idle_timeout_seconds=30 SYNC_QUOTA=true _REDIS_URL_REG=redis://redis:6379/1?idle_timeout_seconds=30 LOG_LEVEL=info DATABASE_TYPE=postgresql POSTGRESQL_HOST=postgresql POSTGRESQL_PORT=5432 POSTGRESQL_USERNAME=postgres POSTGRESQL_DATABASE=registry POSTGRESQL_SSLMODE=disable POSTGRESQL_MAX_IDLE_CONNS=100 POSTGRESQL_MAX_OPEN_CONNS=900 POSTGRESQL_CONN_MAX_LIFETIME=5m POSTGRESQL_CONN_MAX_IDLE_TIME=0 REGISTRY_URL=http://registry:5000 PORTAL_URL=http://portal:8080 TOKEN_SERVICE_URL=http://core:8080/service/token HARBOR_ADMIN_PASSWORD=Harbor12345 MAX_JOB_WORKERS=10 WITH_TRIVY=True CORE_URL=http://core:8080 CORE_LOCAL_URL=http://127.0.0.1:8080 JOBSERVICE_URL=http://jobservice:8080 TRIVY_ADAPTER_URL=http://trivy-adapter:8080 REGISTRY_STORAGE_PROVIDER_NAME=filesystem READ_ONLY=false RELOAD_KEY= REGISTRY_CONTROLLER_URL=http://registryctl:8080 REGISTRY_CREDENTIAL_USERNAME=harbor_registry_user CSRF_KEY=jPcpPYw2HU4V0r2LG2kyHWWSIwRE4Ln8 ROBOT_SCANNER_NAME_PREFIX=2GA78XLs PERMITTED_REGISTRY_TYPES_FOR_PROXY_CACHE=docker-hub,harbor,azure-acr,ali-acr,aws-ecr,google-gcr,quay,docker-registry,github-ghcr,jfrog-artifactory HTTP_PROXY= HTTPS_PROXY= NO_PROXY=localhost,postgresql,portal,trivy-adapter,jobservice,127.0.0.1,.local,.internal,core,registryctl,redis,registry,nginx,db,log,exporter PORT=8080 METRIC_ENABLE=true METRIC_PATH=/metrics METRIC_PORT=9090 METRIC_NAMESPACE=harbor METRIC_SUBSYSTEM=core QUOTA_UPDATE_PROVIDER=db ``` 4. 建立 Harbor container ``` # 定義 Harbor 對外的 url HARBOR_FQDN="pharbor.example.com" # 定義 Harbor 資料永存目錄區 HARBOR_PV="/data" [ ! -d ${HARBOR_PV} ] && sudo mkdir -p ${HARBOR_PV} sudo chown 10000:10000 ${HARBOR_PV} # Run Harbor Container sudo podman run --name=core --detach \ --network=harbor \ --cap-add=setuid \ --cap-add=setgid \ --cap-drop=all \ --env-file=/etc/harbor/coreenv \ --env=EXT_ENDPOINT=https://${HARBOR_FQDN} \ --secret=harbor-secret,type=env,target=CORE_SECRET \ --secret=db-secret,type=env,target=POSTGRESQL_PASSWORD \ --secret=jobservice-secret,type=env,target=JOBSERVICE_SECRET \ --secret=registry-passwd,type=env,target=REGISTRY_CREDENTIAL_PASSWORD \ --secret=harbor-secretkey,type=mount,target=/etc/core/key \ --secret=harbor-key,type=mount,target=/etc/core/private_key.pem \ --volume=${HARBOR_PV}:/data:Z \ --volume=/etc/harbor/harbor.conf:/etc/core/app.conf:ro \ --volume=/etc/ssl/certs/ca-certificates.crt:/etc/core/certificates/root.crt:ro \ --volume=/usr/share/zoneinfo/Asia/Taipei:/etc/localtime:ro \ goharbor/harbor-core:${HARBOR_VERSION} ``` ### 3.7. 部署 jobservice 1. 編輯設定檔 ``` sudo nano /etc/harbor/jobservice.yml ``` 檔案內容如下 : ``` --- #Protocol used to serve protocol: "http" #Server listening port port: 8080 #Worker pool worker_pool: #Worker concurrency workers: 10 backend: "redis" #Additional config if use 'redis' backend redis_pool: #redis://[arbitrary_username:password@]ipaddress:port/database_index redis_url: redis://redis:6379/2?idle_timeout_seconds=30 namespace: "harbor_job_service_namespace" idle_timeout_second: 3600 #Loggers for the running job job_loggers: # The jobLoggers backend name, only support "STD_OUTPUT", "FILE" and/or "DB" - name: "STD_OUTPUT" level: "INFO" # INFO/DEBUG/WARNING/ERROR/FATAL - name: "FILE" level: "INFO" settings: # Customized settings of logger base_dir: "/var/log/jobs" sweeper: duration: 1 #days settings: # Customized settings of sweeper work_dir: "/var/log/jobs" #Loggers for the job service loggers: - name: "STD_OUTPUT" # Same with above level: "INFO" metric: enabled: true path: /metrics port: 9090 reaper: # the max time to wait for a task to finish, if unfinished after max_update_hours, the task will be mark as error, but the task will continue to run, default value is 24, max_update_hours: 24 # the max time for execution in running state without new task created max_dangling_hours: 168 # the max size of job log returned by API, default is 10M max_retrieve_size_mb: 10 ``` 2. 編輯環境變數 ``` sudo nano /etc/harbor/jobservice.env ``` 檔案內容 : ``` REGISTRY_URL=http://registry:5000 CORE_URL=http://core:8080 REGISTRY_CONTROLLER_URL=http://registryctl:8080 JOBSERVICE_WEBHOOK_JOB_MAX_RETRY=3 JOBSERVICE_WEBHOOK_JOB_HTTP_CLIENT_TIMEOUT=3 LOG_LEVEL=info HTTP_PROXY= HTTPS_PROXY= NO_PROXY=localhost,postgresql,portal,trivy-adapter,jobservice,127.0.0.1,.local,.internal,core,registryctl,redis,registry,nginx,db,log,exporter REGISTRY_CREDENTIAL_USERNAME=harbor_registry_user MAX_JOB_DURATION_SECONDS=86400 METRIC_NAMESPACE=harbor METRIC_SUBSYSTEM=jobservice ``` 3. 建立 jobservice container ``` # 定義 Jobservice 資料永存目錄區 JOBSVC_PV="/data/job_logs" [ ! -d ${JOBSVC_PV} ] && sudo mkdir -p ${JOBSVC_PV} sudo chown 10000:10000 ${JOBSVC_PV} sudo podman run --name=jobservice --detach \ --network=harbor \ --cap-add=setuid \ --cap-add=setgid \ --cap-add=chown \ --cap-drop=all \ --env-file=/etc/harbor/jobservice.env \ --secret=harbor-secret,type=env,target=CORE_SECRET \ --secret=jobservice-secret,type=env,target=JOBSERVICE_SECRET \ --secret=registry-passwd,type=env,target=REGISTRY_CREDENTIAL_PASSWORD \ --volume=/etc/harbor/jobservice.yml:/etc/jobservice/config.yml \ --volume=${JOBSVC_PV}:/var/log/jobs:z \ --volume=/etc/ssl/certs/ca-certificates.crt:/harbor_cust_cert/root.crt:ro \ goharbor/harbor-jobservice:${HARBOR_VERSION} ``` ### 3.8. 部署 exporter 1. 編輯環境變數檔 ``` sudo nano /etc/harbor/exporter.env ``` 檔案內容如下 : ``` LOG_LEVEL=info HARBOR_EXPORTER_PORT=8080 HARBOR_EXPORTER_METRICS_PATH=/metrics HARBOR_EXPORTER_METRICS_ENABLED=true HARBOR_EXPORTER_MAX_REQUESTS=30 HARBOR_EXPORTER_CACHE_TIME=23 HARBOR_EXPORTER_CACHE_CLEAN_INTERVAL=14400 HARBOR_METRIC_NAMESPACE=harbor HARBOR_METRIC_SUBSYSTEM=exporter HARBOR_SERVICE_HOST=core HARBOR_REDIS_URL=redis://redis:6379/2?idle_timeout_seconds=30 HARBOR_REDIS_NAMESPACE=harbor_job_service_namespace HARBOR_REDIS_TIMEOUT=3600 HARBOR_SERVICE_PORT=8080 HARBOR_SERVICE_SCHEME=http HARBOR_DATABASE_HOST=postgresql HARBOR_DATABASE_PORT=5432 HARBOR_DATABASE_USERNAME=postgres HARBOR_DATABASE_DBNAME=registry HARBOR_DATABASE_SSLMODE=disable HARBOR_DATABASE_MAX_IDLE_CONNS=100 HARBOR_DATABASE_MAX_OPEN_CONNS=900 HARBOR_DATABASE_CONN_MAX_LIFETIME=5m HARBOR_DATABASE_CONN_MAX_IDLE_TIME=0 ``` 2. 建立 exporter container ``` sudo podman run -d \ --name exporter --network harbor \ --env-file /etc/harbor/exporter.env \ --secret=db-secret,type=env,target=HARBOR_DATABASE_PASSWORD \ --volume=/etc/ssl/certs/ca-certificates.crt:/harbor_cust_cert/root.crt:ro \ goharbor/harbor-exporter:${HARBOR_VERSION} ``` ### 3.9. 部署 Nginx 1. 產生自簽憑證 ``` git clone https://github.com/braveantony/mkcert.git ./mkcert/certctl sudo mkdir -p /data/secret/cert sudo chown -R 10000:10000 /data/secret/ sudo cp mkcert/example.com/example.com.crt /data/secret/cert/server.crt sudo cp mkcert/example.com/example.com.key /data/secret/cert/server.key ``` 2. 建立設定檔 ``` sudo nano /etc/harbor/nginx.conf ``` 檔案內容 : ``` worker_processes auto; pid /tmp/nginx.pid; events { worker_connections 3096; use epoll; multi_accept on; } 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; include /etc/nginx/conf.d/*.upstream.conf; # this is necessary for us to be able to disable request buffering in all cases proxy_http_version 1.1; upstream core { server core:8080; } upstream portal { server portal:8080; } log_format timed_combined '$remote_addr - ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' '$request_time $upstream_response_time $pipe'; access_log /dev/stdout timed_combined; map $http_x_forwarded_proto $x_forwarded_proto { default $http_x_forwarded_proto; "" $scheme; } include /etc/nginx/conf.d/*.server.conf; server { listen 8443 ssl; # server_name harbordomain.com; server_tokens off; # SSL ssl_certificate /etc/cert/server.crt; ssl_certificate_key /etc/cert/server.key; # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html ssl_protocols TLSv1.2 TLSv1.3; 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; # disable any limits to avoid HTTP 413 for large image uploads client_max_body_size 0; # 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'"; # customized location config file can place to /etc/nginx dir with prefix harbor.https. and suffix .conf include /etc/nginx/conf.d/harbor.https.*.conf; location / { proxy_pass http://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; proxy_set_header X-Forwarded-Proto $x_forwarded_proto; proxy_cookie_path / "/; HttpOnly; Secure"; proxy_buffering off; proxy_request_buffering off; } location /c/ { proxy_pass http://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; proxy_set_header X-Forwarded-Proto $x_forwarded_proto; proxy_cookie_path / "/; Secure"; proxy_buffering off; proxy_request_buffering off; } location /api/ { proxy_pass http://core/api/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $x_forwarded_proto; proxy_cookie_path / "/; Secure"; proxy_buffering off; proxy_request_buffering off; } location /v1/ { return 404; } location /v2/ { proxy_pass http://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; proxy_set_header X-Forwarded-Proto $x_forwarded_proto; proxy_buffering off; proxy_request_buffering off; proxy_send_timeout 900; proxy_read_timeout 900; } location /service/ { proxy_pass http://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; proxy_set_header X-Forwarded-Proto $x_forwarded_proto; proxy_cookie_path / "/; Secure"; proxy_buffering off; proxy_request_buffering off; } location /service/notifications { return 404; } } server { listen 8080; #server_name harbordomain.com; return 308 https://$host:443$request_uri; } upstream core_metrics { server core:9090; } upstream js_metrics { server jobservice:9090; } upstream registry_metrics { server registry:9090; } upstream harbor_exporter { server exporter:8080; } server { listen 9090; location = /metrics { if ($arg_comp = core) { proxy_pass http://core_metrics; } if ($arg_comp = jobservice) { proxy_pass http://js_metrics; } if ($arg_comp = registry) { proxy_pass http://registry_metrics; } proxy_pass http://harbor_exporter; } } } ``` 3. 建立 nginx container ``` sudo podman run --name=proxy \ --detach --network=harbor \ --cap-add=setuid --cap-add=setgid --cap-add=chown \ --cap-add=net_bind_service --cap-drop=all \ --volume=/etc/harbor/jobservice.yml:/etc/jobservice/config.yml \ --volume=/etc/harbor/nginx.conf:/etc/nginx/nginx.conf:ro \ --volume=/data/secret/cert:/etc/cert:ro \ --publish=80:8080/tcp \ --publish=443:8443/tcp \ goharbor/nginx-photon:${HARBOR_VERSION} ``` ### 3.10. 部署 trivy 1. 編輯環境變數檔 ``` sudo nano /etc/harbor/trivy.env ``` 檔案內容如下 : ``` REGISTRY_URL=http://registry:5000 SCANNER_LOG_LEVEL=info SCANNER_REDIS_URL=redis://redis:6379/5?idle_timeout_seconds=30 SCANNER_STORE_REDIS_URL=redis://redis:6379/5?idle_timeout_seconds=30 SCANNER_STORE_REDIS_NAMESPACE=harbor.scanner.trivy:store SCANNER_STORE_REDIS_NAMESPACE=harbor.scanner.trivy:store SCANNER_JOB_QUEUE_REDIS_URL=redis://redis:6379/5?idle_timeout_seconds=30 SCANNER_JOB_QUEUE_REDIS_NAMESPACE=harbor.scanner.trivy:job-queue SCANNER_TRIVY_CACHE_DIR=/home/scanner/.cache/trivy SCANNER_TRIVY_REPORTS_DIR=/home/scanner/.cache/reports SCANNER_TRIVY_VULN_TYPE=os,library SCANNER_TRIVY_SEVERITY=UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL SCANNER_TRIVY_IGNORE_UNFIXED=False SCANNER_TRIVY_SKIP_UPDATE=False SCANNER_TRIVY_SKIP_JAVA_DB_UPDATE=False SCANNER_TRIVY_OFFLINE_SCAN=True SCANNER_TRIVY_SECURITY_CHECKS=vuln SCANNER_TRIVY_GITHUB_TOKEN= SCANNER_TRIVY_INSECURE=False SCANNER_TRIVY_TIMEOUT=5m0s ``` 2. 建立 trivy container ``` sudo podman run --name=trivy --detach \ --network=harbor \ --cap-drop=all \ --env-file=/etc/harbor/trivy.env \ goharbor/trivy-adapter-photon:${HARBOR_VERSION} ``` ### 3.11. 檢查所有服務是否異常 1. 執行以下命令檢查 container 運作狀態 ``` sudo podman ps -a ``` 正確執行結果 : ``` CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2fbbebdfa7b7 localhost/goharbor/redis-photon:v2.13.1 redis-server /etc... 2 hours ago Up 37 minutes (healthy) redis 1ee927703c43 localhost/goharbor/harbor-db:v2.13.1 2 hours ago Up 2 hours (healthy) postgresql 6609abf6abd3 localhost/goharbor/registry-photon:v2.13.1 2 hours ago Up 2 hours (healthy) registry 0ac760f6bd97 localhost/goharbor/harbor-portal:v2.13.1 nginx -g daemon o... 2 hours ago Up 2 hours (healthy) portal d5b932627e1c localhost/goharbor/harbor-registryctl:v2.13.1 2 hours ago Up 2 hours (healthy) registryctl 4ae9fe3acffd localhost/goharbor/harbor-core:v2.13.1 50 minutes ago Up 36 minutes (healthy) core efaa7d97283a localhost/goharbor/harbor-jobservice:v2.13.1 20 minutes ago Up 20 minutes (healthy) jobservice f5d6b65fbcf8 localhost/goharbor/harbor-exporter:v2.13.1 9 minutes ago Up 9 minutes exporter f2d2ce9bb84e localhost/goharbor/nginx-photon:v2.13.1 nginx -g daemon o... 6 minutes ago Up 6 minutes (healthy) 0.0.0.0:80->8080/tcp, 0.0.0.0:443->8443/tcp proxy 5c4f83c677a2 localhost/goharbor/trivy-adapter-photon:v2.13.1 5 seconds ago Up 6 seconds (healthy) trivy ``` ### 3.12. 連線 Harbor UI 打開瀏覽器,連線至 ``` https://$HARBOR_FQDN ``` ![image](https://hackmd.io/_uploads/SkJ22UQDel.png) 輸入身分資訊 : - 帳號 : `admin` - 密碼 : `Harbor12345` ![image](https://hackmd.io/_uploads/SkFEaLmvxg.png) ### 3.13. 設定 Harbor 開機自動啟動 :::info 目前只適用 systemd 的 OS,如果是 OpenRC 就不適用 ::: 1. 產生 Systemd Unit 並控制順序 ``` sudo podman generate systemd --name redis --restart-policy=always --after network-online.target --files sudo podman generate systemd --name postgresql --restart-policy=always --after container-redis.service --files sudo podman generate systemd --name registry --restart-policy=always --after container-postgresql.service --files sudo podman generate systemd --name portal --restart-policy=always --after container-registry.service --files sudo podman generate systemd --name registryctl --restart-policy=always --after container-portal.service --files sudo podman generate systemd --name core --restart-policy=always --after container-registryctl.service --files sudo podman generate systemd --name jobservice --restart-policy=always --after container-core.service --files sudo podman generate systemd --name exporter --restart-policy=always --after container-jobservice.service --files sudo podman generate systemd --name proxy --restart-policy=always --after container-exporter.service --files sudo podman generate systemd --name trivy --restart-policy=always --after container-proxy.service --files ``` 2. 將這些 `.service` 檔案複製到 systemd 系統目錄 ``` sudo cp container-*.service /etc/systemd/system/ ``` 3. 重新載入 daemon ``` sudo systemctl daemon-reload ``` 4. 設定服務開機自動啟動 ``` sudo systemctl enable container-redis.service container-postgresql.service container-registry.service container-portal.service container-registryctl.service container-core.service container-jobservice.service container-exporter.service container-proxy.service container-trivy.service ``` 5. 重開機測試 ``` sudo reboot ``` 6. ssh 連線進 podman host 主機 7. 確認 harbor 各元件的 containers 運作狀態 ``` sudo podman ps -a ``` 執行結果 : ``` CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2fbbebdfa7b7 localhost/goharbor/redis-photon:v2.13.1 redis-server /etc... 3 hours ago Up 3 minutes (healthy) redis 1ee927703c43 localhost/goharbor/harbor-db:v2.13.1 3 hours ago Up 3 minutes (healthy) postgresql 6609abf6abd3 localhost/goharbor/registry-photon:v2.13.1 3 hours ago Up 3 minutes (healthy) registry 0ac760f6bd97 localhost/goharbor/harbor-portal:v2.13.1 nginx -g daemon o... 3 hours ago Up 3 minutes (healthy) portal d5b932627e1c localhost/goharbor/harbor-registryctl:v2.13.1 3 hours ago Up 3 minutes (healthy) registryctl 4ae9fe3acffd localhost/goharbor/harbor-core:v2.13.1 2 hours ago Up 3 minutes (healthy) core efaa7d97283a localhost/goharbor/harbor-jobservice:v2.13.1 About an hour ago Up 3 minutes (healthy) jobservice f5d6b65fbcf8 localhost/goharbor/harbor-exporter:v2.13.1 About an hour ago Up 3 minutes exporter f2d2ce9bb84e localhost/goharbor/nginx-photon:v2.13.1 nginx -g daemon o... About an hour ago Up 3 minutes (healthy) 0.0.0.0:80->8080/tcp, 0.0.0.0:443->8443/tcp proxy 5c4f83c677a2 localhost/goharbor/trivy-adapter-photon:v2.13.1 About an hour ago Up 3 minutes (healthy) trivy ``` --- ## 參考資料 - [Podman 安裝 harbor - zggzcgy blog](https://www.cnblogs.com/zggzcgy/p/18639254)