اگر دستی بر برنامهنویسی داشته باشید حتما تجربه کار با پروژههای مختلف رو هم تجربه کردهاید. پروژههایی که نیازمندیهای خاص خود را دارند و هرکدام پیشنیازهای نرمافزاری خود را دارند.
این پیشنیازها چه هستند؟
فضای لازم: برای مثال شما لازم دارید تا یک فضای مشخص برای اپلیکیشن خود ایجاد کنید تا دادهها در آن ذخیره شوند یا برنامهها فضای مشخصی از آن را اشغال کنند. همچنین احتمالا میخواهید این فضا محدودیتها و حد خاص خود را داشته باشد و بر دیگر فضاها دسترسی نداشته باشد.
برنامههای لازم: احتمالا این پروژهها نیازمند این هستند تا برنامههای مشخصی را از قبل در محیط خود نصب داشته باشند. مثلا اگه برای اجرای یک پروژه پایتون اقدام میکنید ممکن است که لازم داشته باشید تا پکیجهای پایتون توسط دستور pip یا به هر روش دیگری ذخیره شده باشند. یا اگر یک پروژه NodeJS مدنظر باشد ممکن است لازم باشد تا کتابخانههای مشخص شده در package.json نصب شده باشند.
محیط مشخص: ممکن است لازم داشته باشید تا محیطی که برنامه در آن اجرا میشود دستورهای مشخصی تعریف شده باشند یا تنظیمات خاصی فعال شده باشند.
محدودیت دسترسی: احتمالا بخواهید پروژه موردنظرتان فقط در محیط مشخصی که دسترسیهای مشخصی دارد فعال باشد و نتواند فراتر از آن تغییری ایجاد کند و مثلا در سطح سیستمعامل شما اثری بگذارد. یا پروژههای مختلفی در حال اجرا دارید که میخواهید هرکدام بر روی دیگری اثر نگذارند و در محیطی ایزوله در حال اجرا باشند.
اطلاعات لازم پروژه: همچنین شما علاوه بر تمامی مشخصات بیان شده نیاز دارید تا کد پروژه را نیز در محیط داشته باشید.
پس براساس اطلاعات بالا به طور خلاصه به محیطی نیاز داریم تا موارد زیر را با هم در قالب یک بسته داشته باشد:
دارا بودن این موارد در یک محیط ایزوله کمک میکند تا شما یک پروژه را در سطح سیستمعامل اجرا کنید و اجرای این پروژه در بیرون از سطح دسترسی آن اثری نداشته باشد. با این کار چندین پروژه میتوانند در یک سیستمعامل اجرا شوند که باتوجه به ایزوله بودن هرکدام محیطی ایدهآل شبیهسازی میشوند همانند اینکه یک معماری micro-service پیادهسازی شده باشند و ذخیره داده و انجام پردازشها و غیره در دیگر محیطها اثری نگذارد. مثلا با این کار شما در صورتی که دولوپر کلاینت باشید و بخواهید پروژه بکاند را اجرا کنید تنها لازم است تا محیط خاص بکاند را با دستوراتی ساده اجرا کنید و از آن استفاده کنید.
تمامی ویژگیهایی که در بالا بیان شد منجر به تولید مفهوم containerization , کانتینرها شد. به طور کلی میتوانیم تعریف زیر از container ها را داشته باشیم:
Container : is a standard unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another. A Docker container image is a lightweight, standalone, executable package of software that includes everything needed to run an application: code, runtime, system tools, system libraries and settings. ( از سایت docker )
مزایای containerization:
Consistent Environment:
کانتینرها به توسعه دهندگان این امکان را می دهند که محیط های قابل پیش بینی ایجاد کنند که از سایر برنامه ها جدا شده اند. کانتینرها همچنین می توانند شامل وابستگی های نرم افزاری مورد نیاز برنامه باشند، مانند نسخه های خاص زمان اجرا زبان برنامه نویسی و سایر کتابخانه های نرم افزار.
Runnable Virtually:
کانتینرها می توانند تقریباً در همه جا اجرا شوند و توسعه و استقرار را تا حد زیادی تسهیل می کنند: در سیستم عامل های لینوکس، ویندوز و مک. در ماشین های مجازی ؛ در ماشین توسعه دهنده یا در مراکز داده در محل؛ و البته در فضای ابری.
Isolation:
کانتینرها CPU، حافظه، ذخیره سازی و منابع شبکه را در سطح سیستم عامل مجازی می کنند و به توسعه دهندگان یک نمای سندباکس از سیستم عامل به طور منطقی ایزوله از سایر برنامه ها ارائه می دهند.
معایب containerization:
سرویسهای متعددی جهت ایجاد کانتینر ایجاد شده است.
در کنار ایجاد کانتینترها مسئلهای برای مدیریت این کانتینرها نیز ایجاد میشود. به این صورت که این کانتینرها به چه صورت در شبکه قرار بگیرند. یا چطور بتوانیم چندین کانتینر مشابه داشته باشیم تا در صورت پایین بودن یکی از دیگری بتوان استفاده کرد. برای حل این مسائل مفهوم container orchestration ایجاد شد. با کمک این راهحل ابزارهایی به وجود آمد تا بتواند مسائل زیر را بررسی کند:
Container’s lifecycle:
در ابتدا بگذارید یک تعریف از چرخه حیات داشته باشیم. چرخه حیات از همان ابتدا بالا آمدن یک کانتینر تا زمانی که کانتینر به کار خود خاتمه میدهد و دیگر از آن استفاده نمیشود گفته میشود.
چرخه حیات را میتوان شامل تمامی موارد زیر دانست:
یکی از وظایف container orchestration ها این است که این حالتها را مدیریت کند و در صورت بروز مشکل در هر حالت به حل آن بپردازند.
Provisioning:
به دلیل اینکه کانتینرها به وجود آمده و در طول حیات خود اطلاعات را ذخیره میکنند و نیز حذف میشوند دادههایی که دارند به اصطلاح ephemeral هستند که یعنی پس از اینکه کانتیر متوقف شود از بین میروند. یکی از مثالها برای این مورد مثل دادههایی هست که در stdout و به صورت لاگ منتشر میشوند. یکی از قابلیتهایی که orchestration ها میتوانند به کانتینرها بدهند این است که محیطی را در اختیار آنها قرار بدهند تا دادهها در آنها ذخیره شود و حتی پس از توقف کانتینر نیز بتوان به آن دسترسی داشت.
Deployment:
دیپلویمنت و بالا آوردن پروژه نیز از وظایف orchestration است تا بتواند به راحتی کانتینر را به محیط محصول وصل کند.
Scaling (up and down):
همانطور که گفته شد یکی از ویژگی کانتینرها فضای اختصاصی خود است. اما تمامی محصولات ممکن است روزی بزرگ و بزرگتر شوند و کاربران بیشتری را جذب کنند یا بالعکس از کاربران خود بکاهند و همین موارد باعث افزایش یا کاهش فضا و کانفیگهای کانتینر میشود. یکی از کارهایی که orchestration ها میتوانند بکنند این است که این فضاها را به راحتی برای کانتینر تغییر دهند.
Networking:
اتصال به شبکه نیز از کارهای این راهحل است. تا بتواند کانتینر بالا آمده را به شبکه اینترنت وصل کند، به آن ip مشخص بدهد، دامنههای آن را تعیین کند و غیره و غیره.
Load balancing:
از جمله کارهای دیگری که orchestration میتواند برای کانتینری که scale شده است انجام بدهد این است که چندین کانتینر مشابه بالا بیاورد و جهت اینکه درخواستها به یک کانتینر مشخص زیاد نشود درخواستها را بین کانتینرهای مختلف پخش کند. از جمله پیچیدگیای که این قسمت دارد نگهداری اطلاعات مشترکی که بین کانتینرها در اشتراک است میباشد.
ابزارهای متن باز برای containerization و container orchestration:
k8s (kubernetes):
این ابزار یکی از بهترین container orchestration های ممکن است که امکانات گستردهای را در اختیار قرار میدهد.
ابزار Kubernetes یک سیستم منبع باز قدرتمند است که در اصل توسط گوگل برای مدیریت برنامه های کاربردی کانتینری در یک محیط خوشه ای توسعه یافته است. ماموریت آن ارائه بهترین راه ممکن برای مدیریت اجزا و خدمات مرتبط و توزیع شده در طیف گسترده ای از زیرساخت ها است. هنگامی که برنامهها (سرویسهای میکرو) با وابستگیها و پیکربندیهایشان در یک کانتینر بستهبندی میشوند، ابزاری برای مدیریت خودکار کانتینرها و کوچکسازی آنها بر اساس الزامات دسترسی برنامه مورد نیاز است. Kubernetes ابزار عالی برای آن است.
باتوجه به اینکه مفاهیم این ابزار در بسیاری از ابعاد کاربرد دارد به توضیح برخی از این مفاهیم میپردازیم:
Container:
یک image اجرایی که شامل یک نرم افزار واحد و تمام وابستگی های آن است. در مورد ما، این یک ظرف Docker است.
Node:
یک ماشین مجازی یا فیزیکی که به عنوان کارگر برای Kubernetes استفاده می شود. Kubernetes مدیریت خود را در عمل انتزاع خواهد کرد. یک خوشه Kubernetes شامل یک گره اصلی است که برای مدیریت وضعیت خوشه در زمان واقعی استفاده می شود و امکان تعامل کاربر را فراهم می کند.
Cluster:
مجموعه ای از node ها که کانتینرهای مدیریت شده توسط Kubernetes را اجرا می کنند.
Pod:
کوچکترین شی k8s. یک pod مجموعه ای از کانتینرها را اجرا می کند. معمولاً، pod ها هر کدام یک کانتینر دارند، اما در برخی موارد، ممکن است شامل خدمات کانتینری اضافی مانند یکی برای افزودن قابلیت های ثبت گزارش نیز باشد.
Deployment:
یک object ای که مجموعه ای از pod های تکرار شده را مدیریت می کند. مقیاس پذیری یک میکروسرویس شامل افزودن pod های بیشتری به یک deployment است.
Service:
یک object که نحوه دسترسی به deploymentها یا گروههایی از پادها را از طریق یک نقطه پایانی مشترک توضیح میدهد. ممکن است چیزهایی مانند متعادل کننده بار برای دسترسی به منبع ایجاد کند.
Label:
اصطلاح label ها به اشیاء Kubernetes (پاد، deployment، services و غیره) اضافه می شوند تا با هم انتخاب شوند.
Selector:
یک selector به یک label ارجاع می دهد تا به عنوان مثال، امکان تعامل با مجموعه ای از اشیاء، مانند چندین کانتینر برای اهداف متعادل سازی بار را فراهم کند.
Kubectl:
ابزار command line که برای تعامل با node اصلی Kubernetes استفاده می شود.
منابع:
این مطلب، بخشی از تمرینهای درس معماری نرمافزار در دانشگاه شهیدبهشتی است