راه اندازی private registry در داکر

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

ساده‌ترین کار اینه که ایمیج‌های مورد استفادمون رو روی فلش یا حافظه سیستم نگهداری کنیم، تا هر وقت که خواستیم ازشون استفاده کنیم. این‌کار فقط ساده‌ترین راهه نه بهترین راه، چون اگر تعداد سیستم ها زیاد باشه باید یکسری فرایند دستی رو برای کپی کردن ایمیج ها روی سیستم لوکال انجام بدیم:(

برا اینکه از همه این سختی ها نجات پیدا کنیم، یکبار راه اندازی private registry رو انجام میدیم و زندگی شیرین میشه.

با این رجیستری خیلی راحت میتونیم ایمیج هارو push/pull کنیم. حتی میتونیم ایمیج های اختصاصی‌مون رو روش قرار بدیم و ادرس رجیستری رو در اختیار مشتریانمون قرار بدیم)

خب شروع میکنیم:

فقط یه docker image به اسم registry:2 رو اجرا میکنیم و تموم!!!



حواستون باشه برای اولین بار حتما باید با وی پی ان متصل باشید تا بتونید ایمیج رو دانلود کنید.

docker run -d -p 5000:5000 registry:2

اینجا ما پورت پیش فرض ۵۰۰۰ رو مپ کردیم، که میتونیم تغییرش بدیم ( نکنید اینکارو بیکارید مگه)

مرحله بعدی قرار دادن docker image روی private registry‌مونه(من اینجا از ایمیج mysql که روی لوکال داشتم استفاده کردم)

دستور اول ایمیج mysql رو برای ریپازیتوری تگ میکنه و دومی هم ارسالش می‌کنه روی ریپازیتوری

docker tag mysql localhost:5000/mysql:1.0.0
docker push localhost:5000/mysql:1.0.0


تا اینجا ما یه private registry داریم، که یه ایمیج هم داخلش ذخیره کردیم. ولی این سرور فقط روی localhost کار می‌کنه، اگر بخوایم از یه سیستم بیرونی ایمیجی رو pull/push کنیم انجام نمیشه.

این اتفاق بخاطر اینه که docker daemon درخواست‌های بیرونی بدون TLS رو ریجکت می‌کنه.

ساخت یک Self Signed Certificate

این certificate ها برای احراز هویت به کار میره. که دو مدل داریم self signed و public تفاوتشون هم در اینه که، selfsigned certificate ها رو خودمون می‌سازیم، ولی هر کس که میخواد متصل بشه باید بهش یه public key بدیم. مورد دوم خریداری میشه و برای اتصال نیازی نیست که public key کپی بشه. بسته به نیازتون ممکنه از یکی از این روش ها استفاده کنید.

روش دیگه ای هم وجود داره که برای هر کس نام کاربری و کلمه عبور تعریف می‌کنیم، که آقای بهروزم توی این پست توضیح دادند

توی این پست، ما یه Self Signed Certificate روی سرورمون میسازیم و از اون برای Docker registry استفاده می‌کنیم. از طریق دستور openssl اینکارو انجام می‌دیم


mkdir registry_certs
openssl req -newkey rsa:4096 -nodes -sha256 \
-keyout registry_certs/domain.key -x509 -days 356 \
-out registry_certs/domain.cert

(طی مراحل ساخت certificate یکسری سوال میپرسه مثل

Country Name (2 letter code) [XX]

باید اسم اختصاری کشور(ir) رو بزنید.

ولی گزینه پایین که خیلی باید بهش دقت کنید، ادرس FQDN یا همون ادرس DNS ی که قرار از طریق اون به رجیستری متصل بشید رو باید وارد کنید. (مثلا من برای خودمو گذاشتم docker-repo.local )

Common Name (eg, your name or your server's hostname) []:

ما یک x509 certificate و private RSA key ساختیم که برامون دو تا فایل ایجاد کرد:

  • domain.cert - این فایل رو به کلاینت می‌دیم تا بتونه از ریپازیتوری استفاده کنه
  • domain.key - این فایل هم کلید خصوصیه و توی رجیستری قرار میگیره

راه اندازی private registry با certificate

(دقت کنید اگر docker run -d -p 5000:5000 registry:2 رو قبلا اجرا کردید باید با دستور docker rm کانتینری که ساخته شده رو حذف کنید)

docker run -d -p 5000:5000 \
-v $(pwd)/registry_certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.cert \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
--restart=always --name registry registry:2

برای اینکه از بیرون بهش وصل بشیم کافیه certificate رو توی کلاینت قرار بدیم

mkdir -p /etc/docker/certs.d/docker-repo.local:5000
cp domain.cert /etc/docker/certs.d/docker-repo.local:5000/ca.crt
service docker restart

در نظر داشته باشید توی قسمت <registry_address> باید ادرس hostname رجیستری سرور رو قرار بدیم. که میتونه پابلیک باشه مثلا www.example.com یا تو dns لوکال ست شده باشه.(برا من docker-repo.local) اگر ادرس پابلیک هست که نیازی نیست کاری انجام بدید ولی اگر مثل من یه ادرس من دراوردی گذاشتید باید فایل /etc/hosts ادرس ای پی private registry رو با این اسم معرفی کنید.

حالا میتونیم از یه کلاینت بیرونی هم ایمیج هارو pull/push کرد.

به جای <your server address> باید ادرس سرور خودتون بهمراه پورتی که براش تعریف کردید رو بزارید، بدون این دوتا <> مثلا برای من میشه(docker tag mysql docker-repo.local/proxy:registryserver)

docker tag mysql <your server address>/proxy:registry-server
docker push <your server address>:5000/proxy:registry-server

توی pull و push هاتون حتما دقت داشته باشید که تگ اضافه کنید.

جالبه که میتونیم برای این رجیستری یه frontend هم راه اندازی کنیم که از طریق یک container دیگه انجام میشه (ادرس سرور Docker-repo.local هستش)

docker run \
-d \
-e ENV_DOCKER_REGISTRY_HOST=docker-repo.local \
-e ENV_DOCKER_REGISTRY_PORT=5000 \
-e ENV_DOCKER_REGISTRY_USE_SSL=1 \
-p 0.0.0.0:80:80 \
konradkleine/docker-registry-frontend:v2
مجموعه این تحقیقات و ازمایش هایی که در ادامه مستند می‌کنم در شرکت پردازش هوشمند ترگمان مجری سامانه های ترجمه ماشینی ترگمان و ترجمیار انجام شده است.