گیتآپس در عمل: خط لولهی CI/CD مقیاسپذیر با GitLab و GKE
خلاصهٔ کاملتر
به گفتهی نویسنده، ساختن یه خط لولهی CI/CD مقیاسپذیر روی GitLab و Google Kubernetes Engine از یه تصمیم شروع میشه: خط لوله رو یه سیستم تحویل میبینی که خودت طراحیش میکنی، یا یه فایل YAML که از یه آموزش کپی میکنی؟ تو این مقاله اومده که بیشتر تیمها گزینهی دوم رو انتخاب میکنن؛ یه .gitlab-ci.yml مینویسن، روی کلاستر پوش میکنن و اسمشو میذارن گیتآپس. تا وقتی همهچیز کوچیکه جواب میده، ولی همینکه محیطها زیاد شدن و سکرتها پخش شدن، یه مرج بد کافیه تا به پروداکشن برسه.
پس اولین سؤال طراحی «کدوم YAML؟» نیست، «push یا pull؟»ه. تو مدل push، رانر GitLab از بیرون kubectl apply میزنه و دستش رو میبره تو کلاستر. تو مدل pull برعکسه: یه ایجنت داخل خود کلاستر گیت رو میپاد و تغییرات رو میکشه. مستندات GitLab برای گیتآپس، Flux بههمراه GitLab agent for Kubernetes رو پیشنهاد میدن تا کلاستر هیچوقت بیرون از فایروال در معرض دید نباشه — یعنی نه دسترسی ورودی به کلاستر لازمه، نه یه kubeconfig طولانیعمر که تو متغیرهای CI بمونه.
شاخهبندی جاییه که آهنگ ریلیز بیسروصدا تعیین میشه. غریزه میگه برای هر محیط یه شاخهی بلندمدت بساز (dev و staging و prod) و بینشون مرج کن؛ به گفتهی نویسنده همین کار drift و کانفلیکت و سردرگمیِ «الان دقیقاً چی تو staging هست؟» رو میسازه. الگوی تمیزتر اینه که کد اپلیکیشن با trunk-based development جلو بره و پیکربندی محیطها تو یه مخزن مانیفست جدا بشینه، جایی که هر محیط یه پوشه یا overlay هست، نه یه شاخه. اونوقت ترفیع یه ریلیز فقط یه کامیته که تگ ایمیج رو عوض میکنه و تاریخچهش خطی و قابل ممیزی میمونه.
برای ترفیع بین محیطها، GitLab دو تا ابزار صریح میده: environments که dev و staging و prod رو به شیء درجهیک تبدیل میکنن، و protected environments که جلوی محیطهای حساس دروازه میذارن و میتونن قبل از این که جابی به پروداکشن دست بزنه تأیید بگیرن. تو مدل pull، «دیپلوی» یعنی کامیت تگ ایمیج جدید تو مخزن مانیفست: CI ایمیج رو میسازه و اسکن میکنه و یه مرجریکوئست روی overlay اون محیط باز میکنه، و Flux خودش اعمالش میکنه. سودش قابلیت ردیابیه — هر تغییر پروداکشن یه MR بازبینیشده با تأییدکننده و دیف و زمانه، نه یه لاگ رانر.
بیشترین آسیب رو همون تنظیمات پیشفرض میزنن: گرفتن کلید JSON سرویساکانت گوگل و مونتکردنش بهعنوان Secret کوبرنتیز — دقیقاً همون الگویی که خود گوگل ازش پرهیز میده، چون کلید بلندمدت لو میره، سر از مخزن درمیاره و کم پیش میاد کسی بچرخونتش. جواب نویسنده Workload Identity Federationه: سرویساکانت کوبرنتیز با توکنهای کوتاهعمر و خودچرخان به APIهای گوگل احراز هویت میکنه و هیچ فایل کلیدی تو کلاستر نمیمونه. برای سکرتهای اپلیکیشن هم میشه External Secrets Operator رو با Google Secret Manager جفت کرد تا مخزن فقط ارجاع رو نگه داره، نه خود مقدار رو.
نقش GitLab Duo هم به گفتهی نویسنده نوشتن کل خط لوله نیست؛ کمکردن دو تا هزینهست: نوشتن کانفیگ درست CI و ریشهیابی جابهای شکستخورده. Duo میتونه کامپوننت CI/CD تولید کنه و با Root Cause Analysis لاگ یه جاب خراب رو تحلیل کنه و علت محتمل و اصلاح رو پیشنهاد بده، بهجای این که خودت لای لاگ دنبال یه ایمیج بدون رانتایم Go بگردی. آخر کار هم خط لولهای مقیاسپذیره که بشه اندازهش گرفت: چهار متریک DORA (فراوانی دیپلوی، زمان تحویل تغییر، نرخ شکست تغییر و زمان بازیابی) رو باید با هم خوند، نه جدا جدا؛ دیپلویِ زیاد با نرخ شکست بالا یعنی دروازههات شلان.
نکات کلیدی:
- گیتآپس یعنی گیت منبع حقیقتِ وضعیت کلاستر باشه و یه کنترلر کلاستر رو باهاش همگام کنه؛ برای هر چیزی فراتر از یه کلاستر dev، مدل pull پیشفرض بهتره
- کد اپلیکیشن با trunk-based development جلو بره و پیکربندی محیطها تو مخزن مانیفست جدا، به شکل پوشه/overlay بشینه — نه شاخهی جدا برای هر محیط
- ترفیع به پروداکشن از دروازهی protected environment و کدریویو رد بشه، نه از شرطهای پنهون توی خود پایپلاین
- کلید JSON سرویساکانت تو متغیرهای CI ممنوع؛ جاش Workload Identity Federation و برای سکرتها External Secrets Operator با Secret Manager
- سلامت خط لوله رو با چهار متریک DORA بسنج و همیشه کنار هم تفسیرشون کن




