همه میدونیم image ها از لایه های متفاوت تشکیل میشوند به زبان دیگه image یه configuration object هست که شامل مجموعه ای از لایه ها و meatdata هست، دیتا یا همون اپ ما داخل این لایه ها هستند.
هر image و لایه با یه دونه ID منحصر به فرد شناسایی میشه که در image ها این hash شده از محتوای config اون و در داخل لایه ها hash شده از متحوای اون لایه هست پس در نتیجه در تغییر در محتوای image یا لایه های اون باعث میشه مقدار hash عوض بشه از این رو میشه فهمید که این image جدید هست!
حتی از این برای صحت سنجی محتوا داخل image استفاده میشه که مطمئن باشه image بدون تغییر رسیده(که این کم کم وارد بحث Docker Content Trust میشه ).
همه با کامند sub command ls داخل contaner ها یا image های docker cli اشنایم خب یسری وقتا هست ما رو docker lab خیلی چیز ها تست میکنیم container اجرا میکنیم یا image میسازیم و ... و اگر اینا خوب پیش نره lab ما کثیف میشه اینجا option های filter-- و formant-- به کمک ما میان
docker image ls --format "{{.Repository}}: {{.Tag}}" docker image ls --filter=reference="*:latest"
همین ها برای دستور contaner هم هست !
برای مثال با ترکیب اون با دستور rm می تونیم lab خودمون رو تمیز کنیم.
docker container rm $(docker container ls -aq) -f docker image rm $(docker image ls -q) -f
دقت کنید این دستور ها تمامی container ها و image ها رو پاک میکنه یه همین منظور می توانید از option filter-- برای موارد خاص استفاده کنید بجای اینکه تک تک حذف کنید.
بیشتر وقت ها وقتی ابزاری میگه از docker استفاده میکنه در بیشتر مواقع منظور Docker Engine هست و مسئول مدیریت و اجرا کردن contaner ها است .
در واقع docker engin به صورت modular طراحی شده و بیشتر ابزار ها یه بخش جدا و قابله جایگزین با ابزار هایی که دیگران یا خودتا نوشته اید هستند که همه ی این ها بر پایه استاندارد OCI (در بخش بعدی توضیح میدم).
قبل از این داکر monolithic طراحی شده بود و همه کد ها یجا بود docker api , docker client ,container runtime و ... بعد LXC به داکر تمام موارد لازم داخل kernel linux برای ساختن container ارائه میداد(مثلnamespaces و .. )
این موضوع متکی بودن به LXC مشکلاتی داشت (همون طور که میدونید LXC راه حلی بود برای بالا اوردن چند linux system روی یک kernel) از جمله داکر با هدف multi-platform اومد و از مشکلات دیگه این بود متکی بودن به یه ابزار خارجی برا هدف اصلی پروژه محدودیت های داشت در توسعه اون .
به مرور زمان مشکاتی دیگه هم از این قبیل نمایان شد تا تصمیم گرفتند داکر رو modularize کنند.
ظاهرا وقتی داکر اومد سریع رشد کرد و مردم مدام داشتن ازش استفاده میکردن، با این وضعیت عادی بود یکسری بخش ها ایراداتی هم داشته باشن بعد کمپانی به اسم CoreOS استاندرد های داکر رو دوست نداشت بنابر این خودش استانداردی به اسم appc و ابزاری مثل داکر درست کرد به که اسم اون شد rkt .
این داستان اکوسیستم کانتینر هارو تو وضعیت بدی قرار داد، استانداردهای متفاوت برا کانتینر ها.
رقابت خوبه اما نه سر استاندارد خلاصه کاربران در انتخاب بین استاندارد مشکل داشتند، گیج شده بودن و...
برای حل مشکلات بالا جمعی از بزرگان جمع شدند و استاندارد هایی کلی تعریف کردند که ابزار ها باید اونارو رعایت کنند و اینجوری بود که Open Container Initiative شکل گفت.
همون طور که میدونیم docer file شامل یکسری دستوره که درواقع یک image درست میکنه از app ما و ما با اون container درست میکنیم، همه docer file ها با دستورFROM شروع میشن که پایه image ما هست باقی دستور ها لایه هایی به image ما اضافه میکنند و تفاوت هایی دارند.
دستورات به دو دسته تقسیم میشوند یا یک لایه به image اضافه می کنند یا اطلاعاتی به image اضافه میکنه(metadata).
مثال اون هایی که لایه اضافه میکنند میشه گفت دستور COPY، RUN و ... و برای اون هایی که اطلاعاتی به image اضافه میکنند ENTRYPOINT، EXPOSE، LABEL و ....
بله اما رسما اسمش به Moby عوض شد تو سال ۲۰۱۷ و هدفشون این بود دست بالاترو نصبت به داکر داشته باشه و داکر رو به ماژول ها بیشتری بشکنن، پروژه روی github موجوده https://github.com/moby و شما می تونید دانلود کنید مشارکت داشته باشین و ... (Apache License 2.03).
همون طوری که می دونیم docker file برای ساخت app ما مجبوره یسری ابزار نصب کنه برای build پروژه ما، نصب dependency ها و در اخر run کردنش و هر کدوم از این برای نصب یک لایه به image اضافه کرده و حجم image زیاد میشه.
راه حله بهینه اینه که ما از چند stage استفاده کنیم (در واقع از چند دستور from) و یک stage رو به عنوان builder که تمام ابزار ها نصب و app ما اونجا build میشه در مرحله بعد ما stage قبلی دیتا های مورد نیاز (نه همه ابزار ها یا لایه ها یا دیتا ها) استفاده میکنیم تا app رو بیاریم بالا و اینجوری حجم image اصلی ما کاهش پیدا میکنه نسبت به اینکه همه نیاز مندی ها رو توی یک stage انجام بدیم و لایه های اضافه برای image داشته باشیم.
داکر به غیر از مواردی که خودش برای امنیت داره از فناوری های اصلی لینوکس برای امنیت هم پشتیبانی میکنه.
هدف داکر برای پیکربندی مواردی مربوط به امنیت اینه که ساده باشن، چون اگر سخت باشه یسرها پشت گوش می اندازند و یه مقدار پیشفرضی برای هر مورد درنظر گرفته شده یعنی شما بدون هیچ تلاشی حدی از امنیتش رو داری.
1) Namespaces :
فضاهای نام kernel در قلب کانتینرها قرار دارند! اونا به ما اجازه می دهند یک سیستم عامل را به گونه ای از هم جدا کنیم که مانند چندین سیستم عامل ایزوله به نظر برسند.
2) control groups:
در مورد تعیین محدودیت هستند،چیزهایی مانند CPU، RAM و I/O دیسک . Cgroups به ما اجازه می دهند محدودیت هایی را برای هر یک از اینها تعیین کنیم تا یک کانتینر نتواند از تمام CPU، RAM یا ورودی/خروجی ذخیره سازی هاست استفاده کند.
3) capabilities:
ایده بدیه که container ها رو به صورت root اجرا کنیم - root بسیار قدرتمنده و بنابراین بسیار خطرناک است. اما، اما اجرا بدون root محدویت های زیادی پشت container داره، که عملاً بی فایده است.
چیزی که ما به اون نیاز داریم، فناوری است که به ما امکان میدهد انتخاب کنیم که container های ما چه دسترسی های root برای اجرا نیاز دارند.
4) mandatory access control:
منابع را بر اساس سیاستهای امنیتی مرکزی و سختگیرانه کنترل میکند. در این مدل، سیستم تعیین میکند که چه کسی میتواند به چه چیزی دسترسی داشته باشد.. در لینوکس، ابزارهایی مانند SELinux و AppArmor از MAC برای افزایش امنیت استفاده میکنند.
5) seccomp:
داکر از seccomp، در حالت فیلتر، برای محدود کردن syscalls که یک کانتینر میتواند به host’s kernel بسازد، استفاده میکند.
1) Swarm Mode:
این به شما امکان میده که چندین docker host رو cluster کنید و برنامه های خود را به روشی declarative deploy کنید. هر Swarm از managers و workers تشکیل شده است که می تونن لینوکس یا ویندوز باشن. Managers کنترل cluster و مسئول پیکربندی cluster و ارسال کار به Worker ها هست. Worker ها node هایی هستند که کد برنامه شما را به عنوان کانتینر اجرا می کنند.
همون طوری که انتظار داریم این مود شام یسری features های امنیتی میشه از جمله:
• Cryptographic node IDs
• Mutual authentication via TLS
• Secure join tokens
• CA configuration with automatic certificate rotation
• Encrypted cluster store (config DB)
• Encrypted networks
2) Detecting vulnerabilities with Docker Security Scanning:
یه ابزاره برای شناسایی نفوذپذیری image های docker، یه اسکن تو سطح binary یک image انجام میده و نفوذ پذیری هایی رو که رفتارشون رو می تونه تشخیص بده با استفاده از CVE databases ( Common Vulnerabilities and Exposures نقص های امنیتی که به طور عمومی فاش شده است.) شناسایی میکنه.
3) Signing and verifying images with Docker Content Trust:
در سطح بالایی، DCT به توسعه دهندگان اجازه میده تا image های خودشون رو هنگام push به Docker Hub یا هر Docker Trusted Registry امضا کنند. همچنین هنگامی که image ها pull می شوند، به طور خودکار تأیید می کند.
4) Docker Secrets:
قبل از داکر ۱.۱۳ استانداردی نبود و توسعه دهنده ها Secret های مورد نیاز خود را داخل یه فایل متنی(environment variables) دخیر میکردن اما بعد از این نسخه با دستور docker secret می تونیم secret های مورد نیاز سرویس های خودمون رو بسازیم و مدیریت کنیم.
اجرای کانتینرهایی با restart policie اغلب ایده خوبی است. این یه نوع خوددرمانی است که داکر تا را قادر میسازه تا پس از رخ دادن events یا failures خاص، container ها را بهطور خودکار restart کند.
سه نوع restart policies وجود داره:
• always
ساده ترین است همیشه یک کانتینر متوقف شده را مجددا راه اندازی می کند مگر اینکه به صراحت متوقف شده باشد.
• unless-stopped
در صورتی که کانتینر در حالت توقف (خروج) باشد، هنگام راه اندازی مجدد دیمون، راه اندازی مجدد نخواهد شد.
• on-failed
یک کانتینر تنها در صورتی به طور خودکار راه اندازی مجدد می شود که با کد خروج غیر صفر خارج شود
یک container نمی تونه بدون process در حال اجرا وجود داشته باشه، مثلا اگر دقت کرده باشین وقتی یه image alpin ران می کنید
docker container run --name test -it alpine /bin/sh
اگر داخل اون Processes هاشو چک کنید
بعد اگر کامند exit رو بزنید بعد docker container ls می بیند که این container در حالت run نیست این یعنی شما هنگام exit کردن processe اصلی رو که pid اون 1 هست (که در همه container ها همینه )رو kill کردین و container جایی دیگه run نیست، اما اگر بجا کامند exit کلید Ctrl-PQ را فشار دهید از container خارج شده اما بدون kill کردن processe اصلی، دوباره docker container ls رو بزنید متوجه میشین که container همچنان در حالت اجرا ست.