Bối cảnh: Khi Docker Hub trở thành nút thắt cổ chai
Thời điểm team mình mở rộng từ 5 lên hơn 30 microservices, việc đẩy image lên Docker Hub công cộng bắt đầu bộc lộ nhiều bất cập. Đầu tiên là chi phí tài khoản trả phí tăng nhanh. Kế đến, Docker Hub áp giới hạn 200 lượt pull trong 6 giờ với tài khoản ẩn danh hoặc miễn phí. Giới hạn này từng làm pipeline CI/CD của bên mình gãy giữa chừng vào đợt release cao điểm. Quan trọng hơn, chính sách bảo mật nội bộ nghiêm cấm việc đưa container image chứa mã nguồn doanh nghiệp lên cloud bên thứ ba.
Hạ tầng build lúc đó đang chuyển đổi dần từ các server CentOS 7 cũ sang CentOS Stream 9. Team cần một hệ thống private registry on-premise đặt ngay trong mạng LAN văn phòng. Hệ thống này phải có phân quyền người dùng (RBAC), quản lý hạn mức lưu trữ và quét mã độc tự động trước khi triển khai lên cụm Kubernetes production.
Sau khi cân nhắc giữa Nexus OSS và Harbor, team chọn Harbor—dự án mã nguồn mở thuộc cấp Graduated của CNCF. Harbor giải quyết gọn gàng ba bài toán:
- Tốc độ và kiểm soát: Toàn bộ dữ liệu nằm trên máy chủ nội bộ. Bạn có thể kéo image dung lượng 800MB qua cổng mạng 1Gbps chỉ trong vài giây, không tốn một đồng băng thông internet.
- Bảo mật chủ động: Engine Trivy quét tự động các layer của image. Bạn có thể thiết lập chính sách chặn đứng lệnh pull nếu image dính CVE mức Critical.
- Quản trị tập trung: Hỗ trợ đồng bộ tài khoản qua LDAP/Active Directory, phân quyền dự án rõ ràng và hỗ trợ ký số container bằng Cosign.
Cài đặt các thành phần phụ thuộc trên CentOS Stream 9
Harbor vận hành dưới dạng một cụm container do Docker Compose điều phối. Vì vậy, bước đầu tiên là chuẩn bị môi trường Docker Engine và Compose plugin sạch trên CentOS Stream 9.
1. Cài đặt Docker CE và Docker Compose Plugin
Đầu tiên, bạn cài gói quản lý repository, khai báo kho phần mềm chính thức của Docker rồi tải các package cần thiết:
# Cài đặt công cụ quản lý repository
sudo dnf install -y dnf-plugins-core
# Thêm repository Docker CE chính thức cho RHEL/CentOS
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# Cài đặt Docker engine, CLI, containerd và Docker Compose plugin
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Khởi động dịch vụ Docker và kích hoạt cùng hệ thống
sudo systemctl enable --now docker
# Kiểm tra phiên bản Docker hoạt động
sudo docker version
2. Cấu hình tường lửa Firewalld
Mặc định Harbor sử dụng hai cổng: HTTP (80) và HTTPS (443). Hãy mở vĩnh viễn hai cổng này trên firewall:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
3. Tạo chứng chỉ SSL/TLS tự ký (Self-signed Certificate)
Docker daemon mặc định từ chối giao tiếp với registry qua kênh HTTP không mã hóa. Thay vì dùng tùy chọn insecure-registries kém an toàn, bạn nên kích hoạt HTTPS ngay từ đầu. Dưới đây là cách tạo chứng chỉ tự ký chuẩn SAN (Subject Alternative Name) cho domain nội bộ registry.internal.lan:
# Tạo thư mục chứa chứng chỉ
sudo mkdir -p /data/cert && cd /data/cert
# Khởi tạo khóa private cho CA nội bộ
sudo openssl genrsa -out ca.key 4096
# Tạo chứng chỉ CA với thời hạn 10 năm
sudo openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=VN/ST=Hanoi/L=Hanoi/O=ITFromZero/CN=registry.internal.lan" \
-key ca.key -out ca.crt
# Tạo khóa private cho Harbor server
sudo openssl genrsa -out server.key 4096
# Tạo Certificate Signing Request (CSR)
sudo openssl req -sha512 -new \
-subj "/C=VN/ST=Hanoi/L=Hanoi/O=ITFromZero/CN=registry.internal.lan" \
-key server.key -out server.csr
# Tạo file cấu hình SAN để tránh lỗi xác thực trên trình duyệt và Docker
cat <<EOF | sudo tee v3.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1=registry.internal.lan
DNS.2=registry
EOF
# Ký chứng chỉ cho máy chủ Harbor bằng CA vừa tạo
sudo openssl x509 -req -sha512 -days 365 \
-extfile v3.ext \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in server.csr -out server.crt
Cài đặt và cấu hình Harbor
1. Tải bộ cài đặt Harbor Offline Installer
Gói offline nặng khoảng 800MB và chứa toàn bộ image cần thiết. Nhờ đó, việc cài đặt sẽ nhanh và ổn định hơn so với bản online:
cd /opt
sudo wget https://github.com/goharbor/harbor/releases/download/v2.10.0/harbor-offline-installer-v2.10.0.tgz
sudo tar -zxvf harbor-offline-installer-v2.10.0.tgz
cd harbor
2. Chỉnh sửa file cấu hình harbor.yml
Tạo bản sao từ file mẫu và mở file cấu hình bằng text editor:
sudo cp harbor.yml.tmpl harbor.yml
sudo vi harbor.yml
Cập nhật domain, đường dẫn chứng chỉ và mật khẩu quản trị như sau:
# Tên miền hoặc FQDN của máy chủ Harbor
hostname: registry.internal.lan
# Cổng HTTP (dùng để redirect sang HTTPS)
http:
port: 80
# Cấu hình HTTPS kèm đường dẫn chứng chỉ vừa tạo
https:
port: 443
certificate: /data/cert/server.crt
private_key: /data/cert/server.key
# Mật khẩu tài khoản admin mặc định
harbor_admin_password: StrongPassword123!
# Nơi lưu trữ image, database và cache redis
data_volume: /data/harbor
3. Chạy script cài đặt kèm scanner Trivy
Đừng quên thêm cờ --with-trivy khi chạy file cài đặt. Tham số này sẽ kéo và dựng sẵn container phân tích mã độc:
sudo ./install.sh --with-trivy
Quá trình bung image và khởi tạo 9 dịch vụ con mất khoảng 2 đến 3 phút. Khi màn hình terminal xuất hiện dòng chữ ----Harbor has been installed and started successfully.----, hệ thống đã sẵn sàng đón kết nối.
Vận hành thực tế & Kiểm tra bảo mật
1. Khai báo tin cậy chứng chỉ trên Docker client
Nếu không khai báo CA cert, Docker client sẽ báo lỗi x509: certificate signed by unknown authority ngay khi bạn gõ lệnh login. Hãy copy file ca.crt vào thư mục tin cậy của Docker trên từng máy worker hoặc developer:
# Tạo thư mục certs.d tương ứng với tên domain
sudo mkdir -p /etc/docker/certs.d/registry.internal.lan/
# Copy file root CA từ máy chủ Harbor sang
sudo cp /data/cert/ca.crt /etc/docker/certs.d/registry.internal.lan/ca.crt
# Tải lại cấu hình Docker daemon
sudo systemctl restart docker
Nếu chưa dựng DNS server nội bộ, bạn có thể map tạm IP của server Harbor vào file hosts:
echo "192.168.1.50 registry.internal.lan" | sudo tee -a /etc/hosts
2. Đăng nhập và đẩy image thử nghiệm
Đăng nhập vào registry bằng tài khoản admin thông qua terminal:
docker login registry.internal.lan
# Username: admin
# Password: StrongPassword123!
Bây giờ, hãy thử kéo image alpine:3.18 về máy, gắn tag và đẩy lên dự án mặc định library:
# Kéo image nhẹ từ Docker Hub
docker pull alpine:3.18
# Gắn tag trỏ về Harbor Private Registry
docker tag alpine:3.18 registry.internal.lan/library/alpine:3.18
# Đẩy image lên kho nội bộ qua mạng LAN
docker push registry.internal.lan/library/alpine:3.18
3. Quét CVE và kích hoạt rào chắn tự động
Mở trình duyệt, truy cập https://registry.internal.lan và đăng nhập tài khoản admin.
- Vào mục Projects > chọn library > chuyển sang tab Repositories.
- Nhấp vào repository
alpine, bạn sẽ thấy tag3.18vừa đẩy lên. - Tích chọn tag này rồi bấm nút Scan. Sau khoảng 15 đến 30 giây, cột Vulnerabilities sẽ liệt kê chi tiết các lỗ hổng phát hiện được theo 4 cấp độ: Low, Medium, High và Critical.
Để ngăn chặn triệt để rủi ro đưa image dính lỗ hổng lên production, bạn chuyển sang tab Project Settings và bật hai chính sách sau:
- Prevent vulnerable images from running: Đặt ngưỡng chặn tại mức High hoặc Critical. Bất kỳ lệnh
docker pullnào nhắm vào image vượt quá ngưỡng này đều bị Harbor từ chối ngay với mã lỗi412 Precondition Failed. - Automatically scan images on push: Kích hoạt cơ chế quét tự động ngay khi image hoàn tất tải lên kho lưu trữ.
4. Giám sát tình trạng các service của Harbor
Trong quá trình vận hành, bạn có thể kiểm tra sức khỏe của toàn bộ cụm container Harbor bằng lệnh:
cd /opt/harbor
sudo docker compose ps
Tất cả container như harbor-core, registry, nginx, harbor-db và trivy-adapter cần ở trạng thái Up (healthy). Khi cần gỡ lỗi quét bảo mật, bạn có thể theo dõi luồng log thời gian thực:
sudo docker compose logs -f trivy-adapter
Thiết lập này cung cấp cho team một trạm trung chuyển image khép kín, an toàn tuyệt đối về dữ liệu và loại bỏ hoàn toàn tình trạng nghẽn băng thông ra ngoài internet.

