ساخت رجیستری شخصی برای Docker

داکر برای نگهداری ایمیج ها از مخزنی استفاده میکنه که در صورت انتشار عمومی ، میشه ایمیج های زیادی داشت ولی فقط یک ایمیج خصوصی در اختیار شما میگذاره. توی این پست توضیح میدم چطور رجیستری شخصی خودتون رو داشته باشید

ساخت رجیستری شخصی برای Docker

این مخزن پیشفرض که همان DockerHub نامیده میشه محل ذخیره دنیایی از ایمیج هاست که تمامشون به صورت عمومی منتشر شده ان. حساب های کاربری عادی 1 ایمیج خصوصی رایگان دارن و سازمان ها هم هیچ ایمیج خصوصی در اختیارشون قرار داده نشده. در صورتی که بخواید از چنین قابلیتی استفاده کنید باید هزینه اش رو هم پرداخت کنید

Screenshot_2020-07-10-Pricing-Plans---Docker-Hub

راه حل ؟

ساده ترین و بهترین راه اینه که یک Registry برای خودتون داشته باشید. این کار چند مزیت داره :

  • مدیریت همه چیز دست خودتونه
  • دیگه نگران حریم شخصی نیستید
  • از شر تحریم های Docker خلاص میشید
  • یه عالمه ترافیک اینترنت ذخیره میکنید :))
  • سرعت Pull/Push توی سازمان و شبکه محلی خیلی بیشتره

شروع کار

نصب و تنظیم Registry خیلی ساده است و دو راه وجود داره :

  • نصب با استفاده از کتابخانه به صورت سرویس
  • نصب با استفاده از داکر

تو این پست روش دوم رو توضیح میدم چون استفاده و تنظیم کردنش خیلی ساده تره و سرویس جداگانه ای هم به سیستم عامل اضافه نمی کنید. مدیریت کردنش هم راحت تره و میتونید بعدا از یک GUI خوب هم براش استفاده کنید

روش نصب

داکر Registry خودش رو به صورت متن باز منتشر کرده که ایمیج داکر اون هم موجوده.

The Docker Registry 2.0 implementation for storing and distributing Docker images

کار با این ایمیج بسیار ساده است و با نوشتن یک فایل compose و اجرای اون می تونید در کوتاه ترین زمان ممکن Registry شخصی خودتون رو داشته باشید.

قبل از اینکه ادامه بدیم باید در نظر داشته باشید که رجیستری شخصی هم نیاز به اعتبارسنجی داره. پس در ابتدا باید یک حساب کاربری برای رجیستری خودمون تعریف کنیم. جهت انجام این کار از basic auth و کتابخانه htpasswd استفاده می کنیم. ابتدا با دستور زیر htpasswd رو نصب می کنیم :

sudo apt install apache2-utils

حالا یک دایرکتوری خالی به نام auth برای ذخیره کردن فایل حساب های کاربری میسازیم

mkdir -p ~/docker-registry/auth && cd $_

با استفاده از htpasswd یک حساب کاربری با نام username می سازیم :

htpasswd -Bc registry.passwd username

نکته : برای ساخت حساب های کاربری بیشتر ، دستور بالا را بدون آرگومان c اجرا کنید.

حالا همه چیز آماده است و در کنار دایرکتوری auth فایل docker-compose.yml خودمون هم به این صورت میسازیم :

version: "3.7"

services:
  registry:
    image: registry:2
    container_name: registry-server
    restart: unless-stopped
    ports:
      - 5000:5000
      - 5001:5001
    volumes:
      - type: bind
        source: ./data/
        target: /var/lib/registry/
      - type: bind
        source: ./config.yml
        target: /etc/docker/registry/config.yml
      - type: bind
        source: ./auth
        target: /auth
    depends_on:
      - redis

  redis:
    image: redis:6.0.5-alpine
    container_name: registry-redis
    restart: unless-stopped
    volumes:
      - type: bind
        source: ./data-redis
        target: /data
  • در رجیستری میتونیم از Redis برای Cache استفاده کنیم. پس ایمیج مربوطه رو هم اضافه می کنیم
  • جهت تنظیم کردن رجیستری به فایل config.yml نیاز داریم که در ادامه در موردش توضیح میدم
  • از دایرکتوری های data و data-redis برای ذخیره سازی داده های رجیستری و ردیس استفاده می کنیم.
  • پورت پیشفرض رجیستری 5000 بوده و از پورت 5001 برای مباحث debug استفاده میشه

تنظیمات رجیستری

جهت اعمال تنظیمات دلخواه فایل config.yml رو به صورت زیر درست کنید :

version: 0.1
log:
  level: error
  formatter: text
  fields:
    service: registry
http:
  addr: 0.0.0.0:5000
  debug:
    addr: 0.0.0.0:5001
    prometheus:
      enabled: true
      path: /metrics
  headers:
    X-Content-Type-Options: [nosniff]
    Access-Control-Allow-Methods: ["HEAD", "GET", "OPTIONS", "DELETE"]
    Access-Control-Expose-Headers: ["Docker-Content-Digest"]
    Access-Control-Allow-Origin: ["*"]
    Access-Control-Allow-Credentials: [true]
    Access-Control-Allow-Headers: ["Authorization", "Accept"]
    Access-Control-Max-Age: [1728000]
storage:
  cache:
    blobdescriptor: redis
  filesystem:
    rootdirectory: /var/lib/registry
  delete:
    enabled: true
redis:
  addr: redis:6379
  db: 0
  dialtimeout: 10ms
  readtimeout: 10ms
  writetimeout: 10ms
  pool:
    maxidle: 16
    maxactive: 64
    idletimeout: 300s
auth:
  htpasswd:
    realm: Registry-Realm
    path: /auth/registry.passwd

کارایی اکثر گزینه ها مشخصه ولی موارد مهم رو توضیح میدم :

  • برای debug و metrics ها پورت 5001 رو تنظیم میکنیم و Prometheus هم فعال میکنیم
  • برای اینکه در آینده از GUI های مربوطه استفاده کنیم نیازه تا یکسری Header تنظیم کنیم. برای مثال جهت حذف ایمیج ها نیازه که متد Delete توسط رجیستری پذیرفته بشه
  • در قسمت storage محل ذخیره سازی ایمیج ها و قابلیت حذف رو تنظیم می کنیم
  • تنظیمات Redis رو اعمال می کنیم
  • در قسمت auth مسیر قرارگیری فایل حساب های کاربری رو تنظیم میکنم

جهت مشاهده لیست کامل تنظیمات به این آدرس مراجعه کنید

تا اینجا ساختار پوشه شما به این صورته :

|- auth\  
|-------\ registry.passwd  
|- data\  
|- data-redis\  
|- config.yml  
|- docker-compose.yml

حالا کافیه فایل compose رو اجرا کنیم تا رجیستری ما ساخته بشه

docker-compose up -d

استفاده

از اونجایی که رجیستری روی پورت 5000 اجرا شده با رفتن به مسیر زیر از صحت عملکردش مطمئن میشیم :

http://localhost:5000/v2/_catalog

مشاهده می کنید که از شما نام کاربری و رمز عبور به صورت basic auth درخواست میشه. پس از وارد کردن اطلاعات ، لیست ایمیج ها در قالب JSON به شما نشون داده میشه که خب مسلما در ابتدای کار این لیست خالیه.

حالا که رجیستری آماده شده می تونیم ازش برای ذخیره سازی ایمیج های شخصی خودمون استفاده کنیم.

وقتی شما یک ایمیج Push/Pull می کنید ، از آدرس ریجستری پیشفرض داکر یعنی docker.io استفاده میشه. پس مسلما Tag های هر ایمیج رو باید برای استفاده در رجیستری شخصی خودمون تغییر بدیم.

برای مثال ما ایمیج busybox رو دریافت میکنیم و اونو به رجیستری خودمون منتقل می کنیم

docker pull busybox:latest
docker tag ff88df13bb6c localhost:5000/busybox:v1

در مثال بالا ما ایمیج Busybox که از رجیستری رسمی داکر دریافت کرده بودیم رو مجدد Tag کردیم. توجه کنید که شما میتونید هر اسم یا نسخه دلخواه برای ایمیج مورد نظر تنظیم کنید ولی چون از رجیستری پیشفرض استفاده نمیکنید حتما باید از آدرس رجیستری در شروع نام Tag خود استفاده کنید.

localhost:5000/bu...

برای Push کردن ایمیج ابتدا نیازه تا از طریق CLI هم اعتبارسنجی خودمون رو انجام بدیم. برای این منظور از دستور زیر استفاده کنید :

docker login localhost:5000

با وارد کردن نام کاربری و کلمه عبور که در اولین مرحله ساختیم ، اعتبارسنجی انجام میشه و میتونیم ایمیج خودمون رو Push کنیم :

docker push localhost:5000/busybox:v1

حالا اگر مجددا به آدرس زیر مراجعه کنید ایمیج خودتون رو مشاهده می کنید

http://localhost:5000/v2/_catalog

به این صورت رجیستری شخصی شما ساخته شد و یاد گرفتیم که چطور ایمیج هامون رو به این رجیستری منتقل کنیم. توجه داشته باشید که ایمیج های ساخته شده توسط خودمون هم میتونیم به این رجیستری Push کنیم. فقط کافیه موقع ساخت ، از Tag مناسب استفاده کنیم :

docker build -t localhost:5000/<IMAGE_NAME>:<VERSINO> .
docker push localhost:5000/<IMAGE_NAME>:<VERSINO>

نکات مهم

1- این تنظیمات صرفا برای آموزش بود. در محیط Production اینطور عمل نکنید

2- حتما از یک Reverse Proxy مناسب استفاده کنید

3- برای رجیستری خودتون از SSL استفاده کرده و مجدد تنظیمات رو اعمال کنید. جهت اطلاعات بیشتر به این آدرس مراجعه کنید. در صورتی که از SSL استفاده نکنید ، رجیستری شما insecure شناخته میشه و باید به لیست رجیستری های مجاز اضافه بشه.

4- از اونجایی که Prometheus رو فعال کردید ، میتونید عملکرد رجیستری رو به راحتی مانیتور کنید

5- در محیط Production حتما از Notification ها استفاده کنید تا از رخداد های رجیستری خودتون مطلع بشید

6- در آینده می تونید از GUI های مناسبی برای مشاهده رجیستری و اطلاعات اون استفاده کنید. در پستی جداگانه این مورد رو توضیح میدم.


اگر سوال در مورد راه اندازی و استفاده رجیستری شخصی داکر داشتید ، با من در تماس باشید