توی این پست میریم سراغ انواع پایپلاین و یه سری از امکاناتی که میتونیم توی فایل gitlab-ci.yml. داشته باشیم رو بررسی میکنیم.

خب یه مروری کنیم پستهای قبلی رو:
دواپس چیه و چرا لازمه؟ اینجا در مورد دواپس و ضرورت استفاده از آن صحبت کردم.
چطور اپلیکیشن مناسب کلاد آماده کنیم؟ و اینجا توضیح دادم که چطور میتونیم یه اپلیکیشن مناسب کلاد توسعه بدیم.
چه عمقی از لینوکس برای دواپس لازمه؟ و اینجا توضیح دادم که کدوم موارد لینوکس برای دواپس الزامی هست که اول سراغ اون موارد بریم.
خودکارش کن,مشکلاتت حل میشه در اینجا در مورد اتومیشن و اینکه انسیبل چیه و چه کمکی به ما میکنه صحبت کردم.
در مسیر دواپس اینبار اجزای اصلی انسیبل تو این پست اجزای انسیبل رو معرفی کردم و آنها را شرح دادم.
در مسیر دواپس به داکر رسیدیم (قسمت اول) تو این پست داکر رو شروع کردیم و اونو معرفی کردیم.
در مسیر دواپس اینبار: پشت داکر چه خبره؟ (قسمت دوم) توی این پست در مورد تکنولوژی هایی که داکر ازشون استفاده میکنه توضیح دادیم.
تست نوشتن و شروع مسیر CI/CD (قسمت اول) توی این پست انواع تست رو بررسی کردیم و با ابزارهای CI/CD آشنا شدیم و یه مقایسه بین گیتلب و جنکینز داشتیم.
در مسیر CI/CD گیت رو بررسی میکنیم (قسمت دوم) توی این پست قبل ورود به گیتلب نیاز بود که گیت و ورژن کنترل سیستم ها رو یه بررسی کنیم.
در مسیر CI/CD شناخت گیتلب (قسمت سوم) توی این پست اجزای گیتلب رو بررسی کردیم و با کامپوننتهای مختلفی که داره بیشتر آشنا شدیم.
در مسیر CI/CD پایپلاین و رانر گیتلب (قسمت چهارم) توی این پست پایپلاین و رانر گیتلب رو بررسی کردیم.
در مسیر CI/CD وریبل، گیتآپس و جمعبندی (قسمت پنجم) توی این پست وریبلهای گیتلب رو بررسی کردیم و یه معرفی کوتاه از گیتآپس و آتودواپس کردیم و در انتها یه مقدار تجربههای خودم رو در گیتلب باهاتون به اشتراک گذاشتم.
در مسیر Observability، الک (قسمت دوم) توی این پست استک قدرتمند ELK رو بررسی کردیم.
در مسیر Observability، جمع بندی استک الک (قسمت سوم) توی این پست بقیه کامپوننتهای استک الک رو بررسی کردیم و fluentd و fluentbit رو مقایسه کردیم و نهایتا یه معرفی هم روی opensearch داشتیم.
در مسیر Observability، استک پرومتئوس (قسمت چهارم) توی این پست یه معرفی اولیه داشتیم روی استک پرومتئوس.
در مسیر Observability، استک پرومتئوس (قسمت پنجم) توی این پست یه مقدار کامپوننت های استک پرومتئوس رو بیشتر بررسی کردیم.
در مسیر Observability، استک ویکتوریا (قسمت ششم) توی این پست استک ویکتوریا رو معرفی کردیم و سعی کردیم با پرومتئوس مقایسهاش کنیم.
در مسیر Observability، میمیر (قسمت هفتم) توی این پست در مورد ابزار میمیر از ابزارهای گرافانا توضیح دادیم و کاربردش رو بررسی کردیم.
در مسیر Observability، لوکی (قسمت هشتم) توی این پست در مورد ابزار گرافانا برای مدیریت لاگ یعنی لوکی توضیح دادیم و آخرشم یه معرفی کوتاه رو graylog داشتیم.
در مسیر Observability، تمپو (قسمت نهم) توی این پست در مورد تریسینگ توضیح دادیم و گرافانا تمپو رو بررسی کردیم و یه معرفی کوتاه روی Jaeger داشتیم
در مسیر Observability، گرافانا (قسمت دهم) توی این پست در مورد گرافانا و HA کردنش و همچنین یه سری از ابزارهاش مثل alloy , incident, on-call توضیح دادیم.
آغاز مسیر کوبر (قسمت اول) تو این قدم به معرفی ابزارهای ارکستریشن پرداختیم و مدارک کوبرنتیز رو بررسی کردیم.
کوبر سینگل ( قسمت دوم ) توی این قدم در مورد kubectl , kubeconfig توضیح دادیم و تعدادی ابزار رو معرفی کردیم که به کمک اونها میتونیم یک کوبرنتیز دمهدستی واسه تستهامون داشته باشیم.
کامپوننتهای کوبر ( قسمت سوم ) توی این پست کامپوننتهای مختلف کوبرنتیز رو بررسی کردیم و اجزای نودهای مستر و ورکر رو دونه دونه بررسی کردیم و توضیح دادیم.
پادها و مدیریت اونها در کوبرنتیز (قسمت چهارم) توی این پست در مورد پاد توی کوبرنتیز توضیح دادیم و موارد مربوط به اون رو بررسی کردیم.
ورکلودهای کوبر و مدیریت منابع کوبر (قسمت پنجم) توی این پست در مورد namespaceها توی کوبر توضیح دادیم و انواع ورکلود کوبر رو بررسی کردیم.
اگه لازم شد کوبر خودش گنده میشه! ( قسمت ششم ) توی این پست در مورد سه نوع ورکلود مرتبط با scaling به صورت خودکار در کوبرنتیز توضیح دادیم.
نتورک کوبر (قسمت هفتم) توی این قسمت انواع سرویس توی کوبرنتیز رو بررسی کردیم و در مورد مفاهیم اینگرس و نتورک پالیسی توضیح دادیم.
استورج کوبرنتیز (قسمت هشتم) توی این قسمت در مورد انواع استورج توی کوبرنتیز توضیح دادیم و مفاهیم PV و PVC و Storage Class رو بررسی کردیم.
پراب، ریکوئست و لیمیت (قسمت نهم) توی این قسمت موارد مربوط به محدود کردن منابع کانتینر توی کوبرنتیز رو بررسی کردیم و در مورد انواع probe ها توی کوبرنتیز توضیح دادیم.
پاد تو نود (قسمت دهم) توی این قسمت درمورد فرآیند انتقال پاد به نود مناسب مفاهیم پیشرفتهتری مثل affinity و anti-affinity و taint و toleration رو بررسی کردیم.
اولویت پاد و امنیت (قسمت یازدهم) توی این قسمت در مورد تعیین اولویت برای پادها و جنبههای مختلف امنیت در کوبرنتیز توضیح دادیم.
کنترل دسترسی به کوبر (قسمت دوازدهم) توی این قسمت در مورد مراحل دسترسی به api کوبرنتیز صحبت کردیم و بعدش مفاهیمی مثل سرویس اکانت رو توضیح دادیم.
دیزاین کلاستر (قسمت سیزدهم) توی این قسمت در مورد طراحی و دیزاین یک کلاستر و روشهای مختلفی که داره توضیح دادیم و همچنین تفاوت روشهای مختلف تقسیم منابع در کلاسترها را بررسی کردیم.
مالتی تننسی در کوبر (قسمت چهاردهم) توی این قسمت چالشهای مربوط به داشتن چند مستاجر بر روی کلاستر کوبرنتیز توضیح دادیم.
هلم (قسمت پانزدهم) توی این قسمت پکیج منیجر معروف کوبرنتیز یعنی Helm رو بررسی کردیم و در موردش ویژگیها و کاربردهاش توضیح دادیم.
سی آر دی و اُپراتور (قسمت شانزدهم) توی این قسمت در مورد اینکه چطوری یه ریسورس کاستوم شده به کلاستر اضافه کنیم توضیح دادیم و مفهوم اُپراتور رو توی کوبر بررسی کردیم.
نصب کلاستر با kubeadm (قسمت هفدهم) توی این قسمت قدم به قدم نحوه نصب یک کلاستر کوبرنتیز رو با استفاده از ابزار kubeadm توضیح دادیم.
نصب کلاستر با kubespray (قسمت هجدهم) توی این قسمت نحوه نصب کلاستر با یه پروژه خیلی خوب به نام کیوب اسپری که یه انسیبل خفن برای ستاپ کلاستر رائه میده رو توضیح دادیم.
نصب کلاستر با rancher (قسمت نوزدهم) توی این قسمت توضیح دادیم که چطور با استفاده از ابزار RKE یک کلاستر کوبرنتیز راهاندازی کنیم.
توصیه میکنم که حتما این پستها رو هم مطالعه کنید. بریم که ادامه بدیم.

انواع پایپلاین
Basic pipelines
توی این نوع پایپ لاین جابهای توی یک استیج به صورت همروند اجرا میشن و بعد از اینکه تمام جاب های یک استیج اجرا شدن و تمام شد، گیت لب به سراغ جاب های استیج بعدی میره. دقت کنید تمام جابهای یک استیج به صورت همزمان در صورت وجود رانر اجرا میشوند.

Directed Acyclic Graph Pipeline (DAG)
حالا شرایطی رو در نظر بگیرید که مثلا من یک جاب توی استیج تست دارم که اگه فقط یه دونه از جابهای قسمت بیلد انجام شده باشه، میتونم اجرای این جاب رو هم شروع کنم و نیاز نیست که صبر کنم تا تمام جاب های استیج قبلی تمام بشن، توی این موارد میتونیم با استفاده از پایپ لاین نوع DAG وابستگی جابهای مختلف به هم رو در قالب یک گراف بدون دور جهتدار برای گیت لب مشخص کنیم تا دیگه هر جاب برای شروع شدن فقط منتظر جابهایی که واقعا پِند اونها هست بمونه.

Merged request pipelines
قبلتر در مورد نحوه مشارکت توی پروژهها به صورت PR توضیح دادم، حالا این نوع پایپ لاین تنها زمانیکه درخواست مرج به پروژه بیاد اجرا میشود.
Merged result pipelines
اگه درخواست PR که به پروژه اومده تایید و مرج شد اون موقع این نوع پایپ لاینها اجرا میشن.
Merge trains
این نوع پایپ لاین از نوع قبلی استفاده میکنه تا صفی از مرجها رو در صورت نیاز ایجاد کند.

Parent-child pipelines
معمولا پایپ لاینهای بزرگ و پیچیده رو به واحدهای کوچکتر میشکنند و اونها رو تبدیل به یه سری پایپ لاین والد یا پرنت میکنن که هرکدومشون معمولا چنتا پایپ لاین فرزند یا چایلد رو تریگر و فعال میکنند. پایپ لاینهای والد و فزرند همه در یک پروژه هستند و این روش مناسب طراحیهای mono-repo هست.

Multi-project pipelines
از این نوع پایپ لاین هم در طراحیهای multi-repo استفاده میشه که توی اونها چنتا پایپ لاین رو از پروژههای مختلف با هم ترکیب میکنیم.
به پایپ لاین بالادستی که پایپ لاین دیگه رو تریگر میکنه upstream میگیم و به پایپ لاینی که تریگر میشه downstream میگیم. فرق پرنت چایلد با مالتی پراجکت توی این هست که در حالت پرنت چایلد downstream توی همون پروژه ای هست که upstream هم هست ولی توی مالتی پراجکت اینطور نیست.
با استفاده از Strategy میتونیم مشخص کنیم که پایپلاین ما نسبت به Downstream چه وضعیتی داشته باشد. مثلا اینکه فقط آن را تریگر کند و ازش عبور کنه یا اینکه منتظر باشه تا نتیجهی آن هم مشخص بشه. با استفاده از strategy: depend توی پایپ لاین تا کامل شدن Downstream صبر میکنیم و پس از نهایی شدن آن ادامهی پایپلاین رو طی میکنیم.

نکات مربوط به Pipeline efficiency
پایپ لاینها بلاکهای اصلی و پایهای تو CI/CD گیتلب هستن و کارآمدتر کردن اونها میتونه به بالاتر بردن سرعت پروسههای دواپس ، کمتر کردن هزینه و کوتاه تر کردن feedback loop توسعه دهندهها کمک کنه. معمولا این شکلی هست که با یه پایپ لاین که فقط کار میکنه شروع میکنیم و به طور پیوسته سعی میکنیم اون رو افیشنتتر کنیم. در ادامه نکاتی رو که برای بهتر کردن پایپ لاینها بهمون کمک میکنه رو براتون میارم:
Fail fast
اگه قراره فیل کنه، چه بهتر که سریعتر این اتفاق بیافته. این اصل بهمون توصیه میکنه که از نوشتن جابهایی که زمان زیادی طول میکشه اجراشون خودداری کنیم و سعی کنیم جابهامون رو به شکلی طراحی کنیم که اگر قراره فیل بشن سریعتر این اتفاق بیافته. برای مثال تا جای ممکن قبل از اجرای یک جاب توی جابهای قبل تر براش مواردی مثل syntax و style linting و git commit message verification رو انجام بدیم، یا مثلا جاب های طولانیتر رو تا جای ممکن اول انجام بدیم بعد به سراغ جاب های سریع تر بریم.

این مساله توی زندگی شخصی و روابط عاطفی هم اهمیت داره به نظرم. اگه قراره تهش fail کنه همون بهتر که زودتر اتفاق بیافته. تو این موارد توصیه میکنم که اصول افیشنسی پایپ لاین مرور کنید و به خودتون بگید: رها کن سید! 🙂

Caching
یه روش دیگه که میتونیم باهاش پایپ لایمون رو کارآمدتر کنیم، کش کردن دیپندنسیها هست. اگه دیپندنسیهای پروژه تون تندتند ممکنه تغییر کنن مثل ماژول های NodeJS مثلا، میتونید از cache توی پایپ لاین استفاده کنیم تا اونها رو حتی زمانیکه جاب fail میشه هم نگهداره و به سرعت پایپ لاین برای اجرای بعدی کمک کنه. معمولا این موارد که به صورت استاتیک هستند رو میتونیم به خوبی کش کنیم تا برای دفعات بعدی با سرعت بهتری آنها رو دریافت کنیم.

Docker Images
اگه یک ایمیج داکر داره اجرای جاب تون رو کند میکنه، حتما حجم بیس ایمیج و وضعیت ارتباط نتورکی با رجیستری ایمیج تون رو بررسی کنید و همچنین رجیستری داخلی گیت لب رو هم در نظر بگیرید چون سریعتر از سایر رجیستریها هست و میتونه بسته به نیازتون کمک کننده باشه. تا جای ممکن از اینکه حجم یک ایمیج رو بالا ببرید دوری کنید و سعی کنید تعداد بیشتری ایمیجهای کم حجم تر رو جایگزین کنید که هر کدوم برای یک تسک باشه تا سریعتر دانلود و اجرا بشن. قبلا توی پست مربوط به داکرفایل هم در مورد افیشنت کردن ایمیج هامون گفتم که میتونید بهش مراجعه کنید.
امنیت پایپ لاین Pipeline Security
Secret Management
سکرت منیجمنتها سیستمهایی هستن که توسعهدهندهها ازشون استفاده میکنن برای ذخیره دیتاهای با حساسیت بالا توی یه انوایرومنت امن با دسترسی ها کنترل شده. توی گیت لب secret به دیتایی مثل پسوردها، کلیدهای SSH و توکنها یا هر اطلاعات دیگری که میتونه برای سازمان حساس باشه، گفته میشه که باید به صورت محرمانه نگهداری کنیم. یه ابزار برای این کار Vault هست که secret هارو برای ما بیرون از گیت لب نگهداری میکنه.

CI/CD variables
اگر دیتایی حساسیت بالایی دارد باید برای اون از secret management استفاده کنید اما برای دیتای با حساسیت پایین تر میتونید اونها رو به شکل Mask و Protected توی وریبل CI/CD نگهداری کنید. دقت کنید که وریبل ها برای افرادی که به setting دسترسی دارند قابل نمایش و تغییر هست همچنین وریبل ها میتونن در صورت اشتباه در کانفیگ توی پایپ لاین دیده بشن و اونها رو میس کنیم.

Gitlab CI/CD job token
وقتی که یک جاب توی پایپ لاین اجرا میشه گیت لب یک توکن یونیک رو براش ایجاد میکنه و اون رو میذاره توی وریبل CI_JOB_TOKEN که به صورت دیفالت تعریف شده. برای اطمینان از اینکه توکن لیک نمیشه، گیت لب اون رو توی لاگ جاب ها Mask میکنه و میتونید رانرها رو هم برای این مساله کانفیگ کنید.

موارد مربوط به Runner
چیه و چه کمکی میکنه: رانر اپلیکیشنی هست که با CI/CD گیت لب کار میکنه برای ران کردن جاب های پایپ لاین.

مزایای رانر و انواع رانر: رانرها میتونن چند جاب رو به صورت همروند اجرا کنن و از توکن های مختلف برای دسترسی به سرورهای مختلف استفاده کنن و حتی میتونید تعداد جاب همروند رو برای هر توکن مشخص کنید. رانر به زبان گولنگ نوشته شده میتونه در قالب یک برنامه باینری بدون نیازمندی خاصی جابجا بشه. بنابراین نصبش آسونه و ویژگی باحالی که داره این هست که به صورت خودکار هر ۳ ثانیه چک میکنه کانفیگش رو در اگه نیاز باشه خودش ریلود رو انجام میده.
انواع رانرها: رانر ها رو میشه به سه دسته زیر تقسیم کرد:
Shared Runners
رانر هایی که همه ی پروژههای توی گیت لب مون میتونن تسک به اونها بدن رو shared میگیم. معمولا رانرهایی که در سطح یک اینستنس گیتلب ایجاد میشه رو بهش shared runner میگن.
Group Runners
این رانر ها فقط برای پروژههای داخل یک group و subgroup های اون در دسترس هستن.
Specific Runners
این رانرها مختص یک پروژه هستن و پروژه های دیگه نمیتونن از اونها استفاده کنند.
توضیح executor و انواع آن: به انوایرومنتی که رانر جاب رو توی اون انجام میده اگزکیوتر میگیم که انواع مختلفی داره:
Shell executor
Virtual Machine executor
Docker executor
Docker Machine executor
Kubernetes executor
SSH executor
Custom Executor
توضیح اجمالی نصب و روشهای آن و رجیستر کردن: رانر رو میتونیم رو سیستمعاملهای مختلف یونیکس بیس و مک و ویندوز نصب کنیم. هم میتونیم اونو توی یه کانتینر بالا بیاریم هم برنامه باینریش رو دانلود کنیم و هم میتونیم از طریق پکیچ مخزنها دریافتش کنیم. با یه سرچ ریز میتونید مراحل روشی که میخواید رو پیدا کنید. بعد از نصب رانر باید اون رو به گیت لب مون وصل کنیم یا اصطلاحا رجیسترش کنیم. از طریق پنل گیت لب هنگام اضافه کردن رانر میتونید دستورات و توکن لازم برای اضافه کردن رانر ها از انواع مختلف رو پیدا کنید.

کانفیگ رانر و توضیح قسمتهای مهم آن: راننر دارای کانفیگهای مختلفی است که میتونید آنها رو تو فایل کانفیگ رانر مشاهده کنید. به صورت کلی برخی از کانفیگها به صورت عموم هستند مثلا اینکه رانر ما چند تا جاب رو بتونه همزمان اجرا کنه و برخی از کانفیگها همانند اینکه والیومها و یا image pull policy مربوط به executor داکر هست. به صورت کلی پیشنهاد میکنم حتما با کانفیگهاش آشنا بشید تا بتونید بهترین استفاده رو ازش بکنید.
موارد مربوط به gitlab-ci.yml:
چیه و باهاش چی کار میکنیم: فایلی با نام gitlab-ci.yml. رو توی روت پروژه قرار میدیم و موارد مرتبط با CI/CD رو توی اون مینویسیم. تمام موارد مرتبط با پایپ لاین و اسکریپت هایی که میخوایم اجرا بشن و کانفیگ فایلها و دیپندنسیها رو توی این فایل مینویسیم. همچنین کامندهایی که میخوایم به ترتیب یا به صورت موازی اجرا بشن رو هم اینجا مینویسیم و نحوهی تریگر کردن پایپ لاین و جایی که میخوایم دیپلوی رو انجام بدیم در این فایل مشخص میکنیم.

ادیتور و ولیدیتور: یکی از معدود ابزارهایی که ادیتور آنلاینش میتونه ارزش استفاده کرد به صورت جدی رو داشته باشه گیت لب هست که علاوه بر یک ادیتور خوب امکان بررسی فایل CI/CD تون به لحاظ سینتکس رو هم بهتون میده.
Global keywords default:
برای keyword هایی که تو لیست زیر میارم میتونید مقدار دیفالت مشخص کنید تا اگر در فایلی مقدار اونها رو تعریف نشده بود از مقداری که به صورت دیفالت مشخص کردید، استفاده بشه. یکی از راههایی هست که کمک میکنه فایلهایی که مینویسیم رو سادهتر و تمیزتر کنیم همین استفاده از دیفالت هست.
after_script
artifacts
before_script
cache
image
interruptible
retry
services
tags
timeout
در ادامه مواردی که در قسمت جاب این فایل میتونیم داشته باشیم رو بررسی میکنیم.
include:
میتونید برای جلوگیری از طولانی شدن فایلتون از include استفاده کنید و فایل های yaml بیرونی رو به فایل CI/CD تون اضافه کنید.
after_script:
معمولا مواردی که میخواهیم بعد از تسکاصلی داخل جاب اجرا بشن رو اینجا قرار میدیم. معمولا رویکردمون اینه که در before سعی میکنیم آماده سازیها رو انجام بدیم و در خود script عملکرد اصلی و در after سعی میکنیم cleanupها رو انجام بدیم.
allow_failure:
با گذاشتن مقدار true برای این گزینه میتونیم بگیم که اگه این جاب fail شد ایرادی نداره و پایپ لاین ادامه پیدا کنه. به صورت پیشفرض جابها در زمانی که جاب قبلی به صورت موفقیت آمیز تموم شده باشد اجرا میشود.
artifacts:
با آرتیفکت میتونیم خروجی یک جاب رو ذخیره کنیم و توی جابهای بعدی ازش استفاده کنیم. هیچ ارتباط مشخصی بین رانرها و جابهای ما نیست. راه حل اصلی برای ارتباط بین جابها و انتقال فایل بین آنها استفاده از artifact است که با استفاده از آن میتونیم از یک جاب مواردی رو به جاب بعدی منتقل کنیم.
before_script:
مواردی که میخوایم قبل از اسکریپت هامون انجام بشن رو اینجا میذاریم. مثلا لاگین تو ریجیستری یا اینکه نصب پکیجهای مورد نیازمون.
cache:
مواردی که میخوایم گیت لب اونها رو توی کش نگه داره رو با این گزینه مشخص میکنیم.
environment:
محیطی که میخوایم دیپلوی توش انجام بشه رو با این گزینه مشخص میکنیم.
image:
ایمیجی که جاب ما داخل آن اجرا میشه رو مشخص میکنیم.
needs:
وقتی بخواهیم که یک جاب رو به جاب دیگهای وابسته کنیم از needs استفاده میکنیم.
only:
اینجا مشخص میکنیم که این جاب تنها در کدام برنچ یا وضعیتی اجرا شود.
script:
دقیقا همون کاری هست که انتظار داریم تا در جاب اجرا شود.
services:
با استفاده از سرویس ما میتونیم برخی از مواردی که بهش نیاز داریم همانند دیتابیسها رو به صورت آماده در اختیار داشته باشیم تا بتونیم باهاش به راحتی تست و بررسی کنیم.
stage:
با این گزینه مشخص میکنیم که این جاب ما در کدام استیج اجرا میشود.
tags:
با این گزینه میتونیم روی جاب هامون لیبل بزنیم یه جورایی اونها رو میتونیم به رانر خاصی وصل کنیم. با استفاده از tag ما میتونیم جابهای خودمون رو به راننرهای خاص متصل کنیم. یعنی میتونیم رانرهای اختصاصی داشته باشیم که هیچ جاب به جز جابهایی که فلان تگ رو دارند اجرا نکند.
توی قسمتهای بعدی مسیر دواپسمون رو ادامه میدیم و بیشتر گیتلب و موارد مرتبط به اون رو با هم بررسی میکنیم.
مراقب خودتون باشید. 🌹🐳🌹
خوبه که داکرمی رو تو جاهای مختلف فالو کنید. پذیرای نظرات شما هستیم.
🫀 Follow DockerMe 🫀
🔔 Follow YouTube 🔔
📣 Follow Instagram 📣
🖇 Follow LinkedIn DockerMe🖇
🔎 Follow Linkedin Ahmad Rafiee 🔎
🕊 Follow Twitter 🕊