اگر با Docker، Kubernetes یا CI/CD کار کرده باشید، احتمالاً با مفهومی به نام Container Registry مواجه شدهاید. Docker Imageهایی که برای اجرای Applicationها ساخته میشوند، باید جایی ذخیره شوند تا بتوان آنها را در محیطهای مختلف دریافت و اجرا کرد.
Container Registry دقیقاً همین نقش را بر عهده دارد؛ یعنی یک سیستم برای ذخیره، مدیریت، انتشار و دریافت Container Imageها.
Registry میتواند عمومی باشد و Imageها را برای همه کاربران منتشر کند یا به صورت Private در داخل سازمان راهاندازی شود تا فقط کاربران و سرویسهای مجاز بتوانند به Imageها دسترسی داشته باشند.
در معماریهای مدرن DevOps و Cloud Native، Container Registry معمولاً یکی از اجزای اصلی زنجیره Software Delivery است و مستقیماً با ابزارهایی مانند Docker، Kubernetes، GitLab CI/CD، Jenkins، ArgoCD و OpenShift در ارتباط است.
Container Registry چیست؟
Container Registry یک Repository یا مخزن برای ذخیره و توزیع Container Imageها است.
وقتی یک Application را با Docker Containerize میکنیم، معمولاً یک Image تولید میشود. این Image باید در جایی ذخیره شود تا بتوان آن را روی Server، Kubernetes Cluster یا سایر محیطهای اجرای Container دریافت کرد.
Developer
│
▼
Source Code
│
▼
Dockerfile
│
▼
Docker Build
│
▼
Container Image
│
▼
Container Registry
│
├───────────────┐
▼ ▼
Docker Host Kubernetes
برای مثال فرض کنید یک Application با نام my-app ساختهایم. پس از Build شدن Image میتوان آن را در یک Registry ذخیره کرد:
my-app:1.0.0
سپس Server یا Kubernetes میتواند همین Image را از Registry دریافت کند و Container را اجرا کند.
چرا به Container Registry نیاز داریم؟
در یک پروژه کوچک ممکن است بتوانیم Docker Image را مستقیماً روی Server Build کنیم؛ اما این روش در محیطهای Production و تیمهای چندنفره معمولاً مناسب نیست.
Container Registry چند مشکل مهم را حل میکند:
- ذخیره مرکزی Docker Imageها
- توزیع Image بین Serverهای مختلف
- مدیریت Versionهای مختلف Image
- استفاده در CI/CD
- کنترل دسترسی به Imageها
- نگهداری Imageهای Private
- اسکن Imageها از نظر Vulnerability
- مدیریت Repositoryها و پروژهها
- حذف و پاکسازی Imageهای قدیمی
- ایجاد یک منبع قابل اعتماد برای Kubernetes و سایر Runtimeها
در واقع Registry را میتوان بخشی از Software Supply Chain دانست.
Container Image چیست؟
قبل از اینکه Registry را بهتر درک کنیم، باید بدانیم دقیقاً چه چیزی داخل آن ذخیره میشود.
Container Image یک Package قابل حمل است که شامل اجزای موردنیاز برای اجرای یک Application در یک Container میشود.
برای مثال یک Image مربوط به یک Application مبتنی بر PHP ممکن است شامل موارد زیر باشد:
- Base Operating System Layer
- PHP Runtime
- Required Extensions
- Application Dependencies
- Application Source Code
- Configuration Files
Docker Image معمولاً به صورت چند Layer ساخته میشود.
Docker Image
│
├── Layer 1
│ └── Base OS
│
├── Layer 2
│ └── PHP / Node.js / Python
│
├── Layer 3
│ └── Dependencies
│
└── Layer 4
└── Application
یکی از مزایای این معماری، امکان استفاده مجدد از Layerها و کاهش حجم و زمان انتقال Imageها است.
Docker Registry چگونه کار میکند؟
در سادهترین حالت، یک Docker Registry یک سرویس HTTP/HTTPS است که Clientها میتوانند Imageها را در آن Push یا از آن Pull کنند.
Docker Client
│
┌────────┴────────┐
│ │
docker push docker pull
│ │
▼ ▼
┌──────────────────────────┐
│ Container Registry │
│ │
│ Images / Layers / Tags │
└──────────────────────────┘
برای مثال وقتی دستور زیر را اجرا میکنیم:
docker push registry.example.com/my-app:1.0.0
Docker Client Image را به Registry ارسال میکند.
در طرف مقابل، وقتی روی یک Server دستور زیر اجرا شود:
docker pull registry.example.com/my-app:1.0.0
Docker Image از Registry دریافت میشود.
Docker Hub چیست؟
Docker Hub یکی از شناختهشدهترین Container Registryها است و به عنوان Registry عمومی و خصوصی برای Docker Imageها استفاده میشود.
بسیاری از Imageهای رسمی و محبوب مانند Nginx، Redis، PostgreSQL و بسیاری از ابزارهای دیگر از طریق Docker Hub در دسترس هستند.
برای مثال میتوان یک Image را با دستور زیر دریافت کرد:
docker pull nginx
در این حالت Docker به صورت پیشفرض به Registry پیشفرض خود یعنی Docker Hub مراجعه میکند.
اما در محیطهای Enterprise معمولاً سازمانها ترجیح میدهند Imageهای اختصاصی خود را در یک Registry داخلی یا Private نگهداری کنند.
Public Registry و Private Registry
Container Registryها را میتوان از نظر سطح دسترسی به دو گروه کلی تقسیم کرد:
- Public Registry
- Private Registry
Public Container Registry
در Public Registry، Imageها میتوانند برای عموم کاربران قابل دسترسی باشند.
این مدل برای Open Source Projectها و انتشار عمومی Software بسیار مناسب است.
Private Container Registry
در Private Registry، دسترسی به Imageها محدود به کاربران یا سرویسهای مجاز است.
برای مثال یک سازمان ممکن است Image مربوط به Application داخلی خود را در Registry زیر قرار دهد:
registry.company.local
│
├── backend
├── frontend
├── api
└── worker
در این حالت Applicationهای داخلی، CI/CD Pipelineها و Kubernetes Cluster میتوانند به Registry متصل شوند، بدون اینکه Imageها روی Internet عمومی منتشر شوند.
Registry و CI/CD چه ارتباطی دارند؟
یکی از مهمترین کاربردهای Container Registry در Pipelineهای CI/CD است.
فرض کنید Developer کدی را در Git Repository Push میکند.
Developer
│
▼
Git Push
│
▼
CI/CD Pipeline
│
▼
Docker Build
│
▼
Security Scan
│
▼
Docker Push
│
▼
Container Registry
│
▼
Deployment
در این معماری، Registry نقطه اتصال بین مرحله Build و مرحله Deployment است.
برای مثال GitLab CI میتواند Image را Build کند و آن را در Registry قرار دهد. سپس Kubernetes میتواند همان Image را Pull کرده و Application جدید را Deploy کند.
Docker Push و Docker Pull چیست؟
دو عملیات بسیار مهم در ارتباط با Registry عبارتاند از Push و Pull.
Docker Push
Push یعنی ارسال Image از Docker Client به Registry.
docker push registry.example.com/my-app:1.0.0
Docker Pull
Pull یعنی دریافت Image از Registry به سمت Docker Host یا Container Runtime.
docker pull registry.example.com/my-app:1.0.0
در یک Pipeline معمولاً Push توسط CI/CD انجام میشود و Pull توسط محیط Deployment.
ساختار نام Docker Image
یکی از مفاهیم مهم هنگام کار با Registry، ساختار نام Image است.
registry.example.com/team/my-app:1.2.0
│ │ │
│ │ └── Tag
│ │
│ └── Repository
│
└── Registry
یک Image Reference میتواند شامل بخشهای مختلفی باشد:
- Registry Host
- Namespace یا Organization
- Repository
- Tag
برای مثال:
registry.ultimateco.cloud/backend/api:2.4.1
در این مثال:
- registry.ultimateco.cloud نام Registry است.
- backend Namespace یا Project است.
- api نام Repository است.
- 2.4.1 Tag مربوط به Image است.
Docker Image Tag چیست؟
Tag برای مشخص کردن Version یا Variant یک Image استفاده میشود.
برای مثال:
my-app:1.0.0
my-app:1.1.0
my-app:2.0.0
هر Tag میتواند به یک Image مشخص اشاره کند.
در محیط Production بهتر است از Tagهای مشخص و قابل ردیابی استفاده شود.
برای مثال:
my-app:2026.08.08
my-app:1.4.2
my-app:git-a81f3c2
استفاده از Tagهایی مانند latest در Deploymentهای حساس میتواند باعث ابهام شود؛ زیرا محتوای Image
پشت این Tag ممکن است در طول زمان تغییر کند.
Image Digest چیست؟
علاوه بر Tag، Docker Image دارای یک Digest نیز است که یک شناسه مبتنی بر Hash برای محتوای Image است.
my-app@sha256:
a8f3c7d91e...
برخلاف Tag که میتواند به Image دیگری تغییر کند، Digest به محتوای مشخصی از Image اشاره میکند.
به همین دلیل در محیطهای حساس و مخصوصاً برای Software Supply Chain Security، استفاده از Digest میتواند قابلیت Traceability و Reproducibility را افزایش دهد.
Registry فقط محل ذخیره فایل نیست
یک تصور اشتباه این است که Container Registry را صرفاً یک File Storage برای Docker Imageها بدانیم.
Registry مدرن معمولاً قابلیتهای بسیار بیشتری دارد، از جمله:
- Authentication
- Authorization
- Repository Management
- Image Tagging
- Image Retention
- Garbage Collection
- Vulnerability Scanning
- Audit Logs
- Replication
- Access Control
- Integration با CI/CD
همین قابلیتها است که راهکارهایی مانند Harbor را از یک Registry ساده Docker متمایز میکند.
Docker Registry چیست؟
Docker Registry یک پیادهسازی Open Source و رسمی از Registry API است که برای ذخیره و توزیع Container Imageها استفاده میشود.
این پروژه در مقایسه با راهکارهایی مانند Harbor یا GitLab Container Registry، یک Registry نسبتاً ساده و سبک در اختیار شما قرار میدهد و تمرکز اصلی آن روی ذخیره و دریافت Imageها است.
برای مثال میتوان یک Registry داخلی را روی Server سازمان اجرا کرد:
Developer
│
▼
Docker Build
│
▼
docker push
│
▼
┌─────────────────────────┐
│ Docker Registry │
│ │
│ registry.company.local │
└─────────────────────────┘
│
▼
docker pull
│
▼
Kubernetes / Docker Host
راهاندازی یک Registry ساده با Docker نیز امکانپذیر است:
docker run -d \
--name registry \
--restart=always \
-p 5000:5000 \
registry:3
در این حالت Registry روی Port 5000 در دسترس خواهد بود.
البته این Configuration برای یک محیط Production کافی نیست و موضوعاتی مانند TLS، Authentication، Storage Persistence، Backup و Monitoring باید به شکل جداگانه طراحی شوند.
معماری Docker Registry
در سادهترین معماری، Registry از یک API و Storage Backend تشکیل شده است.
Docker Client
│
│ HTTPS
▼
┌─────────────────┐
│ Registry API │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Storage Backend │
└────────┬────────┘
│
┌───────────┼───────────┐
▼ ▼ ▼
Image Layers Metadata
Storage Backend میتواند بسته به معماری مورد استفاده متفاوت باشد و حتی میتوان Registry را به Object Storage متصل کرد.
این موضوع برای محیطهای بزرگ اهمیت زیادی دارد؛ زیرا Container Imageها ممکن است فضای بسیار زیادی مصرف کنند.
Registry و Object Storage
یکی از معماریهای رایج برای Registryهای Enterprise این است که Imageها به جای Local Disk روی Object Storage ذخیره شوند.
Registry
│
▼
Storage Driver
│
▼
Object Storage
│
┌───────────┼───────────┐
▼ ▼ ▼
S3 MinIO Cloud Storage
برای مثال میتوان Registry را به MinIO متصل کرد و دادههای Image را روی یک Object Storage Cluster نگهداری کرد.
این معماری مزایایی مانند Scalability، مدیریت سادهتر Storage و امکان استفاده از Storageهای Distributed را فراهم میکند.
Authentication در Container Registry
در یک Registry عمومی ممکن است همه کاربران بتوانند Imageها را Pull کنند، اما در یک Registry سازمانی معمولاً باید دسترسیها کنترل شوند.
Authentication مشخص میکند که کاربر یا سرویس چه کسی است.
برای مثال:
Developer
│
│ Username / Password
▼
Registry
│
├── Authentication
│
└── Access Granted
Docker Client میتواند با Registry Login کند:
docker login registry.company.local
پس از Authentication، Client میتواند بر اساس Permissionهای خود Imageها را Push یا Pull کند.
Authorization چیست؟
Authentication و Authorization دو مفهوم متفاوت هستند.
- Authentication: شما چه کسی هستید؟
- Authorization: چه کاری اجازه دارید انجام دهید؟
برای مثال ممکن است یک Developer بتواند Image را Pull کند اما اجازه Push به Repository Production را نداشته باشد.
User
│
▼
Authentication
│
▼
Identity
│
▼
Authorization
│
├── Pull ✓
├── Push ✓
├── Delete ✕
└── Admin ✕
TLS و HTTPS در Container Registry
استفاده از HTTPS در Registryهای Production بسیار مهم است.
Registry معمولاً شامل Imageهایی است که ممکن است شامل کد اختصاصی، Dependencyهای داخلی یا اطلاعات حساس باشند. بنابراین ارتباط بین Client و Registry باید رمزنگاری شود.
Docker Client
│
│ HTTPS / TLS
▼
┌──────────────────────┐
│ Container Registry │
└──────────────────────┘
در محیط Production بهتر است Registry با یک Domain مشخص و Certificate معتبر در دسترس باشد:
registry.example.com
│
▼
HTTPS
│
▼
:443
استفاده از Reverse Proxyهایی مانند Nginx، Caddy یا HAProxy نیز میتواند برای Terminate کردن TLS و کنترل دسترسی به Registry مفید باشد.
آیا میتوان Registry را بدون HTTPS اجرا کرد؟
از نظر فنی امکان اجرای Registry بدون TLS وجود دارد، اما این روش برای Production مناسب نیست.
Docker در چنین شرایطی Registry را به عنوان یک Insecure Registry در نظر میگیرد و باید روی Clientها تنظیمات خاصی انجام شود.
برای مثال:
{
"insecure-registries": [
"registry.example.com:5000"
]
}
این روش بیشتر برای Lab، Development یا محیطهای کاملاً کنترلشده کاربرد دارد و برای Registry Production بهتر است از TLS معتبر استفاده شود.
Harbor چیست؟
Harbor یکی از محبوبترین راهکارهای Open Source برای راهاندازی یک Enterprise Container Registry است.
Harbor در واقع فقط یک Docker Registry ساده نیست؛ بلکه مجموعهای از قابلیتهای مدیریتی، امنیتی و عملیاتی را روی Registry ارائه میکند.
به همین دلیل Harbor در بسیاری از Data Centerها، Private Cloudها و Kubernetes Environmentها مورد استفاده قرار میگیرد.
چرا Harbor به وجود آمد؟
یک Registry ساده وظیفه اصلی خود یعنی ذخیره و توزیع Imageها را به خوبی انجام میدهد، اما در یک سازمان بزرگ معمولاً نیازهای بیشتری داریم.
برای مثال:
- مدیریت چندین Project
- مدیریت User و Team
- Role-Based Access Control
- Vulnerability Scanning
- Image Replication
- Audit Log
- Image Retention
- Garbage Collection
- OIDC / LDAP Integration
- Web UI
- Policy Management
Harbor برای پاسخ دادن به همین نیازها ساخته شده است.
معماری Harbor
Harbor از چند Component تشکیل شده که در کنار یکدیگر یک Container Registry کامل را ایجاد میکنند.
Users / CI/CD
│
▼
┌─────────────┐
│ Harbor │
│ UI │
└──────┬──────┘
│
▼
┌─────────────────┐
│ Harbor Proxy │
└────────┬────────┘
│
┌────────────────┼────────────────┐
▼ ▼ ▼
Registry Core API Scanner
│ │ │
└────────────────┼────────────────┘
▼
Database
│
▼
Redis / Cache
│
▼
Storage Backend
معماری دقیق Harbor بسته به Version و Configuration میتواند متفاوت باشد، اما به صورت مفهومی میتوان آن را مجموعهای از سرویسهای مرتبط دانست که روی یک Registry Core قرار گرفتهاند.
مهمترین قابلیتهای Harbor
1. Project Management
در Harbor میتوان Imageها را در قالب Projectهای مختلف مدیریت کرد.
Harbor
│
├── project-backend
│ ├── api
│ ├── worker
│ └── scheduler
│
├── project-frontend
│ ├── web
│ └── nginx
│
└── project-infrastructure
├── monitoring
├── logging
└── tools
این ساختار برای سازمانهایی که تیمها و Applicationهای متعددی دارند بسیار مفید است.
2. Role-Based Access Control
Harbor امکان تعریف Roleهای مختلف برای کاربران و Projectها را فراهم میکند.
برای مثال:
- Project Admin
- Developer
- Guest
- Maintainer
در نتیجه میتوان مشخص کرد چه کسی اجازه Push، Pull یا مدیریت Repositoryها را داشته باشد.
3. Vulnerability Scanning
یکی از مهمترین ویژگیهای Harbor قابلیت اسکن Container Imageها برای پیدا کردن Vulnerabilityهای شناختهشده است.
Docker Image
│
▼
Harbor
│
▼
Vulnerability Scanner
│
├── Critical
├── High
├── Medium
└── Low
این قابلیت کمک میکند قبل از Deploy شدن Image در Production، وضعیت امنیتی آن بررسی شود.
در معماریهای DevSecOps میتوان این فرآیند را با CI/CD نیز ترکیب کرد تا Imageهای دارای Vulnerabilityهای مشخص اجازه ورود به محیط Production را نداشته باشند.
4. Image Replication
Harbor میتواند Imageها را بین Registryهای مختلف Replicate کند.
Harbor - Site A
│
│ Replication
▼
Harbor - Site B
│
▼
Disaster Recovery
این قابلیت برای سازمانهایی که چند Data Center دارند بسیار کاربردی است.
برای مثال میتوان Registry اصلی را در Data Center اول قرار داد و Imageهای مهم را به Registry موجود در Data Center دوم Replicate کرد.
5. Image Retention
در پروژههای بزرگ ممکن است تعداد Imageها و Tagها به سرعت افزایش پیدا کند.
my-app
│
├── 1.0.0
├── 1.0.1
├── 1.0.2
├── 1.0.3
├── 1.0.4
├── ...
├── 1.9.8
└── latest
اگر هیچ Policy برای حذف Versionهای قدیمی وجود نداشته باشد، Storage Registry به مرور زمان پر خواهد شد.
Retention Policy کمک میکند Imageها و Artifactهای قدیمی بر اساس Ruleهای مشخص حذف یا نگهداری شوند.
6. Garbage Collection
حذف یک Tag الزاماً به معنی آزاد شدن فوری تمام فضای Disk نیست.
Container Imageها از Layerهایی تشکیل شدهاند و ممکن است یک Layer توسط چند Image مورد استفاده قرار گرفته باشد.
Image A ──┐
├── Layer 1
Image B ──┘
Image A ───── Layer 2
Image B ───── Layer 3
Registry باید تشخیص دهد کدام Layerها دیگر توسط هیچ Imageای استفاده نمیشوند و میتوان آنها را حذف کرد.
این فرآیند در قالب Garbage Collection انجام میشود.
Harbor و Kubernetes
Harbor یکی از گزینههای محبوب برای Kubernetes Clusterهای Private و Enterprise است.
Kubernetes برای اجرای یک Pod ممکن است نیاز داشته باشد Image را از Registry دریافت کند.
Kubernetes
│
▼
Pod Specification
│
▼
Container Image
│
▼
Harbor
│
▼
Image Pull
│
▼
Container Runtime
اگر Harbor Private باشد، Kubernetes باید Credential لازم برای دسترسی به Registry را داشته باشد.
این کار معمولاً با استفاده از imagePullSecrets انجام میشود.
apiVersion: v1
kind: Secret
metadata:
name: registry-secret
type: kubernetes.io/dockerconfigjson
سپس میتوان Secret را در Deployment یا Service Account مورد استفاده قرار داد.
Harbor و Kubernetes در یک معماری Private Cloud
در یک زیرساخت Private Cloud مدرن، Harbor میتواند بین CI/CD و Kubernetes قرار بگیرد.
Developer
│
▼
Git Repository
│
▼
CI/CD
│
Docker Build
│
▼
Security Scan
│
▼
Harbor
│
▼
Kubernetes
│
▼
Pods
این معماری باعث میشود Container Image قبل از رسیدن به Production از یک مسیر مشخص و قابل کنترل عبور کند.
Harbor و GitLab چه تفاوتی دارند؟
Harbor و GitLab Container Registry هر دو میتوانند Container Imageها را ذخیره کنند، اما هدف اصلی آنها متفاوت است.
Harbor در درجه اول یک Container Registry و Artifact Management Platform است، در حالی که GitLab یک پلتفرم کامل DevSecOps است که Container Registry یکی از قابلیتهای آن محسوب میشود.
GitLab
│
├── Git Repository
├── Issues
├── CI/CD
├── Packages
├── Container Registry
├── Security
└── DevSecOps
در مقابل:
Harbor
│
├── Container Registry
├── Artifact Management
├── Vulnerability Scanning
├── Replication
├── RBAC
└── Security Policies
بنابراین انتخاب بین این دو به معماری سازمان و ابزارهای موجود بستگی دارد.
GitLab Container Registry چیست؟
GitLab Container Registry Registry داخلی GitLab برای ذخیره و مدیریت Container Imageها است.
مزیت مهم آن این است که Repository، Source Code، CI/CD Pipeline و Container Registry میتوانند در یک پلتفرم واحد قرار داشته باشند.
GitLab
│
┌───────────────┼────────────────┐
▼ ▼ ▼
Repository CI/CD Container Registry
│ │ │
└───────────────┼────────────────┘
▼
Deployment
برای تیمهایی که از GitLab به عنوان پلتفرم اصلی Development و خدمات دواپس استفاده میکنند، این Integration میتواند بسیار ارزشمند باشد.
Docker Registry یا Harbor یا GitLab Registry؟
انتخاب Registry مناسب به اندازه و نیاز سازمان بستگی دارد.
| ویژگی | Docker Registry | Harbor | GitLab Registry |
|---|---|---|---|
| Open Source | بله | بله | بله |
| سادگی | بسیار زیاد | متوسط | متوسط |
| Web UI | به صورت Native محدود | بله | بله |
| RBAC | محدود | قوی | قوی |
| Vulnerability Scanning | Native محدود | بله | بله |
| Replication | محدود | بله | بسته به معماری |
| CI/CD Integration | نیازمند Integration | بسیار خوب | عالی |
| Git Repository | خیر | خیر | بله |
| DevSecOps Platform | خیر | خیر | بله |
| مناسب برای Enterprise | با طراحی مناسب | بسیار مناسب | بسیار مناسب |
چه زمانی Docker Registry ساده انتخاب خوبی است؟
اگر فقط به یک Registry سبک برای ذخیره و دریافت Image نیاز دارید، Docker Registry میتواند انتخاب بسیار خوبی باشد.
برای مثال:
- Lab و Development
- پروژههای کوچک
- محیطهای داخلی ساده
- CI/CD ساده
- Registry موقت
مزیت اصلی آن سادگی و مصرف پایین منابع است.
چه زمانی Harbor انتخاب بهتری است؟
Harbor زمانی جذابتر میشود که Registry بخشی از یک Infrastructure جدی باشد.
برای مثال:
- Private Cloud
- Kubernetes Production
- چندین تیم Development
- نیاز به RBAC
- نیاز به Vulnerability Scanning
- چند Data Center
- نیاز به Image Replication
- نیاز به Audit و Governance
چه زمانی GitLab Container Registry انتخاب بهتری است؟
اگر GitLab از قبل پلتفرم اصلی تیم باشد، استفاده از Container Registry داخلی GitLab معمولاً بسیار منطقی است.
در این حالت میتوان کل مسیر زیر را در یک Platform مدیریت کرد:
Code
│
▼
GitLab Repository
│
▼
GitLab CI/CD
│
▼
Docker Build
│
▼
GitLab Container Registry
│
▼
Kubernetes
این مدل پیچیدگی Integration بین سیستمهای مختلف را کاهش میدهد.
Harbor در مقابل Docker Hub
Docker Hub یک سرویس Registry عمومی و Cloud-based است، در حالی که Harbor را میتوان داخل Infrastructure سازمان Deploy کرد.
| ویژگی | Docker Hub | Harbor |
|---|---|---|
| نوع | Cloud Service | Self-hosted |
| کنترل زیرساخت | محدود | کامل |
| Private Registry | بله | بله |
| استقرار داخل Data Center | خیر | بله |
| Replication بین Registryها | محدودتر | بله |
| Integration با Private Cloud | خوب | عالی |
برای سازمانهایی که به دلایل امنیتی، Compliance یا Network Architecture نمیتوانند Imageهای خود را در یک سرویس عمومی نگهداری کنند، Self-hosted Registry مانند Harbor گزینه بسیار مناسبی است.
Container Registry و Software Supply Chain
در معماریهای مدرن DevOps، Container Registry دیگر صرفاً یک Storage برای Imageها نیست و به یکی از نقاط مهم Software Supply Chain تبدیل شده است.
Source Code
│
▼
Build
│
▼
Container Image
│
▼
Security Scan
│
▼
Registry
│
▼
Deployment
│
▼
Production
اگر Image آلوده یا دارای Vulnerability شدید وارد Registry شود و بدون کنترل به Production برسد، کل زنجیره Software Delivery تحت تأثیر قرار میگیرد.
به همین دلیل Registryهای مدرن معمولاً با ابزارهای Security و CI/CD یکپارچه میشوند.
Image Signing چیست؟
یکی از موضوعات مهمتر در امنیت Containerها، اطمینان از اصالت Image است.
در یک Supply Chain امن، فقط اینکه Image از Registry داخلی آمده باشد کافی نیست؛ باید بتوانیم بررسی کنیم Image توسط منبع مورد اعتماد ساخته و منتشر شده است.
Container Image
│
▼
Signing
│
▼
Registry
│
▼
Verification
│
▼
Deployment
فناوریهایی مانند Sigstore، Cosign و Notary در این حوزه مورد استفاده قرار میگیرند.
این موضوع مخصوصاً در محیطهای Enterprise و Kubernetes که Security و Supply Chain اهمیت بالایی دارند، اهمیت زیادی پیدا میکند.
Image Scanning در CI/CD
بهتر است Vulnerability Scanning فقط بعد از ورود Image به Registry انجام نشود و بخشی از Pipeline نیز باشد.
Git Push
│
▼
CI Pipeline
│
▼
Docker Build
│
▼
Vulnerability Scan
│
├── Critical ──► STOP
│
└── Pass
│
▼
Push
│
▼
Registry
در این مدل میتوان Policy تعریف کرد که مثلاً Image دارای Vulnerability با Severity مشخص اجازه ورود به Production را نداشته باشد.
Container Registry و Air-Gapped Environment
در برخی سازمانها Infrastructure به Internet دسترسی مستقیم ندارد. این محیطها را معمولاً Air-Gapped یا محدود از نظر Network Connectivity میدانیم.
در چنین محیطهایی داشتن یک Private Registry داخلی اهمیت بسیار زیادی دارد.
Internet
│
X
│
┌─────────────────┐
│ Air-Gapped DC │
│ │
│ Harbor │
│ │ │
│ ▼ │
│ Kubernetes │
└─────────────────┘
در این معماری Imageهای موردنیاز میتوانند از طریق فرآیندهای کنترلشده وارد محیط شوند و سپس Kubernetes و سایر سرویسها فقط از Registry داخلی استفاده کنند.
Registry Mirror چیست؟
در برخی معماریها به جای اینکه تمام Serverها مستقیماً Imageهای موردنیاز خود را از Docker Hub یا Registry خارجی دریافت کنند، یک Registry داخلی به عنوان Mirror یا Cache در نظر گرفته میشود.
Docker Hub
│
▼
Registry Mirror
│
┌──────────┼──────────┐
▼ ▼ ▼
Node 1 Node 2 Node 3
این معماری میتواند باعث کاهش ترافیک Internet، افزایش سرعت Pull و کاهش وابستگی به سرویسهای خارجی شود.
در محیطهایی که تعداد زیادی Kubernetes Node یا CI Runner وجود دارد، این موضوع میتواند تأثیر قابل توجهی روی Network و زمان Deployment داشته باشد.
طراحی Container Registry برای محیط Production
راهاندازی یک Container Registry در محیط Development معمولاً ساده است، اما وقتی Registry وارد محیط Production میشود، باید آن را مانند هر سرویس زیرساختی مهم دیگری طراحی و مدیریت کرد.
Registry ممکن است محل نگهداری صدها یا هزاران Image مربوط به Applicationهای سازمان باشد و اختلال در آن میتواند مستقیماً روی فرآیندهای Deployment تأثیر بگذارد.
یک معماری Production معمولاً باید حداقل موارد زیر را در نظر بگیرد:
- High Availability
- Persistent Storage
- TLS
- Authentication و Authorization
- Backup
- Monitoring
- Logging
- Vulnerability Scanning
- Image Retention
- Disaster Recovery
Storage در Container Registry
Storage یکی از مهمترین بخشهای معماری Registry است؛ زیرا حجم Container Imageها میتواند به سرعت افزایش پیدا کند.
فرض کنید یک تیم ۲۰ Application دارد و هر Application به صورت میانگین ۱۰ Version مختلف از Image خود را نگهداری میکند. اگر حجم متوسط هر Image حدود 500MB باشد، خیلی سریع با چندین ده گیگابایت داده مواجه خواهیم شد.
در سازمانهای بزرگ این مقدار میتواند به صدها گیگابایت یا حتی چندین ترابایت برسد.
Local Storage
در سادهترین معماری، Imageها روی Local Disk همان Server ذخیره میشوند.
Registry
│
▼
Local Disk
│
├── Image Layers
├── Metadata
└── Artifacts
این روش ساده است اما برای معماریهای Highly Available محدودیتهایی دارد.
Network Storage
در برخی معماریها Storage روی یک Shared Storage قرار میگیرد.
Registry
│
▼
Shared Storage
│
┌────────┼────────┐
▼ ▼ ▼
Node 1 Node 2 Node 3
این روش امکان اجرای چند Instance از Registry را سادهتر میکند، البته باید Performance، Consistency و قابلیتهای Storage مورد استفاده نیز به دقت بررسی شوند.
Object Storage
برای Registryهای بزرگ، استفاده از Object Storage یکی از معماریهای بسیار مناسب است.
Registry
│
▼
Object Storage
│
┌──────────┼──────────┐
▼ ▼ ▼
S3 MinIO Cloud Object Storage
Object Storageهایی مانند S3 و MinIO میتوانند برای ذخیره Layerهای Image و Artifactها مورد استفاده قرار بگیرند.
این معماری مخصوصاً زمانی جذاب است که Registry باید در یک Private Cloud یا Data Center بزرگ اجرا شود.
High Availability برای Container Registry
اگر Registry فقط روی یک Server اجرا شود، همان Server به یک Single Point of Failure تبدیل خواهد شد.
Clients
│
▼
┌──────────┐
│ Registry │
│ Node 1 │
└────┬─────┘
│
Failure
│
X
در این حالت اگر Server از دسترس خارج شود، Kubernetes و CI/CD Pipelineهایی که به آن Registry وابسته هستند نیز ممکن است با مشکل مواجه شوند.
برای افزایش Availability میتوان چند Instance از Registry را پشت Load Balancer قرار داد.
Clients
│
▼
┌─────────────┐
│ Load Balancer│
└──────┬──────┘
│
┌────────┴────────┐
▼ ▼
┌────────────┐ ┌────────────┐
│ Registry 1 │ │ Registry 2 │
└──────┬─────┘ └──────┬─────┘
│ │
└────────┬────────┘
▼
Shared Storage
البته High Availability واقعی فقط با اضافه کردن دو Registry Instance ایجاد نمیشود و تمام Componentهای معماری، از Storage تا Database و Load Balancer، باید از نظر Availability بررسی شوند.
Load Balancer در مقابل Container Registry
قرار دادن Load Balancer جلوی Registry باعث میشود Clientها به جای اتصال مستقیم به یک Node، از یک Endpoint واحد استفاده کنند.
docker / Kubernetes / CI
│
▼
registry.example.com
│
▼
Load Balancer
│ │
▼ ▼
Registry 1 Registry 2
این Load Balancer میتواند با ابزارهایی مانند HAProxy، Nginx، Caddy یا Load Balancerهای Cloud پیادهسازی شود.
در محیطهای Enterprise بهتر است Health Check نیز فعال باشد تا در صورت Down شدن یکی از Registry Nodeها، Traffic به Node سالم منتقل شود.
Backup از Container Registry
یکی از اشتباهات رایج این است که چون Imageها از Source Code قابل Build هستند، نیازی به Backup Registry نداریم.
در واقع ممکن است Registry علاوه بر Container Image، شامل Artifactهای مهم، Configurationها، Metadata و Imageهای Release شدهای باشد که Rebuild کردن آنها همیشه ساده یا حتی ممکن نیست.
بنابراین Backup باید بخشی از طراحی Registry باشد.
چه چیزهایی باید Backup شوند؟
- Container Imageها
- Artifactها
- Metadata
- Database
- Registry Configuration
- Authentication Configuration
- Security Policyها
- Replication Configuration
در Harbor نیز باید علاوه بر Storage مربوط به Imageها، Componentهای مدیریتی و Database نیز در برنامه Backup و Disaster Recovery در نظر گرفته شوند.
Disaster Recovery برای Registry
در زیرساختهای حساس، داشتن Backup به تنهایی کافی نیست. باید مشخص باشد که در صورت از دست رفتن کامل Data Center چگونه Registry را دوباره راهاندازی خواهیم کرد.
Primary Data Center
│
│ Replication
▼
Secondary DC
│
▼
DR Registry
یکی از روشهای متداول، Replication Imageها به Registry موجود در یک Data Center دیگر است.
در این حالت اگر Data Center اصلی از دسترس خارج شود، کوبرنتیز و CI/CD میتوانند به Registry ثانویه متصل شوند.
Container Registry و Multi-Data Center
در سازمانهایی که چند Data Center دارند، میتوان برای هر Data Center یک Registry محلی در نظر گرفت.
CI/CD
│
▼
Primary Harbor
/ \
/ \
▼ ▼
Data Center 1 Data Center 2
Harbor Harbor
│ │
▼ ▼
Kubernetes Kubernetes
این معماری چند مزیت مهم دارد:
- کاهش Latency هنگام Pull کردن Image
- کاهش مصرف لینک بین Data Centerها
- افزایش Availability
- امکان Disaster Recovery
- کاهش وابستگی به یک Registry واحد
Monitoring برای Container Registry
Registry نیز مانند سایر سرویسهای زیرساختی باید Monitoring شود.
برخی Metricهای مهم عبارتاند از:
- CPU Usage
- Memory Usage
- Disk Usage
- Storage Growth
- HTTP Request Rate
- HTTP Error Rate
- Pull / Push Latency
- Failed Authentication
- Registry Availability
- Garbage Collection Duration
در معماریهای Kubernetes معمولاً میتوان Metricها را با Prometheus جمعآوری و در Grafana نمایش داد.
Container Registry
│
│ Metrics
▼
Prometheus
│
▼
Grafana
│
▼
Alerting
Logging و Audit در Registry
Monitoring به ما میگوید سیستم چه وضعیتی دارد، اما برای فهمیدن اینکه چه اتفاقی افتاده است، به Logging و Audit نیاز داریم.
برای مثال ممکن است بخواهیم بدانیم:
- چه کسی یک Image را Push کرده است؟
- چه کسی Image را Delete کرده است؟
- چه کسی به یک Project دسترسی پیدا کرده است؟
- چه زمانی یک Authentication ناموفق رخ داده است؟
- کدام Image بیشترین Pull را داشته است؟
در محیطهای Enterprise این اطلاعات برای Security، Troubleshooting و Compliance اهمیت زیادی دارند.
Image Lifecycle Management
هر Image باید یک Lifecycle مشخص داشته باشد.
برای مثال:
Build
│
▼
Test
│
▼
Scan
│
▼
Registry
│
▼
Staging
│
▼
Production
│
▼
Retention
│
▼
Cleanup
بدون Lifecycle Management، Registry به مرور زمان پر از Imageهای قدیمی و غیرضروری میشود.
چرا استفاده از latest همیشه ایده خوبی نیست؟
Tag معروف latest برای شروع کار ساده و راحت است، اما در Production میتواند مشکلاتی ایجاد کند.
فرض کنید Deployment ما از این Image استفاده میکند:
registry.example.com/my-app:latest
امروز latest به Version 1.5 اشاره میکند و فردا Developer یک Image جدید Push میکند که Version 1.6
است.
در نتیجه مشخص نیست Pod جدید دقیقاً چه نسخهای را اجرا خواهد کرد.
روش بهتر استفاده از Versionهای مشخص است:
registry.example.com/my-app:1.5.0
registry.example.com/my-app:1.5.1
registry.example.com/my-app:1.6.0
حتی بهتر از آن، در Deploymentهای حساس میتوان از Digest استفاده کرد.
registry.example.com/my-app@sha256:abc123...
Best Practices برای Container Registry
برای داشتن یک Registry امن، پایدار و قابل مدیریت، رعایت چند اصل مهم توصیه میشود.
۱. همیشه از TLS استفاده کنید
Registry Production را روی HTTPS قرار دهید و از Certificate معتبر استفاده کنید.
۲. Authentication را فعال کنید
Registry نباید بدون کنترل دسترسی روی Internet یا Network داخلی قرار بگیرد.
۳. Push و Pull را از هم تفکیک کنید
هر User یا Service نباید الزاماً اجازه Push داشته باشد.
۴. از RBAC استفاده کنید
دسترسیها را بر اساس Project، Team و Role مدیریت کنید.
۵. Imageها را Scan کنید
قبل از Production Deployment، Imageها را از نظر Vulnerability بررسی کنید.
۶. Retention Policy تعریف کنید
Imageهای قدیمی و غیرضروری را به صورت کنترلشده پاکسازی کنید.
۷. از Backup غافل نشوید
برای Registry یک Backup و Disaster Recovery Strategy مشخص داشته باشید.
۸. Image Tagging استاندارد داشته باشید
از Versioning مشخص و قابل ردیابی استفاده کنید.
۹. Registry را Monitor کنید
Disk، Storage Growth، Error Rate، Latency و Availability را تحت نظر داشته باشید.
۱۰. Registry را مستقیماً روی Internet رها نکنید
در صورت نیاز به دسترسی خارجی، از Firewall، Reverse Proxy، TLS، Authentication و Access Policy مناسب استفاده کنید.
نمونه معماری پیشنهادی برای یک Private Cloud
برای یک سازمان متوسط یا بزرگ که Kubernetes و CI/CD را در یک Private Cloud اجرا میکند، میتوان معماری زیر را در نظر گرفت:
Developers
│
▼
GitLab / Git
│
▼
CI/CD Runners
│
Docker Build
│
▼
Image Scanning
│
▼
┌─────────────────┐
│ Harbor │
│ │
│ Registry │
│ RBAC │
│ Scanner │
│ Replication │
└────────┬────────┘
│
Object Storage
│
▼
Kubernetes
│
┌─────────┼─────────┐
▼ ▼ ▼
Node 1 Node 2 Node 3
در چنین معماریای GitLab مسئول Source Code و CI/CD است، Harbor وظیفه مدیریت Container Image و Artifactها را بر عهده دارد و Kubernetes محیط اجرای Applicationها است.
آیا هر سازمانی به Harbor نیاز دارد؟
خیر.
انتخاب Registry باید بر اساس نیاز واقعی Infrastructure انجام شود.
اگر فقط یک پروژه کوچک دارید و چند Image ساده نگهداری میکنید، یک Registry ساده میتواند کاملاً کافی باشد.
اما وقتی تعداد Applicationها، تیمها، Kubernetes Clusterها و Data Centerها افزایش پیدا میکند، قابلیتهایی مانند RBAC، Scanning، Replication، Audit و Retention اهمیت بیشتری پیدا میکنند.
به همین دلیل Harbor معمولاً زمانی ارزش خود را نشان میدهد که Container Registry به یک جزء مهم از معماری DevOps و Private Cloud تبدیل شده باشد.
جمعبندی
Container Registry یکی از اجزای پایهای معماریهای مدرن Container و Cloud Native است. Registry محل نگهداری و توزیع Docker Imageها و سایر Container Artifactها است و معمولاً بین فرآیند Build و محیط Deployment قرار میگیرد.
Docker Registry یک راهکار ساده و سبک برای ایجاد Registry است و زمانی که فقط به قابلیتهای پایه نیاز داریم میتواند انتخاب مناسبی باشد.
GitLab Container Registry برای تیمهایی که GitLab را به عنوان پلتفرم اصلی Source Code و CI/CD خود استفاده میکنند، مزیت Integration بسیار خوبی دارد.
در مقابل، Harbor یک راهکار کاملتر برای سازمانهایی است که به قابلیتهایی مانند RBAC، Vulnerability Scanning، Replication، Retention، Audit و مدیریت Enterprise-level Container Imageها نیاز دارند.
در یک زیرساخت Private Cloud و Kubernetes Production، Registry را نباید صرفاً یک Storage ساده در نظر گرفت. Registry بخشی از Software Supply Chain است و امنیت، Availability، Backup، Monitoring و Lifecycle Management آن مستقیماً روی فرآیند Software Delivery تأثیر میگذارد.
به طور خلاصه، اگر معماری شما شامل Docker + Kubernetes + CI/CD است، داشتن یک Container Registry استاندارد و امن تقریباً یک جزء ضروری از معماری محسوب میشود.
سوالات متداول
Container Registry چیست؟
Container Registry سرویسی برای ذخیره، مدیریت و توزیع Container Imageها است. Docker، Kubernetes و CI/CD Pipelineها میتوانند Imageها را در Registry Push یا از آن Pull کنند.
تفاوت Docker Registry و Docker Hub چیست؟
Docker Registry یک نرمافزار برای راهاندازی Registry است، در حالی که Docker Hub یک سرویس عمومی و مدیریتشده برای میزبانی Container Imageها است.
Harbor چیست؟
Harbor یک Container Registry متنباز و Enterprise-oriented است که علاوه بر ذخیره Image، قابلیتهایی مانند RBAC، Vulnerability Scanning، Replication، Retention و Audit را ارائه میدهد.
آیا Harbor رایگان است؟
Harbor یک پروژه Open Source است و میتوان آن را به صورت Self-hosted در زیرساخت سازمان اجرا کرد. هزینه اصلی معمولاً مربوط به Infrastructure، Storage، مدیریت و نگهداری آن است.
آیا GitLab خودش Container Registry دارد؟
بله. GitLab دارای Container Registry داخلی است که با Git Repository و CI/CD آن یکپارچه میشود.
برای Kubernetes بهتر است از چه Registry استفاده کنیم؟
برای محیطهای کوچک میتوان از Registryهای ساده استفاده کرد، اما در Kubernetes Production و Private Cloud، راهکارهایی مانند Harbor یا GitLab Container Registry معمولاً قابلیتهای مدیریتی و امنیتی بیشتری ارائه میکنند.
آیا Container Registry باید روی همان کلاستر کوبرنتیز باشد؟
الزامی نیست و در بسیاری از معماریها حتی بهتر است Registry به صورت مستقل از Kubernetes Cluster اجرا شود تا در صورت بروز مشکل در Cluster، Registry همچنان در دسترس باشد.
آیا میتوان Harbor را روی Kubernetes اجرا کرد؟
بله. Harbor میتواند در معماریهای کوبرنتیس نیز Deploy شود، اما انتخاب روش Deployment باید با توجه به Storage، Availability، Backup و پیچیدگی عملیاتی سازمان انجام شود.
آیا Docker Registry از کوبرنتیز پشتیبانی میکند؟
بله. Kubernetes برای Pull کردن Container Image به Registry خاصی وابسته نیست و میتواند از Registryهای سازگار با استاندارد OCI/Docker Registry استفاده کند.
آیا Container Registry فقط برای Docker Image است؟
خیر. Registryهای مدرن میتوانند علاوه بر Container Image، انواع Artifactهای مرتبط با Cloud Native و Software Supply Chain را نیز مدیریت کنند.
آیا استفاده از latest در Production مناسب است؟
معمولاً توصیه نمیشود. استفاده از Versionهای مشخص یا حتی Image Digest باعث میشود Deploymentها قابل پیشبینیتر و قابل ردیابیتر باشند.
آیا Container Registry نیاز به Backup دارد؟
بله. در محیطهای Production باید Imageها، Metadata، Database و Configurationهای مرتبط بر اساس معماری Registry در برنامه Backup و Disaster Recovery قرار بگیرند.
آیا میتوان Container Registry را روی MinIO قرار داد؟
بله. برخی Registryها و راهکارهایی مانند Harbor میتوانند از Object Storageهای سازگار با S3 برای ذخیره Imageها و Artifactها استفاده کنند. این معماری برای Private Cloudهای بزرگ میتواند گزینه مناسبی باشد.
تفاوت Image Tag و Image Digest چیست؟
Tag یک نام قابل تغییر برای اشاره به یک Version از Image است، اما Digest بر اساس محتوای Image تولید میشود و یک مرجع دقیقتر و Immutable برای همان Image فراهم میکند.
آیا Harbor برای یک پروژه کوچک مناسب است؟
از نظر فنی بله، اما ممکن است قابلیتها و پیچیدگی Harbor برای یک پروژه کوچک بیشتر از نیاز واقعی باشد. در چنین شرایطی یک Registry ساده یا Registry داخلی GitLab میتواند انتخاب منطقیتری باشد.
Container Registry چه نقشی در DevOps دارد؟
Registry معمولاً نقطه اتصال بین Build و Deployment است. CI/CD Image را Build و Push میکند و Kubernetes یا سایر محیطهای اجرای Container آن را Pull و اجرا میکنند.