So sánh các giải pháp Container Registry
Việc lựa chọn image registry cho máy chủ bare-metal hoặc mạng cô lập air-gapped thường xoay quanh ba hướng tiếp cận chính:
- Bộ giải pháp Enterprise đa dịch vụ (ví dụ: Harbor): Harbor cung cấp cơ chế phân quyền RBAC chi tiết, hạn ngạch dự án (project quota), tài khoản robot và các chính sách replication. Điểm hạn chế? Hệ thống này phải khởi chạy gần mười container riêng biệt (PostgreSQL, Redis, Core, Jobservice, Trivy, Nginx, Registry). Trên một edge gateway có 4 GB RAM hoặc một máy ảo staging dùng chung, Harbor đã chiếm khoảng 2 GB RAM ngay ở trạng thái không tải.
- Distribution Registry truyền thống (Docker Registry v2): File nhị phân
distribution/distributioncổ điển rất nhỏ gọn và tiêu thụ chưa đến 40 MB RAM. Tuy nhiên, nó thiếu khả năng khám phá artifact OCI gốc, không hỗ trợ lập chỉ mục tìm kiếm (search indexing), không tích hợp sẵn danh sách kiểm soát truy cập (ACL) và không có hook quét lỗ hổng bảo mật. - OCI Registry hiện đại dạng Single-Binary (Zot): Zot là một dự án ươm tạo của CNCF được viết bằng Go. Dự án được phân phối dưới dạng một file binary tĩnh duy nhất hoặc container mà không phụ thuộc vào bất kỳ cơ sở dữ liệu bên ngoài nào. Dù có dung lượng và mức tiêu thụ tài nguyên rất nhỏ, Zot vẫn hỗ trợ lập chỉ mục gốc cho OCI Image Index, Helm chart, Cosign signature và tệp đính kèm SBOM.
| Tính năng | Harbor | Docker Registry v2 | Zot Registry |
|---|---|---|---|
| Kiến trúc | Microservices (8–10 container) | Single process | Single binary / container |
| Mức chiếm dụng RAM khi không tải | ~1.5 GB – 3.0 GB | ~20 MB – 40 MB | ~30 MB – 60 MB |
| Hỗ trợ OCI 1.1 | Hỗ trợ qua tầng Core | Cơ bản / Schema cũ | Chuẩn OCI 1.1 Specification gốc |
| Phụ thuộc hạ tầng | PostgreSQL, Redis | Không có | Không có (Storage engine nhúng sẵn) |
Đánh giá Zot: Ưu điểm và điểm đánh đổi
Trước khi triển khai Zot trên toàn bộ hệ thống, bạn nên cân nhắc những điểm vượt trội cũng như những giới hạn có thể gặp phải.
Điểm mạnh của Zot
- Khởi động gần như tức thì & Overhead thấp: Khởi động trong chưa đầy 200 mili-giây và chỉ tiêu tốn khoảng 35 MB RAM khi rảnh. Bạn có thể dễ dàng nhúng trực tiếp vào các CI build agent, test runner hoặc thiết bị edge.
- Xử lý OCI Artifact gốc: Đẩy Helm 3 chart, binary WebAssembly, chữ ký Cosign và SBOM CycloneDX trực tiếp bằng các công cụ tiêu chuẩn mà không cần cài thêm plugin.
- Bảo trì dễ dàng trong môi trường Air-Gapped: Việc sao lưu cực kỳ đơn giản. Chỉ cần nén thư mục dữ liệu và duy nhất một file cấu hình JSON là hoàn tất.
- Tiện ích mở rộng theo dạng mô-đun: Kích hoạt htpasswd, LDAP, OAuth2/OIDC, chống trùng lặp (deduplication) và quét image bằng Trivy chỉ bằng cách bật các cờ boolean trong một file cấu hình.
Các điểm đánh đổi cần lưu ý
- Giao diện web tinh giản: Zot đi kèm một UI trực quan để duyệt qua các repository và tag, nhưng không có dashboard quản lý nhóm chi tiết theo từng cấp dự án như Harbor.
- Quản trị doanh nghiệp: Các doanh nghiệp lớn yêu cầu quản lý hạn ngạch giữa nhiều phòng ban và quy trình phê duyệt phức tạp có thể vẫn sẽ ưu tiên Harbor hơn.
Kiến trúc mục tiêu
Trong môi trường production, hãy chạy Zot bên trong Docker Compose phía sau một reverse proxy như Nginx hoặc Traefik để xử lý TLS termination. Các container runtime như containerd và CRI-O mặc định từ chối các registry HTTP không an toàn. Đặt một proxy phía trước sẽ giúp xử lý HTTPS trơn tru mà không cần cấu hình chứng chỉ TLS trực tiếp bên trong Zot.
Dưới đây là cấu trúc thư mục trên máy chủ:
/opt/zot/
├── config.json
├── htpasswd
├── docker-compose.yml
└── data/
Hướng dẫn triển khai từng bước
Thiết lập một Zot registry an toàn, đầy đủ chức năng trên bất kỳ máy chủ Linux nào đã cài đặt Docker Engine và Docker Compose v2.
Bước 1: Thiết lập cấu trúc thư mục
Tạo thư mục gốc cho dự án và điểm gắn (mount point) dữ liệu:
sudo mkdir -p /opt/zot/data
cd /opt/zot
Bước 2: Tạo thông tin xác thực
Tạo file mật khẩu băm bằng bcrypt thông qua một container tạm thời:
# Tạo mục htpasswd cho người dùng 'developer'
docker run --rm httpd:alpine htpasswd -B -b -n developer SecurePassword123 > htpasswd
# Giới hạn quyền chỉ cho chủ sở hữu
chmod 600 htpasswd
Bước 3: Cấu hình Zot (config.json)
Tạo file config.json để thiết lập đường dẫn lưu trữ cục bộ, cơ chế chống trùng lặp, dọn rác (garbage collection) và xác thực:
cat <<'EOF' > config.json
{
"distSpecVersion": "1.1.0",
"storage": {
"rootDirectory": "/var/lib/registry",
"gc": true,
"gcDelay": "1h",
"dedupe": true
},
"http": {
"address": "0.0.0.0",
"port": "5000",
"auth": {
"htpasswd": {
"path": "/etc/zot/htpasswd"
}
}
},
"extensions": {
"ui": {
"enable": true
},
"search": {
"enable": true
}
}
}
EOF
Bước 4: Định nghĩa dịch vụ Docker Compose
Viết file docker-compose.yml tham chiếu đến image chính thức đầy đủ tính năng của Zot:
cat <<'EOF' > docker-compose.yml
services:
zot:
image: ghcr.io/project-zot/zot-linux-amd64:v2.1.1
container_name: zot-registry
restart: unless-stopped
ports:
- "5000:5000"
volumes:
- ./config.json:/etc/zot/config.json:ro
- ./htpasswd:/etc/zot/htpasswd:ro
- ./data:/var/lib/registry
user: "1000:1000"
EOF
Cấp quyền sở hữu volume dữ liệu cho UID/GID 1000:1000:
sudo chown -R 1000:1000 /opt/zot/data
Bước 5: Khởi chạy và kiểm tra trạng thái hoạt động
Khởi động container ở chế độ chạy nền (detached mode):
docker compose up -d
# Xem log khởi động
docker compose logs -f zot
Kiểm tra xem endpoint catalog của registry có trả về HTTP 200 hay không:
curl -u developer:SecurePassword123 http://localhost:5000/v2/_catalog
Bạn sẽ nhận được một mảng repository rỗng: {"repositories":[]}.
Bước 6: Đẩy và kéo Docker Image
Đăng nhập bằng Docker CLI và đẩy một image Alpine mẫu:
# 1. Xác thực đăng nhập
echo "SecurePassword123" | docker login localhost:5000 -u developer --password-stdin
# 2. Kéo image gốc về máy
docker pull alpine:3.20
# 3. Gắn tag mới cho registry nội bộ
docker tag alpine:3.20 localhost:5000/base/alpine:3.20
# 4. Đẩy image lên registry
docker push localhost:5000/base/alpine:3.20
# 5. Xóa cache cục bộ và kéo lại image từ Zot
docker rmi localhost:5000/base/alpine:3.20
docker pull localhost:5000/base/alpine:3.20
Bước 7: Đẩy Helm Chart qua OCI
Helm 3 hỗ trợ các OCI registry như các chart repository gốc:
# 1. Tạo một chart mẫu
helm create webapp
# 2. Đóng gói thành tệp nén .tgz
helm package webapp
# 3. Đăng nhập vào Zot bằng Helm
echo "SecurePassword123" | helm registry login localhost:5000 -u developer --password-stdin
# 4. Đẩy trực tiếp file nén chart lên Zot
helm push webapp-0.1.0.tgz oci://localhost:5000/charts
# 5. Kiểm tra việc kéo và giải nén chart
helm pull oci://localhost:5000/charts/webapp --version 0.1.0 --untar
Bước 8: Xác minh các Artifact
Truy vấn lại endpoint catalog một lần nữa:
curl -u developer:SecurePassword123 http://localhost:5000/v2/_catalog
# Kết quả mong đợi: {"repositories":["base/alpine","charts/webapp"]}
Mở http://<server-ip>:5000 trên trình duyệt để khám phá các layer image, báo cáo lỗ hổng bảo mật và các OCI descriptor ngay trên giao diện web.

