رسیدیم به پست آخر گیتلب امیدوارم در آینده هم فرصت کنیم که بیشتر توی مباحث مربوط به CI/CD عمیق شیم. توی این پست اول یه سری از موارد دیگه از gitlab-ci.yml. که باقی مونده بود رو مرور میکنیم بعد در مورد وریبلهای گیتلب و فرآیندهای گیتآپس یه خرده توضیح میدم.
خب یه مروری کنیم پستهای قبلی رو:
توصیه میکنم که حتما این پستها رو هم مطالعه کنید. بریم که ادامه بدیم.
ادامهی موارد مربوط به gitlab-ci.yml:
retry:
با این گزینه مشخص میکنیم که رانر چندبار درصورت انجام نشدن یک جاب دوباره تلاش کنه که اون رو انجام بده و اگه تعریف نکنیم مقدار دیفالت برای تکرار صفر هست. این گزینه رو میتونیم با شرط های when هم ترکیب کنیم.
Parallel:
این گزینه بهمون کمک میکنه تا یک جاب رو چندبار انجام بدیم و برای انجامش باید چنتا رانر هم داشته باشیم یا اگه یک رانر داریم قابلیت انجام چند جاب به صورت موازی در اون فعال باشه.
timeout:
با استفاده از این قابلیت میتونیم برای جاب خودمون تایماوت بذاریم که در صورتی که از زمان تایماوت بیشتر داشت طول میکشید دیگه دیسش رو بده و جاب رو فیل کنه. یه نکتهای که در timeout وجود داره باید دقت کنیم که مقدار آن باید همواره از مقدار runner timeout کمتر باشه چون در این صورت با رسیدن زمان تایماوت رانر دیگه جاب ما را فیل میکند.
trigger:
با استفاده از تریگر میتونیم جاب یا بهتر بگم یه پایپلاین رو استارت بزنیم. این یکی از آیتمهای مهم برای نوشتن CI/CDها هست اینکه پایپلاین ما چطور استارت بشه. روشهای مختلفی براش وجود داره ولی به صورت کلی نرمال استفاده ما ازش به این صورت است که بخوایم یه پایپلاین دیگه رو اجرا کنیم مثلا مالتی پراجکت یا چایلد پرنت که خیلی پر کاربرد هستند. میتونیم با استفاده از api هم پایپلاینهای خودمون رو تریگر کنیم و آنها رو اجرا کنیم.
Variables:
با استفاده از این سینتکس میتونیم وریبل برای جاب، پایپلاین خودمون تعریف کنیم. تو گیتلب خیلی جاها هست که میتونیم وریبل تعریف کنیم که داخل فایل گیتلب سیآی یکی از آن موارد است که به راحتی میتونیم وریبل تعریف کنیم و ازش داخل جابهای خودمون استفاده کنیم.
When:
با استفاده از این کلیدواژه تعریف میکنیم که چه زمانی جاب باید انجام بشه که گزینه ای مختلف زیر رو داره و میتونید بسته به نیازی که دارید از اونها استفاده کنید. یه جورایی داریم کنترل میکنیم که این جاب ما چه زمانی اجرا شود.
on_success (default):
تو این حالت جاب تنها زمانی اجرا میشود که تمام جاب های استیج قبلی یا اونهایی که بهش این جاب وابسته است یا انجام شده باشند یا اینکه allow_failure: true داشته باشند.
manual:
جاب تنها زمانیکه به صورت دستی اون رو تریگر کنیم اجرا میشه. معمولا از این قابلیت ما برای زمانهای که میخواهیم تو پروداکشن دیپلوی کنیم استفاده میکنیم که استارت دیپلوی تو پروداکشن وابسته به اکشن ما میباشد.
always:
تو این حالت در هر صورت حتی اگه توی استیج قبل fail هم داشته باشیم این جاب اجرا میشود.
on_failure:
تنها درصورتی اجرا میشود که حداقل یک جاب در استیج قبلی fail شده باشد.
delayed:
تو این حالت زمان اجرای تسک رو برای زمان مشخص شده ای به تاخیر میاندازد.
never
تو این حالت جاب اجرا نمیشه که ازین گزینه توی rule های workflow میتونیم استفاده کنیم.
Workflow:
از ورکفلو برای کنترل رفتار پایپ لاین استفاده میکنیم مثلا ورکفلو چک میکنه که اگه جاب تگی رو داره که توی تگ های مجاز نیست، نمیذاره جاب ران بشه. همچنین میتونیم با استفاده از workflow: rules مواردی رو که میخوایم به صورت شرط برای ورکفلو تعریف کنیم.
Environments and Deployments:
به جایی که داریم اونجا دیپلوی میکنیم environments میگیم. یعنی جاهایی که داریم اونجاها دیپلوی میکنیم. مثلا stage یا production یا pre-production و … . پس به جایی که دیپلوی میکنیم environment میگیم و به مواردی که داخل environmentها ایجاد کردیم deployments میگیم. کلا مفهوم سادهای هست. اما چیزی که داره مهمش میکنه اینه که میتونیم برای محیطهای مختلف خود پنل داشته باشیم و یه جورایی به صورت کامل بهمون history میده و میتونیم rollout و rollback کنیم.
Job artifacts:
ببین به صورت کلی هیچ ارتباطی بین جابها وجود نداره. یعنی اینکه ما اگر بخواهیم یه فایلی رو از جاب یک ببریم به جاب دو نیاز داریم که از Artifacts استفاده کنیم. راه ارتباطی بین جابهای ما همین آرتیفکت هست. این دیدگاه اشتباه هست که ما فایلمون رو داخل رانر میگذاریم و جاب بعدی هم از همون جا بر میداره. شاید تو برخی از مدلهای رانر اونم اگر فقط یک رانر باشه امکانش باشه اما به صورت اصولی این کار اشتباه است و اصلا نباید به این صورت پیش رفت. روش درست اینکه که داخل جاب خودمون اون چیزی که میخواهیم منتقل بشه رو آرتیفکتش کنیم و در جاب بعدی خودمون ازش استفاده کنیم.
Dependencies:
با این سینتکس مشخص میکنیم که آرتیفکت کدوم جاب تو این جاب وارد بشه. چون آرتیفکتهای ما برای تمام جابهای پایپلاین در دسترس هست که با دیپندنسی داریم مشخص میکنیم که آرتیفکت کدوم جابها برای این جاب در دسترس باشه.
Caches:
معمولا ما جابهایی داریم که همواره یه سری استاتیک رو دانلود میکنند یا آنها رو نصب میکنند. برای همین بهینه هست که آنها رو کش کنیم و فقط یک بار بگیریم. سینتکس cache بهمون کمک میکنه که این موارد رو کش کنیم که به شدت تو سرعت پایپلاین ما میتونه موثر باشه.
Tags:
اگر بخواهیم یک جاب رو به یه رانر یا گروهی از رانرها وابسته کنیم میتونیم از tags استفاده کنیم. این قابلیت خوبی است که باهاش میتونیم رانرهای اختصاصی داشته باشیم. یه نکتهی دیگه اینکه داخل رانر هم میتونیم مشخص کنیم که به جز جابهایی که این تگ رو دارند جاب دیگهای اجرا نکند که خیلی کمک میکنه تا رانر اختصاصی داشته باشیم.
only / except:
اگر بخواهیم مشخص کنیم که این جاب ما در چه زمانی اجرا بشود یا نشود از این دو تا سینتکس استفاده میکنیم. مثلا اینکه هر زمانی که تو main پوش کرد یا اینکه اگر schedule بود این جاب اجرا نشود. به هر صورت به ما امکانی رو میده که بتونیم جاب خودمون رو مدیریت کنیم.
Extends:
این قابلیت رو به ما میده که بتونیم فایل gitlab-ci تمیزتری داشته باشیم. مواردی که زیاده و میخواهیم احتمالا تو برخی از جابها تکرار کنیم و داخل دیفالت هم نمیتونیم بزاریم رو میتونیم یه جا بنویسیم و بعد با این سینتکس آنها رو فراخوانی کنیم. این طوری خیلی فایلمون تمیزتر و خواناتر میشه. البته من خودم زیاد باهاش حال نمیکنم ولی به هر حال کمک میتونه بکنه.
Coverage:
با این سینتکس و مدلی که بهش میدیم میتونیم میزان کد کاورج تستمون رو مشخص کنیم. این کمک میکنه تا بعدا تو منوهایی گیتلب میزان کاورج تست روی کد خودمون رو ویژوالایز ببینیم که زیبا میشه.
Rules:
این سینتکس هم به ما کمک میکنه که مشخص کنیم در چه صورتی که این جاب اجرا بشه یا نشه. یه جورایی داریم کنترل میکنیم که چه زمانی این جاب اجرا بشه یا اگر چه اتفاقی افتاد این جاب اجرا نشه. این سینتکسها به ما کمک میکنند که کنترل بیشتری روی اوضاع داشته باشیم. کانفیگ و قوانین متعددی هم داره که توصیه میکنم حتما بخونید و بهش مراجعه کنید.
Release:
با استفاده از این سینتکس ما میتونیم یک release از کد خودمون ایجاد کنیم. کلی هم آپشن داره که خیلی این کار رو میتونه جذابش کنه.
Inherit:
این دستورالعمل بهمون کمک میکنه که ارثبری جابمون رو از وریبلهای سطح پایپلاین و سینتکس دیفالت کنترل کنیم. مثلا میتونیم بگیم که از دیفالت تبعیت نکنه. مثلا تو دیفالت نوشتیم که همه تو before_script داخل رجیستری لاگین کنند حالا یه جاب داریم که اصلا لازم نداره که تو رجیستری لاگین کنه و حتی کامند docker هم نداره برای همین با خطا مواجه میشه که با استفاده از این سینتکس میتونیم بهش بگیم که این جاب از دیفالت تبعیت نکنه.
Interruptible:
این سینتکس باحالی هست. معمولا ما زمانی که داریم تغییرات میدیم مواقعی پیش میاد که تعداد کامیتهای زیادی داریم. گاهی در حین اینکه داره پایپلاین اجرا میشه کامیت جدید داریم و ادامهی پایپلاین قبلی برامون ثمری نداره. تو این طور مواقع این سینتکس به کمکمون میاد که با کامیت جدید پایپلاین قبلی که در حال اجرا بود رو کنسل میکنه. به صورت پیشفرض هم false هست که میتونیم true کنیم. این شبیه کانفیگ Auto-cancel redundant pipelines است که میتونیم تو تنظیمات فعالش کنیم.
Manual_confirmation:
این برای زمانی که انتخاب کردیم when: manual باشه کارایی داره که یه مسیج به طرف نشون میده که حاجی داری چی رو تریگر میکنی. کمک میکنه که طرف سنس پیدا کنه که داره چی کار میکنه.
Resource_group:
ببین اینا فکر همهجاش رو کردن. با این سینتکس میتونیم یه کنترلی داشته باشیم که جابهایی که تو این گروه خاص که تعریف میکنیم هستند همزمان باهم اجرا نشن. این طوری یه مدیریت خوبی روی منابع میتونیم داشته باشیم و مثلا زمانی که داریم روی پروداکشن میزنیم چیزی دیگهای اجرا نشه تا این ریسورس گروه خالی بشه.
Identity:
با استفاده از این میتونیم برای احراض هویت از سرویسهای دیگه استفاده کنیم. مثلا از گوگل یا هر چی که بهمون این امکان رو میده.
Pages:
با استفاده از این سینتکس ما میتونیم از قابلیت pages گیتلب استفاده کنیم. با استفاده از این قابلیت میتونیم static siteها خودمون رو هاست کنیم. یه جورایی میتونیم آنها رو از کد و تو گیت نگهداری کنیم. به ازای هر پوش ما آنها تغییر کنند.
وریبل های گیتلب
یکی از مفاهیم مهم توی گیتلب وریبلها هستن اونها رو میتونیم جاهای مختلفی تعریف کنیم. یه سری وریبل از قبل تعریف شده خود گیتلب داره (Predefined variables) ، توی هر اینستنس CI/CD میشه وریبل تعریف کرد، به ازای گروههایی که توی گیتلب داریم میشه وریبل تعریف کرد، به ازای پروژههای گیتلب میشه وریبل تعریف کرد و توی فایل gitlab-ci.yml. هم میشه وریبل تعریف کرد. هر کدوم ازین موارد کاربرد خاص خودش رو داره و نسبت به هم یه اولویتی دارن که مثلا اگه یک وریبل رو توی چندجا مقدار دادیم کدوم یکی استفاده بشه. در ادامه لیستی از ترتیب اولویت جاهایی که وریبل تعریف شده رو براتون میذارم:
اگر وریبلی داریم که برامون خیلی مهمه و میخواهیم که مقدار آن برای دیگر افراد پروژه مشخص نشه میتونیم از وریبلهایی که داخل تنظیمات گیتلب ایجاد میکنیم استفاده کنیم. این طوری وقتیکه وریبلها رو به یه پروژه اضافه میکنیم معمولا فقط اعضایی که نقش Maintainer رو دارن میتونن تغییرات رو توی این قسمت ایجاد کنن. موقعی که از قسمت ستینگ گیتلب وارد بخش CI/CD میشیم میتونیم قسمت Variables رو ببینیم. برای اضافه کردن یک وریبل جدید موارد زیر رو داریم که به اختصار هرکدوم رو توضیح میدم:
Key:
کلید متغیر وریبل که باید توی یک خط بدون خط فاصله و تنها با استفاده از حروف و اعداد و _ اون رو تعریف کنیم.
Value:
مقدار وریبل که محدودیت خاصی توی این مورد نداریم معمولا.
Type:
نوع رو اینجا مشخص میکنیم که به صورت فایل هست یا وریبل.
Environment scope:
یه قابلیت بسیار زیبایی که گیتلب اینجا در اختیارمون میذاره این هست که میتونیم وریبل که تعریف میکنیم رو به ازای انوایرومنتهای مختلفمون بهش مقادیر مختلف بدیم و یا اینکه برای یه سری انوایرومنت خاص فقط تعریفش کنیم که خیلی این قابلیت خوبه و کمکمون میکنه که مثلا برای محیط پروداکشنمون وریبل های امن تر تعریف کنیم و یا متغیرهای محیط تست رو فقط برای همون محیط تعریف کنیم و کلی مورد کاربردی دیگه …
Protect variable Optional:
این گزینه به صورت آپشنال هست و با فعال کردن اون متغیر تنها برای پایپلاینهایی که توی برنچهای protected هستن یا تگ protected دارند در دسترس قرار میگیره.
Mask variable Optional:
این مورد هم به صورت آپشنال هست و با فعال کردن اون متغیر توی لاگ جابهای پایپلاین به صورت مسک شده نشون داده میشه و مقدارش توی لاگ جاب دیده نمیشه و جاهایی که موارد موردنیاز masking رو نداشته باشند امکان ذخیره شدن نخواهد داشت. با اینکه این مورد به صورت آپشنال هست اما توصیه میشه که همیشه اون رو برای پسوردها و وریبل های مهم دیگه فعال کنید.
انواع انوایرومنت در گیتلب:
به طور کلی دو نوع انوایرومنت توی گیتلب داریم. اولی محیطهای استاتیک هستن که اسم ثابت دارند مثل staging یا production. دومی هم محیط های داینامیک هستن که بخش پایه ای از Review apps محسوب میشن و اسم های متغیر دارند.
در حالت خودکار Review app که کاملا هم با لایف سایکل دواپس گیتلب سازگار هست در واقع به ازای هر چنج توی فیچرهای برنچ یک محیط داینامیک بالا میاره بعد از مرج ریکوئست که این امکان به دیزاینرهای محصول و پروداکت منجیرها میده که تغییرات رو ببینند بدون نیاز به بررسی تغییرات برنچ و ران کردن اونها توی محیط سندباکس.
نمونه ای از نحوه تعریف هر دو نوع انوایرومنت رو توی تصاویر زیر میتونید ببینید.
ریلیز گیتلب
ریلیز به ما این قابلیت رو میده که یه اسنپشات از پروژه رو برای یوزرها بگیریم و درکنارش پکیجهای نصبی و نکات مربوط به اون ریلیز رو اضافه کنیم. ریلیزهای گیتلب رو توی هر برنچی میتونیم ایجاد کنیم و با ساخت هر ریلیز یک تگ گیت برای مارک کردن اون نقطه سورس کد ایجاد میشه.
توضیح kaniko
کنیکو ابزاری هست که برای بیلد کردن ایمیج های داکر درون یک کانتینر یا کلاستر کوبرنتیز. کنیکو با استفاده از متد Docker-in-Docker build دوتا مساله رو برای ما حل میکنه:
مساله اول اینه که Dind به طور کلی رو پرفورمنس تاثیر میذاره و میتونه کاملا کند باشه که کنیکو به حل این مساله کمک میکنه.
مساله دوم هم اینه که چون توی Dind کانتینر قراره بتونه کانتیر بسازه پس دسترسی privileged داره برای کار کردن که میتونه به لحاظ امنیتی کاملا نقطه نگران کننده ای باشه که کنیکو توی حل این مساله هم بهمون کمک میکنه.
توضیح و بررسی Kubernetes agent
شما میتونید کلاستر کوبرنتیز خودتون رو به گیتلب متصل کنید برای انجام دیپلوی و مدیریت و مانیتور کردن اپلیکیشنهایی که دارید.
ایجنت گیتلب روی کلاستر کوبر ران میشه و میتونید در موارد زیر ازش استفاده کنید.
توضیح مفاهیم Gitops
بذارید انواع دیپلوی کردن اپلیکیشنها رو به دو دسته push based و pull based تقسیمبندی کنیم.
توی دسته اول یعنی push based ها به این صورت هست که مثلا ما بعد از انجام تستهامون یه کامیت رو میخوایم بفرستیم روی پروداکشن … مرج روی اون کامیت رو تایید میکنیم و بعد از اون فرآیندهای CI/CD ما که دسترسی به کوبرنتیز ما رو هم دارند فعال میشن و تغییرات جدید رو میبرن توی محیط پروداکشن دیپلوی میکنند. توی این حالت نیاز داریم که گیتلب ما هم به لحاظ نتورکی بتونه کلاستر کوبرنتیز یا پروداکشن ما رو ببینه و هم به لحاظ امنیتی دسترسی ایجاد تغییرات روی اون رو داشته باشه.
اما توی دسته دوم که pull based هست ما به کمک ابزاری مثل ArgoCD این امکان رو ایجاد میکنیم که کلاستر کوبرنتیز خودش تغییرات رو از روی گیت برداره و روی خودش دیپلوی کنه … از مزیت های این روش این هست که دیگه اکسس به کلاستر رو توی گیت نمیذاریم و امنیت بالاتری رو داریم. با اجرای این روش ما در واقع داریم با استفاده از Gitops دیپلویهامون رو انجام میدیم. نکتهای که داره مجبوریم تو تمام استیجهای خودمون این ابزار رو داشته باشیم و نصبش کنیم.
توضیح Auto DevOps و موارد پیرامون آن:
یه مقدار عجیب به نظر میرسه ولی فرض کنید فرآیند CI/CD اپلیکیشن مون رو هم گیتلب به صورت خودکار برامون بنویسه! Auto DevOps یه مجموعهای از فیچرهای از قبل کانفیگ شده هست که به صورت سازگار باهم کار میکنند تا فرآیند دلیوری اپلیکیشن مارو انجام بدن. اتودواپس ابتدا زبان برنامهنویسی پروژه ما رو تشخیص میده و بعد فرآیند بیلد و تست اپلیکیشن رو برای ما مینویسه. در صورت امکان کد کوالیتی رو برامون اندازه میگیره و اسکن های امنیتی رو انجام میده، مشکلات لایسنس رو چک میکنه، به صورت real time مانیتور انجام میده و اپلیکیشن رو دیپلوی میکنه … یعنی فقط نون نمیگیره 🙂 البته به شرط اینکه کانفیگهاش به درستی انجام بشه و دردسرای راه اندازیش رو پشت سر بذارید. یه چیز دیگه اینکه بیشتر این قابلیتها تو نسخهی کامرشیالش فعاله و خیلی کم تو نسخهی رایگانش در دسترس هست. ولی به نظرم همون کمش هم خیلی زیاده و میتونیم باهاش کلی کار انجام بدیم.
معرفی منابع:
من و تجربه هام:
خیله خب :) فعلا مسیر CI/CD مون رو به پایان میرسونیم، امیدوارم فرصتش پیش بیاد که در آینده بتونیم باز برگردیم و توی مباحث مختلف این موضوع بیشتر عمیق بشیم و کنار هم چیزای بیشتری یاد بگیریم. قسمت پنجم مسیر CI/CD با مهر تقدیم شما عزیزان 🌹🌹🌹 در ادامه مسیر سعی میکنم که بریم سمت مباحث مانیتورینگ و اونها رو با هم توی یه مسیر جدید بررسی کنیم.
مراقب خودتون باشید. 🌹🐳🌹
خوبه که داکرمی رو تو جاهای مختلف فالو کنید. پذیرای نظرات شما هستیم.
🫀 Follow DockerMe 🫀
🔔 Follow YouTube 🔔
📣 Follow Instagram 📣
🖇 Follow LinkedIn DockerMe🖇
🔎 Follow Linkedin Ahmad Rafiee 🔎
🕊 Follow Twitter 🕊