Trong quá trình phát triển, các kiến trúc truyền thống ngày càng bộc lộ những hạn chế, đòi hỏi các giải pháp như kiến trúc chủ động kép (active-active) và cụm máy chủ (clustering) phải được xem xét.
Việc phát triển trên đám mây thường gặp khó khăn do hạn chế truy cập Internet, gây cản trở cho việc tra cứu tài liệu và tải xuống các gói phần mềm. Trong bối cảnh này, một kho lưu trữ Docker (Docker Registry) là cần thiết để lưu trữ các image tùy chỉnh, cho phép truy cập dễ dàng từ nhiều máy chủ. Do đó, việc thiết lập một máy chủ Docker riêng (Docker private registry) trở nên cấp thiết.
Có nhiều phương pháp để thiết lập máy chủ Docker riêng, bao gồm Registry, Nexus và Harbor. Bài viết này sẽ hướng dẫn chi tiết từng phương pháp.
1. Sử dụng Registry
Registry là kho lưu trữ image chính thức do Docker cung cấp. Tuy nhiên, nó chỉ hỗ trợ thao tác thông qua API và định dạng JSON, không thân thiện với người dùng, nên ít được sử dụng trong thực tế, chủ yếu dùng để tham khảo.
1.1. Khởi chạy Registry
Để khởi chạy một phiên bản Registry, sử dụng lệnh sau:
docker run -itd -p 5000:5000 --name my-registry registry:2
Sau khi khởi chạy, bạn có thể truy cập http://<IP_máy_chủ>:5000/v2/_catalog để xem giao diện quản lý kho lưu trữ. Nếu thành công, bạn sẽ thấy một trang trống hoặc danh sách các image đã có.
1.2. Cấu hình Docker để tin tưởng Registry
Để có thể đẩy (push) và kéo (pull) image từ Registry riêng, bạn cần cấu hình tệp /etc/docker/daemon.json trên máy chủ Docker của mình. Thêm hoặc cập nhật tệp này với nội dung sau:
{
"registry-mirrors": ["<địa_chỉ_mirror_tăng_tốc>"],
"insecure-registries": ["<IP_máy_chủ_Registry>:5000"]
}
Sau khi chỉnh sửa tệp cấu hình, bạn cần khởi động lại dịch vụ Docker:
systemctl daemon-reload
systemctl restart docker
1.3. Đặt tên lại và đẩy Image
Trước khi đẩy image, bạn cần đổi tên (tag) image theo định dạng <địa_chỉ_Registry>/<tên_image>:
# Đổi tên image 'my-app' thành '192.168.1.100:5000/my-app'
docker tag my-app 192.168.1.100:5000/my-app
# Đẩy image lên Registry riêng
docker push 192.168.1.100:5000/my-app
Sau khi đẩy, bạn có thể truy cập lại http://<IP_máy_chủ>:5000/v2/_catalog để xác nhận image đã được tải lên.
1.4. Kéo Image
Để kéo image từ Registry riêng, sử dụng lệnh:
docker pull 192.168.1.100:5000/my-app
Lưu ý: Docker không tự động tìm kiếm trên các registry riêng đã cấu hình như cách Maven tìm kiếm artifact. Bạn cần chỉ định rõ địa chỉ registry khi kéo hoặc đẩy image. Một số hệ điều hành dựa trên Red Hat có tùy chọn --add-registry và --block-registry để ghi đè hành vi này, nhưng các hệ điều hành khác thì không có.
2. Sử dụng Nexus Repository Manager
Nexus là một công cụ quản lý kho lưu trữ phổ biến, có thể dùng để quản lý không chỉ Docker image mà còn cả các loại artifact khác như Maven, npm, PyPI, v.v. Việc sử dụng Nexus giúp tập trung hóa quản lý tài nguyên.
2.1. Cài đặt Nexus
Bạn có thể cài đặt Nexus bằng Docker:
docker run -d -p 8081:8081 -p 8082:8082 --name nexus-repo sonatype/nexus3
Tên đăng nhập mặc định là admin. Mật khẩu ban đầu có thể xem bằng cách truy cập vào container:
docker exec -it nexus-repo bash
tail -n 20 /nexus-data/admin.password
2.2. Tạo kho lưu trữ Docker
Truy cập giao diện Nexus qua http://<IP_máy_chủ>:8081. Sau đó, điều hướng đến phần quản lý kho lưu trữ và tạo một kho lưu trữ mới thuộc loại "docker (hosted)". Cấu hình các thông số cần thiết, ví dụ: tên kho lưu trữ là docker-internal.
2.3. Cấu hình Docker và đẩy Image
Cấu hình /etc/docker/daemon.json tương tự như với Registry, nhưng thêm địa chỉ của Nexus vào danh sách insecure-registries:
{
"registry-mirrors": ["<địa_chỉ_mirror_tăng_tốc>"],
"insecure-registries": ["<IP_máy_chủ_Nexus>:8082", "<IP_máy_chủ_Registry>:5000"]
}
Khởi động lại dịch vụ Docker.
Trước khi đẩy image, bạn cần đăng nhập vào Nexus:
# Đăng nhập vào Nexus
docker login -u admin -p <mật_khẩu_admin_nexus> <IP_máy_chủ_Nexus>:8082
# Đổi tên image
docker tag my-app <IP_máy_chủ_Nexus>:8082/my-app
# Đẩy image
docker push <IP_máy_chủ_Nexus>:8082/my-app
2.4. Kéo Image
Việc kéo image cũng tương tự như với Registry, chỉ cần chỉ định rõ địa chỉ Nexus.
Lưu ý: Các ví dụ trên chỉ mang tính minh họa. Trong môi trường thực tế, cần đảm bảo dữ liệu được lưu trữ bền vững (persistent storage) cho các container Nexus và Registry để tránh mất dữ liệu khi container bị dừng hoặc xóa.
3. Sử dụng Harbor
Harbor là một dự án mã nguồn mở đáng tin cậy, cung cấp kho lưu trữ đám mây gốc (cloud-native registry) để lưu trữ, ký và quét nội dung. Harbor bổ sung các tính năng cần thiết như bảo mật, quản lý danh tính và quản trị, giúp kho lưu trữ hoạt động hiệu quả hơn.
3.1. Tải và Giải nén Harbor
Tải gói cài đặt Harbor từ trang GitHub chính thức (chọn phiên bản phù hợp, ví dụ harbor-offline-installer-v2.9.1.tgz). Sau đó, giải nén gói cài đặt:
tar -zxvf harbor-offline-installer-v2.9.1.tgz
3.2. Cấu hình và Cài đặt Harbor
Di chuyển vào thư mục cài đặt và sao chép tệp cấu hình mẫu:
mv harbor harbor-install
cd harbor-install
cp harbor.yml.tmpl harbor.yml
Chỉnh sửa tệp harbor.yml với các thông số phù hợp, ví dụ:
hostname: <IP_máy_chủ>
http:
port: 8080
# Cấu hình HTTPS nếu cần, ở đây chúng ta bỏ qua
# https:
# port: 443
# certificate: /path/to/your/certificate.pem
# private_key: /path/to/your/private.key
harbor_admin_password: YourHarborAdminPassword
database:
password: YourDatabasePassword
max_idle_conns: 100
max_open_conns: 900
conn_max_lifetime: 5m
conn_max_idle_time: 0
data_volume: /data/harbor # Đường dẫn lưu trữ dữ liệu
# Cấu hình Trivy (công cụ quét lỗ hổng bảo mật)
trivy:
ignore_unfixed: false
skip_update: false
offline_scan: false
security_check: vuln
insecure: false
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 # seconds
log:
level: info
local:
rotate_count: 50
rotate_size: 200M
location: /var/log/harbor # Đường dẫn lưu trữ log
_version: 2.9.0
proxy:
http_proxy:
https_proxy:
no_proxy:
components:
- core
- jobservice
- trivy
upload_purging:
enabled: true
age: 168h # Xóa dữ liệu cũ sau 168 giờ
interval: 24h # Kiểm tra định kỳ 24 giờ
dryrun: false
cache:
enabled: false
expire_hours: 24
Sau khi cấu hình, chạy lệnh cài đặt:
./install.sh
Truy cập Harbor qua http://<IP_máy_chủ>:8080 (sử dụng cổng và mật khẩu đã cấu hình).
3.3. Tạo Project và Đẩy Image
Trước khi đẩy image, bạn cần tạo một "Project" mới trong giao diện Harbor để tổ chức image.
Cấu hình /etc/docker/daemon.json tương tự các phương pháp trước, đảm bảo địa chỉ Harbor được thêm vào insecure-registries.
systemctl daemon-reload
systemctl restart docker
Đăng nhập và đẩy image:
# Đăng nhập vào Harbor
docker login -u admin -p YourHarborAdminPassword <IP_máy_chủ_Harbor>:8080
# Đổi tên image theo định dạng: <IP_máy_chủ>:<cổng>/<tên_project>/<tên_image>
docker tag my-app <IP_máy_chủ_Harbor>:8080/my-project/my-app
# Đẩy image
docker push <IP_máy_chủ_Harbor>:8080/my-project/my-app
Lưu ý rằng đường dẫn image bây giờ bao gồm tên project đã tạo.
3.4. Kéo Image
Kéo image với cú pháp tương tự:
docker pull <IP_máy_chủ_Harbor>:8080/my-project/my-app
Bài viết đã giới thiệu ba phương pháp chính để thiết lập kho lưu trữ Docker riêng. Bạn có thể lựa chọn phương pháp phù hợp nhất với nhu cầu và điều kiện của dự án.