در هر قطعی اینترنت بینالملل یک الگوی تکراری دیده میشود. سایتها و سرویسهای داخلی بالا میمانند و به نظر میرسد زیرساخت از آزمون سربلند بیرون آمده. چند ساعت یا چند روز بعد، اولین استقرار شکست میخورد، سروری که ریاستارت شده دیگر بالا نمیآید، یا ساعت یک دستگاه آنقدر جابهجا میشود که ورود دومرحلهای از کار میافتد.
مشکل این نیست که سرویسها به اینترنت وصلاند. مشکل این است که ساختن، بهروزرسانی و راهاندازی دوبارهی آنها به اینترنت وصل است، و این وابستگیها تا روزی که لازمشان داشته باشید دیده نمیشوند.
وابستگیهایی که معمولاً دیده نمیشوند
- مخزن بستهها —
apt،npm،pipوgoبهطور پیشفرض از سرورهای خارج از کشور دانلود میکنند. هر build و هر نصب تازه به آنها نیاز دارد. - ایمیج کانتینر — Docker Hub درخواستهایی را که از نشانیهای ایرانی میآید رد میکند، حتی در روزهای عادی. خط لولهای که با
FROM node:22شروع میشود، در عمل به یک سرور خارجی وابسته است. - زمان — سرورها ساعتشان را از سرورهایی مثل
ntp.ubuntu.comیاtime.windows.comمیگیرند. بدون همگامسازی، ساعت هر دستگاه روزی چند ثانیه جابهجا میشود؛ بعد از چند هفته، کدهای ورود دومرحلهای، اعتبار گواهیها و ترتیب لاگها به هم میریزد. - DNS — سرورهایی که مستقیم از
8.8.8.8یا1.1.1.1استفاده میکنند، ممکن است در قطعی حتی نام سرویسهای داخلی را هم پیدا نکنند. - فعالسازی لایسنس — بعضی نرمافزارهای تجاری در هر راهاندازی یا هر چند روز یک بار با سرور سازنده تماس میگیرند.
- هشدار — اگر هشدارهای مانیتورینگ فقط از راه سرویسی خارجی ارسال شود، درست روزی که بیشترین نیاز را دارید هیچ هشداری نمیرسد.
- منابع وبسایت — فونت، اسکریپت یا کپچایی که از CDN خارجی بارگذاری میشود، صفحه را برای کاربر داخلی کند یا ناقص میکند.
برای هر وابستگی، یک جایگزین داخلی
| وابستگی | جایگزین داخلی |
|---|---|
| بستههای سیستمعامل | آینهی داخلی با aptly یا apt-mirror |
| بستههای npm، pip و Maven | مخزن واسط مانند Nexus یا Verdaccio که هر بسته را یک بار دریافت و نگه میدارد |
| ایمیج کانتینر | رجیستری داخلی مانند Harbor با ایمیجهای پایهی آزموده |
| زمان | سرور NTP داخلی (chrony) که بقیهی دستگاهها از آن همگام شوند |
| DNS | resolver داخلی که درخواستها را به چند مقصد میفرستد |
| هشدار | کانالی که از داخل شبکه کار کند، مثل پیامک یا پیامرسان داخلی |
| فونت و اسکریپت سایت | میزبانی روی همان سرور سایت |
یک نکته دربارهی مخزن واسط: دریافت «هنگام نیاز» کافی نیست. بستهای که هیچوقت درخواست نشده، روز قطعی هم در مخزن نیست. برای وابستگیهای حیاتی، کل درخت وابستگی را یک بار در روزهای عادی دریافت کنید.
نسخهها را قفل کنید
آینهی داخلی فقط وقتی کمک میکند که build دقیقاً بداند چه میخواهد. فایلهایی مثل package-lock.json، poetry.lock یا go.sum را در مخزن کد نگه دارید و ایمیجهای پایه را با نسخهی کامل مشخص کنید، نه با برچسبی مثل latest:
FROM registry.internal/base/node:22.12-bookwormتمرین قطعی
بهترین راه برای پیدا کردن وابستگیهای پنهان، قطع عمدی است. در محیط staging، ترافیک خروجی به خارج از کشور را برای یک روز ببندید و این کارها را انجام دهید:
- یک build کامل از صفر، بدون cache
- استقرار یک نسخهی تازه
- ریاستارت یک سرور و یک پایگاه داده
- ورود دومرحلهای، و بررسی ساعت دستگاهها
- ارسال یک هشدار آزمایشی
هر چیزی که شکست خورد، وابستگیای است که در فهرست بالا نبوده. نتیجه را ثبت کنید و تمرین را هر چند ماه تکرار کنید؛ وابستگیهای تازه بیصدا اضافه میشوند.
جمعبندی
آمادگی برای قطعی یعنی بتوانید در شبکهی داخلی بسازید، مستقر کنید و دوباره راه بیندازید، نه فقط سرویس بدهید. از زمان و بستهها شروع کنید: هر build به بستهها نیاز دارد و هر ورود دومرحلهای به ساعت درست.