نکته مهم: اگه از نود.جیاس برای وصل شدن به داکر میخوای استفاده بکنی بهتره قبل از اینکه به فکر استفاده مستقیم از API خود داکر باشی یه نگاهی به پکیج dockerode بندازی.
برای ایجاد یه سرویس تو داکر شما میتونی از طریق کامند لاین اقدام بکنی ولی اگه میخوای از RESTful API داکر استفاده بکنی باید اول یکسری تنظیماتی رو اانجام بدی و بعدش میتونی به اندپوینت /services/create یه درخواست POST بفرستی.
اجرای یه دستور هنگام ساختن کانتینر، اینجا باس دستوراتی میخوای تو کانتینرت اجرا بشه رو بزنی مثل npm i
آرگومان های کامندات رو تو این مورد ست میکنی.
مشخص کردن hostname کانتینری که ساخته میشه. اگه replica رو ۱۰ بزاری و hostname رو ست بکنی همشون hostname یکسانی میگیرند. وقتی hostname رو تو نتورک overlay مشخص میکنی، یه اتفاقی که میفته اینه:
دیگه سرویس ها همدیگه رو با نام هم میشناسن و نیازی نیست که بگی پورتش چیه. البته این رو وقتی ست میکنی باید به این موضوع هم توجه بکنی که hostname باید توی کل شبکه overlay تو unique باشه.
برای ست کردن متغیر های محیطی، اینجا جایی هست که باید اونا رو ست بکنی.
ست کردن Dir
اینجا میتونی دایرکتوری کاری (محل ذخیره تنظیمات و فایل های کانتینر) کانتینر رو مشخص بکنی. محلشون رو این پایین آورده ایم:
ست کردن سطح دسترسی کاربر. ما اینجا مشخص میکنیم که سطح دسترسی کاربر برای read و write چقدر هست. برای اینکه موضوع رو بهتر بفهمید میتونید فایل /etc/passwd رو cat کنید تا یه خروجی مشابه خروجی زیر رو بهتون نشون بده:
root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin _apt:x:100:65534::/nonexistent:/usr/sbin/nologin systemd-timesync:x:101:102:systemd Time ynchronization,,,:/run/systemd:/usr/sbin/nologin systemd-network:x:102:103:systemd Network anagement,,,:/run/systemd:/usr/sbin/nologin systemd-resolve:x:103:104:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin messagebus:x:104:110::/nonexistent:/usr/sbin/nologin dnsmasq:x:105:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin avahi-autoipd:x:106:113:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologin usbmux:x:107:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin rtkit:x:108:114:RealtimeKit,,,:/proc:/usr/sbin/nologin sshd:x:109:65534::/run/sshd:/usr/sbin/nologin pulse:x:110:118:PulseAudio daemon,,,:/var/run/pulse:/usr/sbin/nologin speech-dispatcher:x:111:29:Speech Dispatcher,,,:/var/run/speech-dispatcher:/bin/false avahi:x:112:120:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/usr/sbin/nologin saned:x:113:121::/var/lib/saned:/usr/sbin/nologin colord:x:114:122:colord colour management daemon,,,:/var/lib/colord:/usr/sbin/nologin hplip:x:115:7:HPLIP system user,,,:/var/run/hplip:/bin/false lightdm:x:116:123:Light Display Manager:/var/lib/lightdm:/bin/false mjbkhorasani:x:1000:1000:mjbkhorasani,,,:/home/mjbkhorasani:/bin/bash systemd-coredump:x:999:999:systemd Core Dumper:/:/sbin/nologin postgres:x:117:124:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash geoclue:x:118:126::/var/lib/geoclue:/usr/sbin/nologin _rpc:x:119:65534::/run/rpcbind:/usr/sbin/nologin statd:x:120:65534::/var/lib/nfs:/usr/sbin/nologin
وقتی شما یک سرویس جدید مثل postgres رو روی سیستم عاملتون نصب میکنید براش یه کاربر جدید ساخته میشه با سطح دسترسی مشخص. این سطح دسترسی سطح دسترسی کاربر root نیست و هر کاری نمیتونه و فقط در همون حوزه ای که براش تعریف شده میتونه وارد عمل بشه.
این بخث بیشتر به این موضوع بر میگرده که یه سرویس جدید که میای نصب میکنی نیاد به همه چی دسترسی داشته باشه. یجورایی بحث امنیت هست. برای دیتای بیشتر این article رو مطالعه بکن. تو اینجا عددی که اول نوشته میشه همون UID هست.
مشخص کردن گروه کاربری یوزری که برای اون سرویس ساخته میشه. این گروه کاربری مشخص کننده سطوح دسترسی اون یوزر است. فرضا سرویس داکری mysql میسازی و توش یه یوزر تعریف میشه به اسم mysql
همون طوری که میبینید وقتی داخل کانتینر exec کردم و فایل مربوطه رو cat کردم.
فکر میکنم اینجا میاد یه ترمینال میسازه.
نمیدونم
میاد دسترسی به فایل سیستم روت اون کانتینر رو readonly میکنه.
برای مونت کردن دو روش داریم:
مثلا تو روش NFS میای یه استوریج مرکزی رو پارتیشن بندی میکنی بعد یکی از اون پارتیشن ها رو به یه جایی مونت میکنی. یعنی میایم هارد رو تیکه تیکه میکنیم و بعد روش فایل سیستم میکشیم، بعدش میای همون مسیر مونت شده رو، به یه دایرکتوری تو کامپیوتر کلاینت مونت میکنی.
نکته: اگه اون volume وجود نداشته باشه میاد برات ایجادش میکنه.
یعنی یک بار، وقتی فایل سیستم روی هارد میکشی مونت میکنی و بار دیگر روی سیستم کلاینت هم مونت میکنی. جهت مطالعه بیشتر.
در این روش هم میتونی از NFS استفاده بکنی.
این بخش رو کامل نمیدونم
اینجی میایم target رو مشخص میکنیم. target همون مسیری هست که قراره فایل های پروژه توش نگهداری بشن و همین target هست که به volume مونت میشه. البته نکته قضیه اینه که نمیتونی کل / رو مونت بکنی.
/usr/share/nginx/html
اینجی میایم محل فیزیکی volume یا اسم volume ای که توی داکر ساختیم رو مشخص میکنیم که اگه مشخص نکنیم میاد طبق VolumeOptions برات یه volume میسازه و اسمشو هم یه چیز رندم میزاره.
اینجا هم نوع volume رو مشخص میکنیم. دو نوع volume و bind اینجا اومده
دو نوع دیگه volume اینان: tmpfs و npipe
کاربردشو نمیدونم ولی چیزی که مشخصه volume ای که به کانتینر میده رو readonly میکنه.
نمیدونم
اگه نوع volume رو bind بزاری اینجا تنظیمات بیشتری میتونی اعمال بکنی. ولی ما از نوع volume استفاده میکنیم، به همین خاطر به این بخش زیاد پرداخته نمیشه.
نمیدونم
تو این قسمت میای تنظیمات volume رو مشخص میکنی.
برای زمانی کاربرد داره که شما فرضا اول کانتینر/سرویس رو ساختی و حالا تو مسیر target یسری فایل داریم ولی بعد از یه مدتی میای بهش volume مونت کنی. حالا نمیخوای فایل/دایرکتوری هایی که توی target هستن توی volume کپی بشن. پس میای NoCopy رو true میکنی. رفرنس
نمیدونم
توی Name میایم driver رو مشخص میکنیم. مثلا local ،convoy ،flocker ،vieux/sshfs ،cio و ...
توی Options میایم آپشن هایی که اون درایور قبول میکنن رو بهش میدیم. مثلا اگه از cio استفاده میکنی میتونی توش اینا رو بزاری:
Options: { "capacity": "1", "type": "ssd", "iopsmin": "1000", "iopsmax": "2000" }
نمیدونم
نمیدونم.
مشخص کردن سیگنال ارسالی به سرویس وقتی که میخواد سرویس رو stop بکنه. البته هنوز درک نمیکنم وقتی که دستوری برای stop کردن سرویس های داکری نداریم کاربرد این بخش کجاست؟
CONT INT QUIT SIGHUP SIGKILL SIGSTOP SIGUSR1 STOP USR1
HUP KILL SIGCONT SIGINT SIGQUIT SIGTERM SIGUSR2 TERM USR2
مدت زمانی که صبر میشه قبل از kill کردن
...
فهماندن resolver داخلی. یعنی کانتینر ها بتونن از طریق اسم همدیگه رو ping بکنن.
تو اینجا resolver کل سیستم رو مشخص میکنیم. اینجی یا cloudflare استفاده میکنیم یا از DNS server داخلی.
فرض کن یه ssh-key تولید میکنی و میخوای اونو به صورت امن اینور و اونور بکنی تو بستر شبکهی داکری. پس میای یه secret تو داکر create میکنی.
این هم یه آموزش برای ساخت secret
این هم یه آموزش برای تولید ssh key
فعلا نمیدونیم
نمیدونم. مقدار Container ID رو میگیره.
این جا میتونی ریسورس رو مشخص بکنی
اینجا میای limit رو مشخص میکنی
نمیدونم
تنظیم کردن راه اندازی مجدد
تو اینجا میایم مشخص میکنیم که کانتینر های سرویس روی کدوم نود سوار بشه.
نمیدونم
نمیدونم
نمیدونم
اینجا میایم تنظیمات نتورک سرویس رو مشخص میکنیم. آرایهای از آبجکت ها میگیره.
اینجا میایم تعداد replica ها رو مشخص میکنیم تو مد Replicated.
تنظیم کردن نحوهی آپدیت سرویس که تنظیماتش ایناس:
تو اینجا میای تنظیمات rollback رو مشخص میکنی
این Networks قبلا تو TaskTemplate هم اومده بود. اینجی چکار میکنه؟ چه فرقی با اون داره؟ همونه یا نه؟
اینجی میای پورت رو مشخص میکنی. سه تا بخش داره:
sample json:
{ "Name": "sub.test.ir", "Labels": { "foo": "bar" }, "TaskTemplate": { "ContainerSpec": { "Image": "nginx:1.15.9", "Command": [""], "Args": [""], "Hostname": "" "Env": [ "TEST1=1", "TEST2=2" ], "Dir": "/usr/share/nginx/html", "User": "33", "Groups": "33", "TTY": "?", "OpenStdin": "?", "ReadOnly": "?", "Mounts": [ { "ReadOnly": true, "Source": "web-data", "Target": "/usr/share/nginx/html", "Type": "volume", "LogDriver": { "Name": "json-file", "Options": { "max-file": "3", "max-size": "10M" } }, "VolumeOptions": { "DriverConfig": {}, "Labels": { "com.example.something": "something-value" } } } ], "StopSignal": "", "StopGracePeriod": 123, "HealthCheck": [ { "comming soon": "" } ], "Hosts": [ "10.10.10.10 host1", "ABCD:EF01:2345:6789:ABCD:EF01:2345:6789 host2" ], "DNSConfig": { "Nameservers": [ "8.8.8.8" ], "Search": [ "example.org" ], "Options": [ "timeout:3" ] }, "Secrets": [ { "File": { "Name": "www.example.org.key", "UID": "33", "GID": "33", "Mode": 384 }, "SecretID": "fpjqlhnwb19zds35k8wn80lq9", "SecretName": "example_org_domain_key" } ] }, "NetworkAttachmentSpec": "", "Resources": { "Limits": { "NanoCPUs": "30000000", "MemoryBytes": 104857600 }, "Reservations": {} }, "RestartPolicy": { "Condition": "on-failure", "Delay": 10000000000, "MaxAttempts": 10 }, "Placement": {}, "ForceUpdate": 123, "Runtime": "", "Networks": [ { "Target": "network name or id", "Aliases": ["service name in docker network"] } ], "LogDriver": { "Name": "json-file", "Options": { "max-file": "3", "max-size": "10M" } } }, "Mode": { "Replicated": { "Replicas": 1 } }, "UpdateConfig": { "Parallelism": 1, "Delay": 1000000000, "FailureAction": "rollback", "Monitor": 15000000000, "MaxFailureRatio": 0.15 }, "RollbackConfig": { "Parallelism": 1, "Delay": 1000000000, "FailureAction": "rollback", "Monitor": 15000000000, "MaxFailureRatio": 0.15 }, "EndpointSpec": { "Ports": [ { "Protocol": "tcp", "PublishedPort": 8080, "TargetPort": 80 } ] } }
نکته: همه سرویس های دیتابیسی بهتره روی یک نود مشخص ساخته بشن. چرا که برای وصل شدن بهشون راحت تر هستیم و مدیریت آنها ساده میشود. توجه کنید که مهم نیست IP کدوم نود رو میدهی چرا که حتی اگر IP یک نودی را بدهید که سرویس روی آن نیست (کانتینر روی آن ساخته نشده ولی manager هست) درخواست را سمت نودی ارسال میکند که کانتینر روی آن قرار دارد.