DevOps Docker Kubernetes

9 bước cài đặt Harbor registry

congdonglinux-harbor-logo

Giới Thiệu

Harbor Registry là một giải pháp quản lý Docker Registry mạnh mẽ và linh hoạt, được cung cấp bởi trang web https://goharbor.io/. Với Harbor Registry, bạn có thể dễ dàng tạo và quản lý các image Docker của bạn một cách hiệu quả và an toàn. Điều này giúp cho việc phát triển ứng dụng và triển khai chúng trở nên thuận lợi hơn, đồng thời cung cấp môi trường đáng tin cậy để lưu trữ và chia sẻ các image Docker.

Với Harbor, bạn có thể tạo ra các kho lưu trữ riêng tư hoặc công khai để lưu trữ các image Docker của bạn. Khả năng quản lý quyền truy cập và kiểm soát bảo mật giúp bạn đảm bảo rằng chỉ những người được ủy quyền mới có thể truy cập và sử dụng các image quan trọng. Ngoài ra, Harbor cung cấp khả năng sao lưu và khôi phục dữ liệu, giúp bảo vệ dữ liệu quan trọng của bạn khỏi mất mát.

Sự tích hợp dễ dàng với các công cụ và hệ thống khác cũng là một điểm đáng chú ý của Harbor. Bạn có thể tích hợp Harbor vào quy trình triển khai liên tục (CI/CD) của mình để đảm bảo rằng các image Docker luôn được cập nhật và sẵn sàng cho quá trình triển khai mới nhất.

Với giao diện người dùng thân thiện, Harbor cung cấp cho bạn khả năng theo dõi và quản lý các image Docker một cách dễ dàng, từ việc tìm kiếm đến theo dõi lịch sử thay đổi. Tất cả những điều này cùng nhau tạo nên một giải pháp mạnh mẽ để quản lý Docker Registry và tối ưu hóa quá trình phát triển và triển khai ứng dụng của bạn.

congdonglinux harbor 5

Cài đặt Harbor

Bước 1: Yêu cầu

Yêu cầu về Phần cứng

Resource
Minimum
Recommended
CPU
2 CPU
4 CPU
Mem
4 GB
8 GB
Disk
40 GB
160 GB

Yêu cầu về Phần mềm

Software
Version
Description
Docker Engine
Version 17.06.0-ce+ or higher
For installation instructions, see Docker Engine documentation
Docker Compose
docker-compose (v1.18.0+) or docker compose v2 (docker-compose-plugin)
For installation instructions, see Docker Compose documentation
OpenSSL
Latest is preferred
Used to generate certificate and keys for Harbor

Yêu cầu về Network ports

Harbor yêu cầu các port sau được mở trên máy chủ.
Port
Protocol
Description
443
HTTPS
Harbor portal and core API accept HTTPS requests on this port. You can change this port in the configuration file.
4443
HTTPS
Connections to the Docker Content Trust service for Harbor. Only required if Notary is enabled. You can change this port in the configuration file.
80
HTTP
Harbor portal and core API accept HTTP requests on this port. You can change this port in the configuration file.

Bước 2: Download bộ cài đặt Harbor

Truy cập đến trang sau để tải về bản mới nhất của harbor. Links:  Harbor releases page.
Trong bài viết này, tôi sử dụng phiên bản Harbor là v2.8.3
mkdir -p /app/harbor.v2.8.3/data  /app/harbor.v2.8.3/source_harbor
cd /app/harbor.v2.8.3/source_harbor
wget https://github.com/goharbor/harbor/releases/download/v2.8.3/harbor-offline-installer-v2.8.3.tgz
tar xzvf harbor-offline-installer-v2.8.3.tgz
[root@docker-image source_harbor]# cd /app/harbor.v2.8.3/source_harbor
[root@docker-image source_harbor]# tar xzvf harbor-offline-installer-v2.8.3.tgz
harbor/harbor.v2.8.3.tar.gz
harbor/prepare
harbor/LICENSE
harbor/install.sh
harbor/common.sh
harbor/harbor.yml.tmpl

Bước 3: Cấu hình file Harbor YML

cp harbor.yml.tmpl harbor.yml
Điều chỉnh các thông số như sau: http, https, hostname,  harbor_admin_password, data_volume
Tại mục http này, điều chỉnh lại port cần listening để push images. Mặc định là port 80, ở đây tôi chuyển sang dùng port 5000.
http:
# port for http, default is 80. If https enabled, this port will redirect to https port
port: 5000
Cấu hình hostname tại: 
hostname: registry.example.com
Đặt password cho account admin của Harbor tại mục:  harbor_admin_password.
Ví dụ:
harbor_admin_password: 1234567890
Tại mục https, trong bài viết này tôi không sử dụng https, nên sẽ dùng dấu thăng ( #) để rào lại các cấu hình không dùng tới.
#https:
# https port for harbor, default is 443
#port: 8443
# The path of cert and key files for nginx
#certificate: /app/harbor/cert/registry.test.com.cert
#private_key: /app/harbor/cert/registry.test.com.key
Tiếp theo là mục data volume, đây là nơi lưu trữ dữ liệu của Harbor. Cấu hình đường dẫn cho phù hợp.
Ví dụ:
data_volume: /app/harbor/data
Sau khi cấu hình hoàn tất ta sẽ được 1 file template như sau:
# Configuration file of Harbor
# The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
hostname: registry.example.com
# http related config
http:
# port for http, default is 80. If https enabled, this port will redirect to https port
port: 5000
# https related config
#https:
# https port for harbor, default is 443
# port: 443
# The path of cert and key files for nginx
# certificate: /your/certificate/path
# private_key: /your/private/key/path
# # Uncomment following will enable tls communication between all harbor components
# 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
# Uncomment external_url if you want to enable external proxy
# And when it enabled the hostname will no longer used
# external_url: https://reg.mydomain.com:8433
# The initial password of Harbor admin
# It only works in first time to install harbor
# Remember Change the admin password from UI after launching Harbor.
harbor_admin_password: 1234567890
# Harbor DB configuration
database:
# The password for the root user of Harbor DB. Change this before any production use.
password: root123
# The maximum number of connections in the idle connection pool. If it <=0, no idle connections are retained.
max_idle_conns: 100
# The maximum number of open connections to the database. If it <= 0, then there is no limit on the number of open connections.
# Note: the default number of connections is 1024 for postgres of harbor.
max_open_conns: 900
# The maximum amount of time a connection may be reused. Expired connections may be closed lazily before reuse. If it <= 0, connections are not closed due to a connection's age.
# The value is a duration string. A duration string is a possibly signed sequence of decimal numbers, each with optional fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
conn_max_lifetime: 5m
# The maximum amount of time a connection may be idle. Expired connections may be closed lazily before reuse. If it <= 0, connections are not closed due to a connection's idle time.
# The value is a duration string. A duration string is a possibly signed sequence of decimal numbers, each with optional fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
conn_max_idle_time: 0
# The default data volume
data_volume: /app/harbor.v2.8.3/data/
# Harbor Storage settings by default is using /data dir on local filesystem
# Uncomment storage_service setting If you want to using external storage
# storage_service:
# # ca_bundle is the path to the custom root ca certificate, which will be injected into the truststore
# # of registry's containers. This is usually needed when the user hosts a internal storage with self signed certificate.
# ca_bundle:
# # storage backend, default is filesystem, options include filesystem, azure, gcs, s3, swift and oss
# # for more info about this configuration please refer https://docs.docker.com/registry/configuration/
# filesystem:
# maxthreads: 100
# # set disable to true when you want to disable registry redirect
# redirect:
# disable: false
# Trivy configuration
#
# Trivy DB contains vulnerability information from NVD, Red Hat, and many other upstream vulnerability databases.
# It is downloaded by Trivy from the GitHub release page https://github.com/aquasecurity/trivy-db/releases and cached
# in the local file system. In addition, the database contains the update timestamp so Trivy can detect whether it
# should download a newer version from the Internet or use the cached one. Currently, the database is updated every
# 12 hours and published as a new release to GitHub.
trivy:
# ignoreUnfixed The flag to display only fixed vulnerabilities
ignore_unfixed: false
# skipUpdate The flag to enable or disable Trivy DB downloads from GitHub
#
# You might want to enable this flag in test or CI/CD environments to avoid GitHub rate limiting issues.
# If the flag is enabled you have to download the `trivy-offline.tar.gz` archive manually, extract `trivy.db` and
# `metadata.json` files and mount them in the `/home/scanner/.cache/trivy/db` path.
skip_update: false
#
# The offline_scan option prevents Trivy from sending API requests to identify dependencies.
# Scanning JAR files and pom.xml may require Internet access for better detection, but this option tries to avoid it.
# For example, the offline mode will not try to resolve transitive dependencies in pom.xml when the dependency doesn't
# exist in the local repositories. It means a number of detected vulnerabilities might be fewer in offline mode.
# It would work if all the dependencies are in local.
# This option doesn't affect DB download. You need to specify "skip-update" as well as "offline-scan" in an air-gapped environment.
offline_scan: false
#
# Comma-separated list of what security issues to detect. Possible values are `vuln`, `config` and `secret`. Defaults to `vuln`.
security_check: vuln
#
# insecure The flag to skip verifying registry certificate
insecure: false
# github_token The GitHub access token to download Trivy DB
#
# Anonymous downloads from GitHub are subject to the limit of 60 requests per hour. Normally such rate limit is enough
# for production operations. If, for any reason, it's not enough, you could increase the rate limit to 5000
# requests per hour by specifying the GitHub access token. For more details on GitHub rate limiting please consult
# https://developer.github.com/v3/#rate-limiting
#
# You can create a GitHub token by following the instructions in
# https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line
#
# github_token: xxx
jobservice:
# Maximum number of job workers in job service
max_job_workers: 10
# The jobLogger sweeper duration (ignored if `jobLogger` is `stdout`)
logger_sweeper_duration: 1 #days
notification:
# Maximum retry count for webhook job
webhook_job_max_retry: 3
# HTTP client timeout for webhook job
webhook_job_http_client_timeout: 3 #seconds
# Log configurations
log:
# options are debug, info, warning, error, fatal
level: info
# configs for logs in local storage
local:
# Log files are rotated log_rotate_count times before being removed. If count is 0, old versions are removed rather than rotated.
rotate_count: 50
# Log files are rotated only if they grow bigger than log_rotate_size bytes. If size is followed by k, the size is assumed to be in kilobytes.
# If the M is used, the size is in megabytes, and if G is used, the size is in gigabytes. So size 100, size 100k, size 100M and size 100G
# are all valid.
rotate_size: 200M
# The directory on your host that store log
location: /var/log/harbor
# Uncomment following lines to enable external syslog endpoint.
# external_endpoint:
# # protocol used to transmit log to external endpoint, options is tcp or udp
# protocol: tcp
# # The host of external endpoint
# host: localhost
# # Port of external endpoint
# port: 5140
#This attribute is for migrator to detect the version of the .cfg file, DO NOT MODIFY!
_version: 2.8.0
# Uncomment external_database if using external database.
# 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
# notary_signer:
# host: notary_signer_db_host
# port: notary_signer_db_port
# db_name: notary_signer_db_name
# username: notary_signer_db_username
# password: notary_signer_db_password
# ssl_mode: disable
# notary_server:
# host: notary_server_db_host
# port: notary_server_db_port
# db_name: notary_server_db_name
# username: notary_server_db_username
# password: notary_server_db_password
# ssl_mode: disable
# Uncomment external_redis if using external Redis server
# external_redis:
# # support redis, redis+sentinel
# # host for redis: <host_redis>:<port_redis>
# # host for redis+sentinel:
# # <host_sentinel1>:<port_sentinel1>,<host_sentinel2>:<port_sentinel2>,<host_sentinel3>:<port_sentinel3>
# host: redis:6379
# password:
# # Redis AUTH command was extended in Redis 6, it is possible to use it in the two-arguments AUTH <username> <password> form.
# # username:
# # sentinel_master_set must be set to support redis+sentinel
# #sentinel_master_set:
# # db_index 0 is for core, it's unchangeable
# registry_db_index: 1
# jobservice_db_index: 2
# trivy_db_index: 5
# idle_timeout_seconds: 30
# Uncomment uaa for trusting the certificate of uaa instance that is hosted via self-signed cert.
# uaa:
# ca_file: /path/to/ca
# Global proxy
# Config http proxy for components, e.g. http://my.proxy.com:3128
# Components doesn't need to connect to each others via http proxy.
# Remove component from `components` array if want disable proxy
# for it. If you want use proxy for replication, MUST enable proxy
# for core and jobservice, and set `http_proxy` and `https_proxy`.
# Add domain to the `no_proxy` field, when you want disable proxy
# for some special registry.
proxy:
http_proxy:
https_proxy:
no_proxy:
components:
- core
- jobservice
- trivy
# metric:
# enabled: false
# port: 9090
# path: /metrics
# Trace related config
# only can enable one trace provider(jaeger or otel) at the same time,
# and when using jaeger as provider, can only enable it with agent mode or collector mode.
# if using jaeger collector mode, uncomment endpoint and uncomment username, password if needed
# if using jaeger agetn mode uncomment agent_host and agent_port
# trace:
# enabled: true
# # set sample_rate to 1 if you wanna sampling 100% of trace data; set 0.5 if you wanna sampling 50% of trace data, and so forth
# sample_rate: 1
# # # namespace used to differenciate different harbor services
# # namespace:
# # # attributes is a key value dict contains user defined attributes used to initialize trace provider
# # attributes:
# # application: harbor
# # # jaeger should be 1.26 or newer.
# # jaeger:
# # endpoint: http://hostname:14268/api/traces
# # username:
# # password:
# # agent_host: hostname
# # # export trace data by jaeger.thrift in compact mode
# # agent_port: 6831
# # otel:
# # endpoint: hostname:4318
# # url_path: /v1/traces
# # compression: false
# # insecure: true
# # timeout: 10s
# Enable purge _upload directories
upload_purging:
enabled: true
# remove files in _upload directories which exist for a period of time, default is one week.
age: 168h
# the interval of the purge operations
interval: 24h
dryrun: false
# Cache layer configurations
# If this feature enabled, harbor will cache the resource
# `project/project_metadata/repository/artifact/manifest` in the redis
# which can especially help to improve the performance of high concurrent
# manifest pulling.
# NOTICE
# If you are deploying Harbor in HA mode, make sure that all the harbor
# instances have the same behaviour, all with caching enabled or disabled,
# otherwise it can lead to potential data inconsistency.
cache:
# not enabled by default
enabled: false
# keep cache for one day by default
expire_hours: 24

Bước 4: Chạy scripts cài đặt Harbor

Once you have configured harbor.yml copied from harbor.yml.tmpl and optionally set up a storage backend, you install and start Harbor by using the install.sh script. Note that it might take some time for the online installer to download all of the Harbor images from Docker hub.
You can install Harbor in different configurations:
  • Just Harbor, without Notary and Trivy
  • Harbor with Notary
  • Harbor with Trivy
  • Harbor with Notary and Trivy

Cài đặt với Trivy

Sử dụng lệnh sau để tiến hành cài đặt.
sudo ./install.sh --with-trivy
Trong đó:
–with-trivy: là một tiện ích dùng để quét bảo mật các images container.  Chúng ta sẽ tìm hiểu ở một bài viết sau.
[root@docker-image harbor]# ./install.sh --with-trivy
[Step 0]: checking if docker is installed ...
Note: docker version: 20.10.17
[Step 1]: checking docker-compose is installed ...
Note: Docker Compose version v2.6.0
[Step 2]: loading Harbor images ...
Loaded image: goharbor/registry-photon:v2.8.3
Loaded image: goharbor/notary-server-photon:v2.8.3
Loaded image: goharbor/notary-signer-photon:v2.8.3
Loaded image: goharbor/harbor-log:v2.8.3
Loaded image: goharbor/redis-photon:v2.8.3
Loaded image: goharbor/harbor-jobservice:v2.8.3
Loaded image: goharbor/prepare:v2.8.3
Loaded image: goharbor/harbor-core:v2.8.3
Loaded image: goharbor/harbor-registryctl:v2.8.3
Loaded image: goharbor/nginx-photon:v2.8.3
Loaded image: goharbor/trivy-adapter-photon:v2.8.3
Loaded image: goharbor/harbor-portal:v2.8.3
Loaded image: goharbor/harbor-db:v2.8.3
Loaded image: goharbor/harbor-exporter:v2.8.3
[Step 3]: preparing environment ...
[Step 4]: preparing harbor configs ...
prepare base dir is set to /app/harbor.v2.8.3/source_harbor/harbor
WARNING:root:WARNING: HTTP protocol is insecure. Harbor will deprecate http protocol in the future. Please make sure to upgrade to https
Clearing the configuration file: /config/portal/nginx.conf
Clearing the configuration file: /config/log/logrotate.conf
Clearing the configuration file: /config/log/rsyslog_docker.conf
Clearing the configuration file: /config/nginx/nginx.conf
Clearing the configuration file: /config/core/env
Clearing the configuration file: /config/core/app.conf
Clearing the configuration file: /config/registry/passwd
Clearing the configuration file: /config/registry/config.yml
Clearing the configuration file: /config/registryctl/env
Clearing the configuration file: /config/registryctl/config.yml
Clearing the configuration file: /config/db/env
Clearing the configuration file: /config/jobservice/env
Clearing the configuration file: /config/jobservice/config.yml
Generated configuration file: /config/portal/nginx.conf
Generated configuration file: /config/log/logrotate.conf
Generated configuration file: /config/log/rsyslog_docker.conf
Generated configuration file: /config/nginx/nginx.conf
Generated configuration file: /config/core/env
Generated configuration file: /config/core/app.conf
Generated configuration file: /config/registry/config.yml
Generated configuration file: /config/registryctl/env
Generated configuration file: /config/registryctl/config.yml
Generated configuration file: /config/db/env
Generated configuration file: /config/jobservice/env
Generated configuration file: /config/jobservice/config.yml
loaded secret from file: /data/secret/keys/secretkey
Generated configuration file: /config/trivy-adapter/env
Generated configuration file: /compose_location/docker-compose.yml
Clean up the input dir
Note: stopping existing Harbor instance ...
[Step 5]: starting Harbor ...
WARN[0000] Found orphan containers ([chartmuseum]) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up.
[+] Running 11/11
⠿ Network harbor_harbor Created 0.0s
⠿ Container harbor-log Started 0.5s
⠿ Container harbor-db Started 1.4s
⠿ Container registry Started 1.5s
⠿ Container harbor-portal Started 1.2s
⠿ Container registryctl Started 1.2s
⠿ Container redis Started 1.6s
⠿ Container harbor-core Started 2.2s
⠿ Container trivy-adapter Started 2.2s
⠿ Container nginx Started 3.0s
⠿ Container harbor-jobservice Started 2.9s
----Harbor has been installed and started successfully.----
Nếu quá trình cài đặt không gì có lỗi phát sinh, ta sẽ thấy một dòng thông báo như sau: “—-Harbor has been installed and started successfully.—-“
Kiểm tra trạng thái container docker của Harbor
docker ps
CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES
0c52d96efe96    goharbor/harbor-jobservice:v2.8.3  "/harbor/entrypoint.…" (healthy) harbor-jobservice
13f7f18812fd     goharbor/nginx-photon:v2.8.3 "nginx -g 'daemon of…" (healthy) 0.0.0.0:5000->8080/tcp nginx
14de72e35216  goharbor/trivy-adapter-photon:v2.8.3 "/home/scanner/entry…" (healthy) trivy-adapter
e2e203a6785c  goharbor/harbor-core:v2.8.3 "/harbor/entrypoint.…" (healthy) harbor-core
b08eebc89afd   goharbor/registry-photon:v2.8.3 "/home/harbor/entryp…" (healthy) registry
88bc8c543bb0  goharbor/harbor-portal:v2.8.3 "nginx -g 'daemon of…" (healthy) harbor-portal
471a74ed8d0a  goharbor/harbor-db:v2.8.3 "/docker-entrypoint.…" (healthy) harbor-db
1f57a286f80b    goharbor/redis-photon:v2.8.3 "redis-server /etc/r…" (healthy) redis
e2439bc788bc  goharbor/harbor-registryctl:v2.8.3 "/home/harbor/start.…" (healthy) registryctl
12ce9db7906c  goharbor/harbor-log:v2.8.3 "/bin/sh -c /usr/loc…" (healthy) 127.0.0.1:1514->10514/tcp harbor-log

Bước 5: Truy cập web

Add hosts:
vi /etc/hosts
192.168.0.100  registry.example.com
Đăng nhập với user/pass đã cấu hình trước đó. Ví dụ: admin /1234567890
congdonglinux harbor 1

Bước 6: Cấu hình insecure cho docker

MPORTANT: If your installation of Harbor uses HTTP rather than HTTPS, you must add the option –insecure-registry to your client’s Docker daemon. By default, the daemon file is located at /etc/docker/daemon.json
vi /etc/docker/daemon.json
For example, add the following to your daemon.json file:
{
"insecure-registries" : ["registry.example.com:5000", "0.0.0.0"]
}
Khởi động lại docker
systemctl restart docker
Kiểm tra rules kết nối từ client tới server harbor port 5000.
telnet 192.168.0.100  5000
root@gitlab-runner02:~# telnet 192.168.0.100  5000
Trying 192.168.0.100 ...
Connected to 192.168.0.100 .
Escape character is '^]'.
quit

Bước 7: Tạo Project & phân quyền user

congdonglinux harbor 2

Click vào project vừa tạo và chọn vào “Members”, thêm user vào project. 
ví dụ, ở đâu ta sẽ thêm user “gitlab-runner” vào project. 

congdonglinux harbor 3

Bước 8:  Push image containter tới Harbor registry

Đầu tiên ta cần login với user/pass tới harbor, ở đây có thể dùng account admin hoặc 1 account có quyền truy cập vào project. 
echo 1234567890 | docker login --username admin --password-stdin  registry.example.com
Tạo tag theo chuẩn domain của harbor.
Đây là bước bắt buộc để hệ thống hiểu nơi để đẩy image về registry nào, nếu không mặc định nó sẽ hiểu là registry của hub.docker.com
docker pull nginx:latest
docker tag nginx:latest  registry.example.com/dev/nginx:latest
docker push registry.example.com/dev/nginx:latest
Trong đó:
+ docker pull nginx:latest là lấy images từ registry public hub.docker.com
+ docker tag nginx:latest  registry.example.com/dev/nginx:latest là đặt lại tên images cho phù hợp với harbor nội bộ theo cú pháp:
<URL-Harbor>/<project>/<tên Images>. 
+ docker push registry.example.com/dev/nginx:latest là câu lệnh push images lên Harbor registry

Bước 9:  Pull image containter tới Harbor registry

Sau khi đã đẩy image lên server Harbor registry, để có thể kéo về các images. Tương tự ta làm như sau:

echo 1234567890 | docker login --username admin --password-stdin  registry.example.com
docker pull registry.example.com/dev/nginx:latest

Kết Bài

Như vậy, chúng ta vừa đi qua các bước để cài đặt Habor registry để quản lý images container. Chúc các bạn thành công !!

Đăng ký liền tay Nhận Ngay Bài Mới

Subscribe ngay

Cám ơn bạn đã đăng ký !

Lỗi đăng ký !

Add Comment

Click here to post a comment

Đăng ký liền tay
Nhận Ngay Bài Mới

Subscribe ngay

Cám ơn bạn đã đăng ký !

Lỗi đăng ký !