داکر چیست: سفری کوتاه به تاریخ و انتزاعات اساسی

از 10 آگوست در اسلرم آغاز شد دوره ویدیویی داکر، که در آن ما آن را به طور کامل تجزیه و تحلیل می کنیم - از انتزاعات اساسی تا پارامترهای شبکه.

در این مقاله در مورد تاریخچه Docker و انتزاعات اصلی آن صحبت خواهیم کرد: Image, Cli, Dockerfile. این سخنرانی برای مبتدیان در نظر گرفته شده است، بنابراین بعید است که برای کاربران با تجربه جالب باشد. خون، آپاندیس یا غوطه ور شدن عمیق وجود نخواهد داشت. خیلی اصول.

داکر چیست: سفری کوتاه به تاریخ و انتزاعات اساسی

داکر چیست؟

بیایید به تعریف داکر از ویکی پدیا نگاه کنیم.

Docker نرم افزاری برای خودکارسازی استقرار و مدیریت برنامه ها در محیط های کانتینری است.

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

دوران یکپارچه

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

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

سیستم های مجازی سازی مبتنی بر Hypervisor

احتمالاً همه در مورد سیستم های مجازی سازی شنیده اند: VMware، VirtualBox، Hyper-V، Qemu KVM و غیره. آنها ایزوله سازی برنامه ها و مدیریت منابع را ارائه می دهند، اما معایبی نیز دارند. برای انجام مجازی سازی، به یک Hypervisor نیاز دارید. و هایپروایزر یک منبع سربار است. و خود ماشین مجازی معمولاً یک کلوسوس کامل است - یک تصویر سنگین حاوی یک سیستم عامل، Nginx، Apache، و احتمالا MySQL. تصویر بزرگ است و ماشین مجازی برای کار راحت نیست. در نتیجه، کار با ماشین های مجازی می تواند کند باشد. برای حل این مشکل، سیستم های مجازی سازی در سطح هسته ایجاد شدند.

سیستم های مجازی سازی در سطح هسته

مجازی سازی در سطح هسته توسط سیستم های OpenVZ، Systemd-nspawn، LXC پشتیبانی می شود. نمونه بارز چنین مجازی سازی، LXC (ظروف لینوکس) است.

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

اساسا LXC کانتینرها را ایجاد می کند. تفاوت بین ماشین های مجازی و کانتینرها چیست؟

داکر چیست: سفری کوتاه به تاریخ و انتزاعات اساسی

کانتینر برای جداسازی فرآیندها مناسب نیست: آسیب‌پذیری‌هایی در سیستم‌های مجازی‌سازی در سطح هسته یافت می‌شوند که به آنها اجازه می‌دهد از کانتینر به میزبان فرار کنند. بنابراین، اگر نیاز به جداسازی چیزی دارید، بهتر است از ماشین مجازی استفاده کنید.

تفاوت بین مجازی سازی و کانتینری سازی را می توان در نمودار مشاهده کرد.
هایپروایزر سخت افزاری، هایپروایزر در بالای سیستم عامل و کانتینرها وجود دارد.

داکر چیست: سفری کوتاه به تاریخ و انتزاعات اساسی

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

هایپروایزرها به عنوان یک برنامه و کانتینرهایی وجود دارد که در ادامه در مورد آنها صحبت خواهیم کرد. سیستم های Containerization یک Hypervisor ندارند، اما یک Container Engine وجود دارد که کانتینرها را ایجاد و مدیریت می کند. این چیز سبک تر است، بنابراین به دلیل کار با هسته، سربار کمتری وجود دارد یا اصلاً وجود ندارد.

آنچه برای کانتینرسازی در سطح هسته استفاده می شود

فن‌آوری‌های اصلی که به شما امکان می‌دهند یک ظرف جدا شده از سایر فرآیندها ایجاد کنید، فضاهای نام و گروه‌های کنترل هستند.

فضاهای نام: PID، Networking، Mount و User. موارد بیشتری وجود دارد، اما برای سهولت درک، ما روی آنها تمرکز خواهیم کرد.

فضای نام PID فرآیندها را محدود می کند. وقتی مثلاً یک فضای نام PID ایجاد می کنیم و یک پردازش را در آنجا قرار می دهیم، تبدیل به PID 1 می شود. معمولاً در سیستم ها PID 1 سیستمی یا init است. بر این اساس، وقتی فرآیندی را در فضای نام جدید قرار می دهیم، PID 1 را نیز دریافت می کند.

فضای نام شبکه به شما امکان می دهد شبکه را محدود/منزوی کنید و رابط های خود را در آن قرار دهید. Mount یک محدودیت سیستم فایل است. کاربر - محدودیت برای کاربران.

گروه های کنترل: حافظه، CPU، IOPS، شبکه - در مجموع حدود 12 تنظیمات. در غیر این صورت به آنها Cgroups ("گروه های C") نیز می گویند.

گروه های کنترل منابع یک کانتینر را مدیریت می کنند. از طریق گروه های کنترل می توان گفت که کانتینر نباید بیش از مقدار معینی از منابع را مصرف کند.

برای اینکه کانتینری‌سازی به طور کامل کار کند، از فناوری‌های اضافی استفاده می‌شود: قابلیت‌ها، کپی روی نوشتن و موارد دیگر.

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

سیستم Copy-on-Write به ما این امکان را می دهد که با تصاویر Docker کار کنیم و از آنها به طور موثرتری استفاده کنیم.

Docker در حال حاضر مشکلات سازگاری با Cgroups v2 دارد، بنابراین این مقاله به طور خاص بر Cgroups v1 تمرکز دارد.

اما بیایید به تاریخ برگردیم.

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

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

برای حل همه این مشکلات، دوره بعدی فرا رسیده است.

دوران کانتینر

وقتی عصر کانتینرها فرا رسید، فلسفه کار با آنها تغییر کرد:

  • یک فرآیند - یک ظرف.
  • ما تمام وابستگی‌های مورد نیاز فرآیند را به ظرف آن تحویل می‌دهیم. این نیاز به برش یکپارچه ها به میکروسرویس ها دارد.
  • هرچه تصویر کوچکتر باشد، بهتر است - آسیب پذیری های احتمالی کمتری وجود دارد، سریعتر منتشر می شود و غیره.
  • نمونه ها زودگذر می شوند.

به یاد دارید در مورد حیوانات خانگی در مقابل گاو چه گفتم؟ قبلاً مصادیق مانند حیوانات اهلی بودند، اما اکنون مانند گاو شده اند. پیش از این، یکپارچه وجود داشت - یک برنامه. اکنون 100 میکروسرویس، 100 کانتینر است. برخی از ظروف ممکن است 2-3 ماکت داشته باشند. کنترل هر ظرف برای ما کم اهمیت می شود. آنچه برای ما مهمتر است، در دسترس بودن خود سرویس است: این مجموعه کانتینر چه کاری انجام می دهد. این رویکردها را برای نظارت تغییر می دهد.

در 2014-2015، Docker شکوفا شد - فناوری که اکنون در مورد آن صحبت خواهیم کرد.

Docker فلسفه و بسته بندی برنامه استاندارد را تغییر داد. با استفاده از داکر، می‌توانیم یک برنامه را بسته‌بندی کنیم، آن را به یک مخزن ارسال کنیم، آن را از آنجا دانلود کرده و آن را مستقر کنیم.

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

انحراف در مورد سربار

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

از طرف دیگر، اگر عمیق تر بروید، در واقع چندین چیز در Docker وجود دارد که با کشش، می توان گفت که سربار هستند.

اولین مورد فضای نام PID است. وقتی فرآیندی را در فضای نامی قرار می دهیم، PID 1 به آن اختصاص می یابد. در عین حال، این فرآیند دارای PID دیگری است که در فضای نام میزبان، خارج از ظرف قرار دارد. به عنوان مثال، ما Nginx را در یک کانتینر راه اندازی کردیم، آن را به PID 1 (پروسس اصلی) تبدیل کردیم. و در هاست دارای PID 12623 است. و به سختی می توان گفت که چقدر سربار است.

مورد دوم Cgroups است. بیایید Cgroups را با حافظه بگیریم، یعنی توانایی محدود کردن حافظه یک ظرف. هنگامی که فعال می شود، شمارنده ها و حسابداری حافظه فعال می شوند: هسته باید بفهمد که چند صفحه اختصاص داده شده است و چه تعداد هنوز برای این کانتینر رایگان است. این احتمالاً یک سربار است، اما من هیچ مطالعه دقیقی در مورد چگونگی تأثیر آن بر عملکرد ندیده‌ام. و من خودم متوجه نشدم که برنامه در حال اجرا در Docker ناگهان با کاهش شدید عملکرد روبرو شد.

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

درباره مفهوم داکر

داکر از چندین جزء تشکیل شده است:

  1. Docker Daemon همان Container Engine است. کانتینرها را راه اندازی می کند.
  2. Docker CII یک ابزار مدیریت Docker است.
  3. Dockerfile - دستورالعمل هایی در مورد نحوه ساخت یک تصویر.
  4. تصویر - تصویری که ظرف از آن بیرون می‌آید.
  5. کانتینر
  6. رجیستری داکر یک مخزن تصویر است.

از نظر شماتیک چیزی شبیه این به نظر می رسد:

داکر چیست: سفری کوتاه به تاریخ و انتزاعات اساسی

داکر دیمون روی Docker_host اجرا می شود و کانتینرها را راه اندازی می کند. یک کلاینت وجود دارد که دستوراتی را ارسال می کند: تصویر را بسازید، تصویر را دانلود کنید، کانتینر را راه اندازی کنید. داکر دیمون به رجیستری رفته و آنها را اجرا می کند. کلاینت Docker می تواند به صورت محلی (به سوکت یونیکس) و از طریق TCP از یک میزبان راه دور دسترسی داشته باشد.

بیایید هر جزء را مرور کنیم.

داکر دیمون - این قسمت سرور است، روی ماشین میزبان کار می کند: تصاویر را دانلود می کند و کانتینرها را از آنها راه اندازی می کند، شبکه ای بین کانتینرها ایجاد می کند، سیاهه ها را جمع آوری می کند. وقتی می گوییم "تصویر بسازید"، شیطان نیز این کار را انجام می دهد.

داکر CLI - بخش مشتری Docker، ابزار کنسول برای کار با دیمون. تکرار می کنم، می تواند نه تنها به صورت محلی، بلکه از طریق شبکه نیز کار کند.

دستورات پایه:

docker ps - نشان دادن کانتینرهایی که در حال حاضر در میزبان Docker در حال اجرا هستند.
تصاویر docker - تصاویر دانلود شده به صورت محلی را نشان می دهد.
docker search <> - یک تصویر را در رجیستری جستجو کنید.
docker pull <> - یک تصویر را از رجیستری در دستگاه دانلود کنید.
ساخت داکر < > - تصویر را جمع آوری کنید.
docker run <> - کانتینر را راه اندازی کنید.
docker rm <> - ظرف را بردارید.
لاگ های docker <> - سیاهههای مربوط به کانتینر
docker start/stop/restart <> - کار با ظرف

اگر به این دستورات تسلط دارید و در استفاده از آنها مطمئن هستید، خود را 70% در Docker در سطح کاربر مسلط بدانید.

dockerfile - دستورالعمل برای ایجاد یک تصویر. تقریباً هر دستور دستوری یک لایه جدید است. بیایید به یک مثال نگاه کنیم.

داکر چیست: سفری کوتاه به تاریخ و انتزاعات اساسی

این چیزی است که Dockerfile به نظر می رسد: دستورات در سمت چپ، آرگومان ها در سمت راست. هر دستوری که در اینجا وجود دارد (و به طور کلی در Dockerfile نوشته شده است) یک لایه جدید در Image ایجاد می کند.

حتی با نگاه کردن به سمت چپ، تقریباً می توانید متوجه شوید که چه اتفاقی می افتد. ما می گوییم: "یک پوشه برای ما ایجاد کنید" - این یک لایه است. "Make the folder working" لایه دیگری است و غیره. کیک لایه ای زندگی را آسان تر می کند. اگر Dockerfile دیگری ایجاد کنم و چیزی را در آخرین خط تغییر دهم - چیزی غیر از "python" "main.py" را اجرا کنم، یا وابستگی‌هایی را از فایل دیگری نصب کنم - لایه‌های قبلی دوباره به‌عنوان یک کش استفاده می‌شوند.

تصویر - این بسته بندی ظرف است؛ ظروف از تصویر راه اندازی می شوند. اگر از دیدگاه یک مدیر بسته به Docker نگاه کنیم (انگار با بسته‌های deb یا rpm کار می‌کنیم)، پس تصویر اساساً یک بسته rpm است. از طریق yum install می توانیم برنامه را نصب کنیم، آن را حذف کنیم، آن را در مخزن پیدا کرده و دانلود کنیم. اینجا هم تقریباً به همین صورت است: کانتینرها از تصویر راه‌اندازی می‌شوند، در رجیستری Docker ذخیره می‌شوند (شبیه به yum، در یک مخزن)، و هر تصویر دارای یک هش SHA-256، یک نام و یک برچسب است.

تصویر مطابق دستورالعمل های Dockerfile ساخته شده است. هر دستور از Dockerfile یک لایه جدید ایجاد می کند. لایه ها را می توان دوباره استفاده کرد.

رجیستری داکر یک مخزن تصویر داکر است. مشابه سیستم عامل، داکر دارای یک رجیستری استاندارد عمومی است - dockerhub. اما شما می توانید مخزن خود، رجیستری Docker خود را بسازید.

ظرف - آنچه از تصویر راه اندازی می شود. ما یک تصویر را طبق دستورالعمل های Dockerfile ساختیم، سپس آن را از این تصویر راه اندازی می کنیم. این کانتینر از ظروف دیگر جدا شده است و باید همه چیز لازم برای عملکرد برنامه را داشته باشد. در این مورد، یک ظرف - یک فرآیند. این اتفاق می افتد که شما باید دو فرآیند را انجام دهید، اما این تا حدودی بر خلاف ایدئولوژی Docker است.

نیاز "یک ظرف، یک فرآیند" به فضای نام PID مربوط می شود. هنگامی که یک فرآیند با PID 1 در فضای نام شروع می شود، اگر به طور ناگهانی بمیرد، کل ظرف نیز می میرد. اگر دو فرآیند در آنجا در حال اجرا باشد: یکی زنده و دیگری مرده، آنگاه ظرف همچنان به حیات خود ادامه خواهد داد. اما این یک سوال از بهترین روش ها است، ما در مورد آنها در مواد دیگر صحبت خواهیم کرد.

برای مطالعه جزئیات بیشتر ویژگی ها و برنامه کامل دوره، لطفاً لینک زیر را دنبال کنید:دوره ویدیویی داکر'.

نویسنده: مارسل ابرایف، مدیر معتبر Kubernetes، مهندس تمرین در Southbridge، سخنران و توسعه دهنده دوره های Slurm.

منبع: www.habr.com

اضافه کردن نظر