حالت تاریک
فصل ۱۲ — مدیریت تغییرات سرورها
بسیاری از سازمانها و تیمها روی فرایندها و ابزار ساخت سرور و زیرساخت دیگر تمرکز میکنند، اما تغییرات را نادیده میگیرند. وقتی تغییری لازم است — رفع مشکل، اعمال patch امنیتی یا ارتقای نرمافزار — آن را رویداد غیرعادی treat میکنند. اگر هر تغییر استثنا باشد، نمیتوانید آن را automate کنید. این mindset دلیل است که بسیاری سازمانها سیستمهای ناهمگون و flaky دارند. دلیل است که بسیاری از ما وقت را بین برداشتن ticketهای کسلکننده و خاموش کردن آتشها جابهجا میکنیم.
تنها ثابت سیستمهای ما این است که تغییر میکنند. اگر سیستمها را بهصورت کد تعریف کنیم، روی بسترهای زیرساخت پویا اجرا کنیم و آن کد را با change pipeline در سراسر سیستمها تحویل دهیم، میتوانیم تغییر را routine و آسان کنیم. اگر سیستمها فقط از طریق کد و pipeline ایجاد و تغییر کنند، میتوانیم سازگاری را تضمین و مطمئن شویم با هر سیاستی که نیاز داریم همراستا هستند.
«چه چیزهایی روی سرور است» در صفحه ۱۷۰ و «منشأ چیزها» در صفحه ۱۷۱ توضیح میدهند چه چیزهایی روی سرور است و از کجا میآیند. همه چیز روی سرور دادهشده از منبع تعریفشده میآید — چه نصب OS، مخزن بسته سیستم یا کد پیکربندی سرور. هر تغییری که روی سرور لازم است، تغییر در یکی از این چیزهاست.
این فصل درباره تغییر چیزها روی سرور با تغییر کدی است که تعریف میکند چیز از کجا میآید و سپس اعمال آن به هر نحوی که مناسب باشد. با پیادهسازی فرایند تغییر خودکار و قابل اعتماد برای سرورها، میتوانید تغییرات را سریع و مطمئن در سراسر estate rollout کنید. همه سرورها را با آخرین بستهها و پیکربندی تأییدشده با حداقل تلاش بهروز نگه دارید.
چند الگو برای اعمال کد پیکربندی روی سرورها وجود دارد — از جمله اعمال هر تغییر همانطور که رخ میدهد، همگامسازی مداوم، و rebuild سرورها برای تغییر. بعد دیگر تغییر، نحوه اجرای ابزار برای اعمال تغییرات روی سرور است — push یا pull پیکربندی. در نهایت، رویدادهای دیگری در چرخه عمر سرور هست — از pause تا rebuild تا حذف سرور.
الگوهای مدیریت تغییر: چه زمانی تغییرات را اعمال کنیم
یک ضدالگو و دو الگو برای تصمیم درباره زمان اعمال تغییرات روی نمونه سرور وجود دارد.
ضدالگو: اعمال هنگام تغییر (Apply On Change)
همچنین شناختهشده بهعنوان: اتوماسیون ad hoc.
با ضدالگوی apply on change، کد پیکربندی فقط وقتی روی سرور اعمال میشود که تغییر مشخصی برای اعمال باشد.
مثلاً تیمی که چند application server Tomcat اجرا میکند. اعضا هنگام ایجاد نمونه سرور جدید playbook Ansible برای نصب و پیکربندی Tomcat اجرا میکنند، اما وقتی سرور در حال اجراست تا نیاز باشد Ansible اجرا نمیکنند. وقتی نسخه جدید Tomcat منتشر میشود، playbook را بهروز و روی سرورها اعمال میکنند.
در شدیدترین نسخه این ضدالگو، فقط کدی را روی سرور اعمال میکنید که قصد تغییر مشخص آن را دارید.
تیم در مثال ما میبیند یکی از application serverها ترافیک بسیار بالاتری دارد و بار Tomcat را unstable میکند. اعضا تغییراتی در playbook برای بهینهسازی پیکربندی Tomcat برای بار بالاتر میدهند و فقط روی سرور مشکلدار اعمال میکنند — نه روی بقیه application serverها، چون به تغییر نیاز ندارند.
انگیزه (Motivation)
مدیران سیستم و شبکه سنتیاً سرورها را دستی مدیریت میکردند. وقتی تغییر لازم است، login میکنید و تغییر میدهید. چرا متفاوت عمل کنید؟ حتی کسانی که اسکریپت استفاده میکنند معمولاً اسکریپت مینویسند و برای تغییر مشخص اجرا میکنند. ضدالگوی apply on change توسعه این روش کار است که بهاتفاق از ابزار Infrastructure as Code بهجای دستور دستی یا اسکریپت one-off استفاده میکند.
کاربرد (Applicability)
اعمال کد فقط وقتی برای تغییر مشخص لازم است برای یک سرور موقت تکی شاید کافی باشد. اما روش مناسبی برای مدیریت پایدار گروهی از سرورها نیست.
پیامدها (Consequences)
اگر کد پیکربندی فقط برای تغییر مشخص اعمال شود، ممکن است فاصلههای طولانی باشد که کد هرگز روی نمونه سرور خاص اعمال نشود. وقتی بالاخره اعمال میکنید، ممکن است بهخاطر تفاوتهای دیگر روی سرور — غیر از آنچه قصد تغییر داشتید — fail کند.
چیزها عادت دارند وقتی توجه نمیکنید روی سرور تغییر کنند. کسی ممکن است دستی تغییر دهد — مثلاً fix سریع برای outage. کس دیگری ممکن است سیستم را با نسخههای جدیدتر بسته OS یا برنامه patch کرده باشد. اینها در دسته تغییرات سریعی که مطمئنیم چیزی نمیشکند — و دستهای که هفته بعد یادمان نمیآید (چون تغییر کوچک بود) تا چند ساعت debug کنیم و بفهمیم چه چیزی را شکسته.
مسئله وقتی بدتر میشود که تغییر را فقط روی بعضی سرورها و نه همه اعمال کنیم. مثال قبلی که تیم کد بهینهسازی performance را روی یک سرور اعمال کرد. بعداً کسی از تیم باید تغییر دیگری روی application serverها بدهد.
وقتی این کار را میکند، تغییر بهینهسازی performance قبلی را هم — بهعنوان side effect اعمال کد برای تغییر جدید — روی سرورهایی که هنوز ندارند اعمال میکند. تغییر قبلی ممکن است روی سرورهای دیگر اثر غیرمنتظره داشته باشد. بدتر، کسی که کد را اعمال میکند ممکن است بهینهسازی performance را فراموش کرده باشد و کشف علت مشکلات خیلی طولانیتر شود.
پیادهسازی (Implementation)
کسانی که به تغییر دستی یا اسکریپت one-off عادت دارند معمولاً کد پیکربندی سرور را همانطور استفاده میکنند. ابزار — Ansible، Chef، Puppet — را ابزار اسکریپت با syntax awkward میبینند. اغلب ابزار را دستی از کامپیوتر محلی اجرا میکنند، نه pipeline یا سرویس orchestration دیگر.
الگوهای مرتبط (Related patterns)
معمولاً ضدالگوی apply on change با الگوی push configuration («الگو: Push Server Configuration» در صفحه ۱۹۸) استفاده میشود، نه pull («الگو: Pull Server Configuration» در صفحه ۲۰۰). جایگزینها: همگامسازی مداوم یا سرورهای immutable («الگو: Immutable Server» در صفحه ۱۹۵).
الگو: همگامسازی مداوم پیکربندی (Continuous Configuration Synchronization)
همچنین شناختهشده بهعنوان: بهروزرسانی زمانبندیشده پیکربندی سرور.
همگامسازی مداوم پیکربندی یعنی اعمال مکرر و مکرر کد پیکربندی روی سرور — چه کد تغییر کرده باشد چه نه. این تفاوتهای غیرمنتظرهای که ممکن است در سرور یا منابع دیگر مورد استفاده کد پنهان شوند را revert یا surface میکند.
انگیزه (Motivation)
دوست داریم باور کنیم پیکربندی سرور قابل پیشبینی است. یک بار کد را اعمال کنم، تا دفعه بعدی چیزی نباید تغییر کند. و اگر کد را تغییر ندادهام، نیازی به اعمال نیست. اما سرورها و کد سرور حقهبازند.
گاهی سرور به دلایل واضح تغییر میکند — مثل login و تغییر دستی. مردم اغلب تغییرات جزئی اینطور میدهند چون فکر میکنند مشکلی ایجاد نمیکند. اغلب در این اشتباهند. در موارد دیگر، برخی جنبههای سرور با ابزار یا فرایند دیگر مدیریت میشود. مثلاً برخی تیمها ابزار تخصصی برای بهروز و patch سرور — بهویژه patch امنیتی — دارند.
حتی اگر سرور تغییر نکرده باشد، اعمال مکرر همان کد پیکربندی سرور ممکن است تفاوت ایجاد کند. مثلاً کد از پارامتر registry پیکربندی متمرکز استفاده کند. اگر یکی از پارامترها تغییر کند، دفعه بعد که روی سرور اجرا شود ممکن است کار متفاوتی کند.
بستهها منبع خارجی دیگر تغییرند. اگر کد پیکربندی بسته را از مخزن نصب کند، ممکن است وقتی نسخه جدیدتر در دسترس شد، بسته را بهروز کند. میتوانید نسخه بسته را مشخص کنید، اما به یکی از دو راه بد منتهی میشود. در یک راه، سیستم eventually بستههای قدیمی زیادی دارد — از جمله با آسیبپذیری امنیتی شناختهشده برای مهاجمان. در راه دیگر، شما و تیم انرژی enormی صرف بهروز دستی شماره نسخه بسته در کد سرور میکنید.
با اعمال مجدد منظم و خودکار کد پیکربندی سرور، همه سرورها را بهطور سازگار پیکربندیشده نگه میدارید. هر تفاوتی — از هر منبعی — زودتر اعمال میشود تا دیرتر.
کاربرد (Applicability)
پیادهسازی همگامسازی مداوم از جایگزین اصلی — سرورهای immutable — آسانتر است. بیشتر ابزارهای Infrastructure as Code — Ansible، Chef و Puppet — با این الگو طراحی شدهاند. اعمال تغییر با بهروزرسانی نمونه موجود سریعتر و کممزاحمتتر از ساخت نمونه جدید است.
پیامدها (Consequences)
وقتی فرایند خودکار کد پیکربندی سرور را در estate اعمال میکند، ریسک شکستن چیزی وجود دارد. همه چیزهایی که ممکن است غیرمنتظره تغییر کنند — همانطور که در بخش انگیزه توضیح داد — میتوانند سرور را بشکنند. برای مقابله، سیستم نظارت مؤثر برای alert و فرایند خوب آزمایش و تحویل کد قبل از اعمال روی production لازم است.
پیادهسازی (Implementation)
همانطور که گفته شد، بیشتر ابزارهای پیکربندی سرور بهصورت کد برای اجرای مداوم طراحی شدهاند. مکانیزمهای خاص در «الگو: Push Server Configuration» در صفحه ۱۹۸ و «الگو: Pull Server Configuration» در صفحه ۲۰۰ توضیح داده شده.
بیشتر پیادهسازیهای همگامسازی مداوم روی schedule اجرا میشوند. معمولاً راهی برای vary کردن زمان اجرا روی سرورهای مختلف دارند تا همه سرورها همزمان بیدار نشوند و پیکربندی اجرا نکنند.[۱] گاهی میخواهید کد سریعتر اعمال شود — شاید برای fix یا پشتیبانی deploy نرمافزار. ابزارهای مختلف راهحلهای متفاوت دارند.
[۱] برای نمونه، گزینه chef-client --splay را ببینید.
الگوهای مرتبط (Related patterns)
همگامسازی مداوم با push («الگو: Push Server Configuration» در صفحه ۱۹۸) یا pull («الگو: Pull Server Configuration» در صفحه ۲۰۰) پیادهسازی میشود. جایگزین: سرورهای immutable («الگو: Immutable Server» در صفحه ۱۹۵).
الگو: سرور Immutable (Immutable Server)
سرور immutable نمونهای است که پیکربندی آن هرگز تغییر نمیکند. تغییرات را با ایجاد نمونه جدید با پیکربندی تغییریافته و جایگزینی نمونه موجود تحویل میدهید.[۲]
[۲] همکارم Peter Gillard-Moss و همکار سابق Ben Butler-Cole وقتی روی پلتفرم SaaS Mingle در ThoughtWorks کار میکردند از سرورهای immutable استفاده کردند.
انگیزه (Motivation)
سرورهای immutable ریسک اعمال تغییر را کاهش میدهند. بهجای اعمال تغییر روی نمونه در حال اجرا، نمونه جدید میسازید. فرصت آزمایش نمونه جدید، swap با نمونه قبلی، بررسی درست کار کردن، و سپس destroy نمونه اصلی — یا swap برگشت اگر مشکلی پیش آمد.
کاربرد (Applicability)
سازمانهایی که کنترل و سازگاری سختگیرانه پیکربندی سرور نیاز دارند ممکن است سرورهای immutable مفید بدانند. مثلاً شرکت مخابراتی که هزاران image سرور اجرا میکند ممکن است تصمیم بگیرد تغییر روی سرورهای در حال اجرا اعمال نکند و پایداری پیکربندی را تضمین کند.
پیامدها (Consequences)
پیادهسازی سرورهای immutable به فرایند خودکار قوی برای ساخت، آزمایش و بهروزرسانی image سرور نیاز دارد (فصل ۱۳). طراحی سیستم و برنامه باید swap نمونه سرور بدون قطع سرویس را پشتیبانی کند (ایدهها در «تغییر زیرساخت زنده» در صفحه ۳۶۸).
با وجود نام، سرورهای immutable تغییر میکنند.[۳] configuration drift ممکن است نفوذ کند — بهویژه اگر مردم login کنند و دستی تغییر دهند بهجای فرایند تغییر پیکربندی برای ساخت نمونه جدید. پس تیمهایی که immutable server استفاده میکنند باید تازگی نمونههای در حال اجرا را تضمین کنند. کاملاً ممکن است immutable server را با ضدالگوی apply on change («ضدالگو: اعمال هنگام تغییر» در صفحه ۱۹۲) ترکیب کرد — که سرورهایی میدهد که مدت طولانی بدون تغییر اجرا میشوند و patch و بهبودهای سرورهای ساختهشده بعداً را شامل نمیشوند. تیمها باید دسترسی به سرور را غیرفعال کنند، یا دسترسی و تغییر دستی سرویسها را با فرایند «break glass» نیاز دهند.[۴]
[۳] برخی اعتراض کردهاند که زیرساخت immutable رویکرد نامعتبری است چون جنبههای سرور — از جمله log، حافظه و فضای فرایند — قابل تغییرند. این استدلال شبیه رد «serverless computing» چون پشت صحنه از سرور استفاده میکند. اصطلاح استعاره است. با وجود ناقص بودن استعاره، رویکی که توصیف میکند برای بسیاری مفید است.
[۴] فرایند «break glass» برای دسترسی elevated موقت در emergency استفاده میشود. معمولاً بسیار visible است تا استفاده routine را discourage کند. اگر مردم به break glass تکیه کنند، تیم باید ببیند چه کارهایی مجبورشان میکند و راه پشتیبانی بدون آن پیدا کند. وبینار Derek A. Smith «Break Glass Theory» را ببینید.
پیادهسازی (Implementation)
بیشتر تیمهایی که immutable server استفاده میکنند bulk پیکربندی را در image سرور handle میکنند و baking image («Baking Server Images» در صفحه ۱۸۷) را به frying نمونه ترجیح میدهند. پس pipeline یا مجموعه pipelineها برای ساخت و بهروز خودکار image سرور پایه immutable server است.
میتوانید پیکربندی را روی نمونه immutable fry کنید («Frying a Server Instance» در صفحه ۱۸۶)، بهشرط بعد از ایجاد به نمونه تغییر ندهید. اما شکل سختگیرتر immutable server از افزودن هر تفاوتی به نمونه سرور اجتناب میکند. image سرور را میسازید و آزمایش میکنید، سپس از یک محیط به بعدی promote میکنید. چون با هر نمونه سرور تقریباً چیزی تغییر نمیکند، ریسک creep مشکل از محیطی به محیط دیگر کمتر است.
الگوهای مرتبط (Related patterns)
معمولاً برای پشتیبانی immutable server سرورها bake میشوند («Baking Server Images» در صفحه ۱۸۷). همگامسازی مداوم («الگو: همگامسازی مداوم پیکربندی» در صفحه ۱۹۴) رویکرد مخالف — اعمال routine تغییر روی نمونه در حال اجرا. سرورهای immutable زیرمجموعه زیرساخت immutable («Immutable Infrastructure» در صفحه ۳۵۱) هستند.
Patch کردن سرورها
بسیاری تیمها به patch سرور بهعنوان فرایند خاص و جدا عادت دارند. اما اگر pipeline خودکار تغییرات به سرور دارید و کد سرور را بهطور مداوم با سرورهای موجود همگام میکنید، میتوانید همان فرایند را برای patch نگه داشتن سرورها استفاده کنید.
تیمهایی که باهاشان کار کردم آخرین patch امنیتی OS و بستههای هسته را هفتگی — و گاه روزانه — pull، test و deliver میکنند.
این فرایند patch سریع و مکرر CIO یکی از مشتریانم را تحت تأثیر قرار داد وقتی مطبوعات business آسیبپذیری امنیتی پرنمایش در بسته هسته OS را سر صدا کرد. CIO خواست همه چیز را رها کنیم و برنامه برای رفع آسیبپذیری با تخمین زمان و هزینه انحراف منابع بسازیم. خوشحال شدند وقتی گفتیم patch رفع مشکل قبلاً بخشی از بهروزرسانی routine همان صبح rollout شده بود.
چگونه کد پیکربندی سرور را اعمال کنیم
بعد از الگوهای مدیریت زمان اعمال کد پیکربندی روی سرورها، این بخش الگوهای تصمیم درباره چگونه اعمال کد روی نمونه سرور را بحث میکند.
این الگوها برای تغییر سرورها — بهویژه بخشی از فرایند همگامسازی مداوم («الگو: همگامسازی مداوم پیکربندی» در صفحه ۱۹۴) — مرتبطاند. اما هنگام ساخت نمونه سرور جدید برای fry پیکربندی روی نمونه («Frying a Server Instance» در صفحه ۱۸۶) هم استفاده میشوند. و هنگام ساخت image سرور (فصل ۱۳) هم باید الگو انتخاب کنید.
با نمونه سرور — چه جدید در حال ساخت، چه موقت برای ساخت image، چه موجود — دو الگو برای اجرای ابزار پیکربندی سرور برای اعمال کد وجود دارد: push و pull.
الگو: Push Server Configuration
در الگوی push server configuration، فرایندی خارج از نمونه سرور جدید به سرور متصل میشود و اجرا میکند، کد را دانلود و اعمال میکند.
انگیزه (Motivation)
تیمها push را برای اجتناب از preinstall ابزار پیکربندی سرور روی image سرور استفاده میکنند.
کاربرد (Applicability)
الگوی push وقتی کنترل بیشتری روی زمانبندی بهروزرسانی پیکربندی سرورهای موجود نیاز دارید مفید است. مثلاً اگر رویدادهایی مثل deploy نرمافزار با دنباله فعالیتها روی چند سرور دارید، میتوانید با فرایند متمرکز orchestrate کنید.
پیامدها (Consequences)
الگوی push configuration نیاز به اتصال به نمونه سرور و اجرای فرایند پیکربندی روی شبکه دارد. این میتواند آسیبپذیری امنیتی ایجاد کند چون vectorی باز میکند که مهاجم ممکن است برای اتصال و تغییر غیرمجاز استفاده کند.
اجرای push configuration برای نمونههایی که بستر خودکار ایجاد میکند («پیکربندی بستر برای ایجاد خودکار سرورها» در صفحه ۱۸۲) — مثلاً autoscaling یا recovery خودکار — میتواند awkward باشد. اما امکانپذیر است.
پیادهسازی (Implementation)
یک راه push این است که کسی ابزار پیکربندی سرور را از کامپیوتر محلی اجرا کند. اما همانطور که در «اعمال کد از سرویس متمرکز» در صفحه ۳۴۵ بحث شد، بهتر است ابزار از سرور یا سرویس متمرکز اجرا شود تا سازگاری و کنترل فرایند تضمین شود.
برخی ابزارهای پیکربندی سرور برنامه سرور برای مدیریت اتصال به نمونه ماشین دارند، مثل Ansible Tower. برخی شرکتها SaaS برای پیکربندی remote نمونه سرور ارائه میدهند، اگرچه بسیاری سازمانها control این سطح روی زیرساخت را به third party نمیدهند.
در موارد دیگر، خودتان سرویس متمرکز برای اجرای ابزار پیکربندی سرور میسازید. بیشتر دیدهام تیمها با محصول CI یا CD این کار را میکنند. job CI یا مرحله pipeline که ابزار پیکربندی را روی مجموعه سرورها اجرا میکند. job بر اساس رویداد trigger میشود — مثل تغییر کد پیکربندی سرور یا ایجاد محیط جدید.
ابزار پیکربندی سرور باید بتواند به نمونه سرور متصل شود. برخی ابزارها پروتکل شبکه سفارشی استفاده میکنند، اما بیشتر SSH. هر نمونه سرور باید اتصال SSH از ابزار را بپذیرد و ابزار با privilege کافی برای اعمال تغییرات پیکربندی اجرا شود.
authentication قوی و secrets management برای این اتصالات ضروری است. وگرنه سیستم پیکربندی سرور سوراخ امنیتی enorm برای estate است.
هنگام ایجاد و پیکربندی نمونه سرور جدید، میتوانید secret authentication جدید — مثل SSH key — بهصورت پویا تولید کنید. بیشتر بسترهای زیرساخت راهی برای تنظیم key هنگام ایجاد نمونه دارند. ابزار پیکربندی سرور میتواند از این secret استفاده کند و شاید key را وقتی دیگر لازم نیست disable و discard کند.
اگر باید تغییرات پیکربندی روی نمونههای موجود اعمال کنید — مثل همگامسازی مداوم — به روش بلندمدتتری برای authenticate اتصال از ابزار پیکربندی نیاز دارید. سادهترین روش نصب یک key روی همه نمونههای سرور است. اما این single key آسیبپذیری است. اگر expose شود، مهاجم ممکن است به هر سرور estate دسترسی پیدا کند.
جایگزین: key منحصربهفرد برای هر نمونه سرور. دسترسی به این keyها را طوری مدیریت کنید که ابزار پیکربندی سرور به آنها دسترسی داشته باشد و ریسک مهاجم که همان دسترسی را بگیرد — مثلاً با compromise سروری که ابزار روی آن اجرا میشود — کم شود. توصیه «مدیریت Secrets بهعنوان پارامتر» در صفحه ۱۰۲ مرتبط است.
رویکردی که بسیاری سازمانها استفاده میکنند: چند سرور یا سرویس برای مدیریت پیکربندی سرور. estate به realmهای امنیتی مختلف تقسیم میشود و هر نمونه سرویس پیکربندی سرور فقط به یکی دسترسی دارد. این دامنه compromise را کاهش میدهد.
الگوهای مرتبط (Related patterns)
جایگزین الگوی push، الگوی pull server configuration است.
الگو: Pull Server Configuration
الگوی pull server configuration فرایندی روی خود نمونه سرور دارد که کد پیکربندی را دانلود و اعمال میکند. این فرایند هنگام ایجاد نمونه سرور جدید trigger میشود. برای نمونههای موجود تحت الگوی همگامسازی مداوم، فرایند معمولاً روی schedule اجرا میشود — دورهای بیدار میشود و پیکربندی فعلی را اعمال میکند.
انگیزه (Motivation)
پیکربندی سرور مبتنی بر pull از نیاز به پذیرش اتصال ورودی از سرور متمرکز توسط نمونه سرور اجتناب میکند، پس attack surface کمتر میشود. الگو پیکربندی نمونههای ایجادشده خودکار توسط بستر زیرساخت — مثل autoscaling و recovery خودکار («پیکربندی بستر برای ایجاد خودکار سرورها» در صفحه ۱۸۲) — را ساده میکند.
کاربرد (Applicability)
میتوانید pull-based server configuration را وقتی image سرور با ابزار پیکربندی سرور preinstall شده بسازید یا استفاده کنید پیادهسازی کنید.
پیادهسازی (Implementation)
pull configuration با image سروری که ابزار پیکربندی سرور preinstall دارد کار میکند. اگر برای نمونه سرور جدید pull میکنید، image را طوری پیکربندی کنید که ابزار در اولین boot اجرا شود.
cloud-init ابزار پرکاربرد برای اجرای خودکار این نوع فرایند است. میتوانید پارامترها را با API بستر زیرساخت به نمونه سرور جدید بدهید — حتی شامل دستور اجرا و پارامتر برای ابزار پیکربندی سرور (مثال ۱۲-۱ را ببینید).
مثال ۱۲-۱. نمونه کد پشته که اسکریپت setup اجرا میکند
server:
source_image: stock-linux-1.23
memory: 2GB
vnet: ${APPSERVER_VNET}
instance_data:
- server_tool: servermaker
- parameter: server_role=appserver
- parameter: code_repo=servermaker.shopspinner.xyzاسکریپت را طوری پیکربندی کنید که کد پیکربندی را از مخزن متمرکز دانلود و در startup اعمال کند. اگر همگامسازی مداوم برای بهروز سرورهای در حال اجرا استفاده میکنید، فرایند setup باید این را پیکربندی کند — چه اجرای background process برای ابزار پیکربندی سرور، چه cron job برای اجرای دورهای ابزار.
حتی اگر image سرور خودتان را نمیسازید، بیشتر imageهای ارائهشده توسط cloud vendor عمومی cloud-init و ابزارهای محبوب پیکربندی سرور preinstall دارند.
چند ابزار دیگر، بهویژه Saltstack، از رویکرد messaging و event-based برای trigger پیکربندی سرور استفاده میکنند. هر نمونه سرور agentی اجرا میکند که به service bus مشترک متصل میشود و از آن دستور اعمال کد پیکربندی دریافت میکند.
الگوهای مرتبط (Related patterns)
جایگزین الگوی pull، الگوی push server configuration («الگو: Push Server Configuration» در صفحه ۱۹۸) است.
پیکربندی غیرمتمرکز (Decentralized Configuration)
بیشتر ابزارهای پیکربندی سرور سرویس متمرکز ارائه میدهند که روی ماشین یا کلاستر اجرا میشود تا توزیع کد پیکربندی و پارامترها و سایر فعالیتها را متمرکز کنترل کند. برخی تیمها بدون سرویس متمرکز کار میکنند.
دلیل اصلی غیرمتمرکز کردن، سادهسازی مدیریت زیرساخت است. configuration server مجموعه دیگری از قطعات برای مدیریت است و میتواند single point of failure باشد. اگر configuration server down باشد، نمیتوانید ماشین جدید بسازید — وابستگی disaster recovery میشود. configuration serverها ممکن است bottleneck عملکرد هم باشند و برای اتصال از (و شاید به) صدها یا هزاران نمونه سرور scale نیاز داشته باشند.
برای پیادهسازی پیکربندی غیرمتمرکز، ابزار پیکربندی سرور را در حالت offline نصب و اجرا کنید — مثل
chef-soloبهجایchef-client. ممکن است ابزار را از اسکریپت اجرا کنید که مخزن فایل متمرکز را برای دانلود آخرین نسخه کد پیکربندی سرور check میکند. کد روی نمونه سرور محلی ذخیره میشود تا ابزار حتی اگر مخزن فایل در دسترس نباشد اجرا شود.مخزن فایل متمرکز ممکن است single point of failure یا bottleneck عملکرد باشد، مثل configuration server. اما در عمل، گزینههای ساده، بسیار reliable و performant زیادی برای میزبانی فایلهای static مثل پیکربندی سرور وجود دارد — web server، file server شبکهای و سرویس object storage مثل AWS S3.
روش دیگر: بستهبندی کد پیکربندی سرور در بسته سیستم مثل
.rpmیا.debو میزبانی در مخزن بسته خصوصی. فرایند منظمyum updateیاapt-get updateاجرا میکند که بسته را نصب یا بهروز میکند و کد پیکربندی سرور را در directory محلی کپی میکند.
رویدادهای دیگر چرخه عمر سرور
ایجاد، تغییر و destroy نمونه سرور چرخه عمر پایه سرور را تشکیل میدهد. اما فازهای جالب دیگری در چرخه عمر گسترده هست — از جمله stop و restart سرور (شکل ۱۲-۱)، جایگزینی سرور و recovery سرور failed.
توقف و راهاندازی مجدد نمونه سرور
وقتی بیشتر سرورها دستگاه فیزیکی وصل به برق بودند، معمولاً برای ارتقای سختافزار shutdown میکردیم، یا برای ارتقای برخی اجزای OS reboot میکردیم.
شکل ۱۲-۱. چرخه عمر سرور — توقف و راهاندازی مجدد
مردم هنوز سرور مجازی را stop و reboot میکنند — گاه به همان دلایل: reconfigure سختافزار مجازی یا ارتقای kernel OS. گاه سرور را shutdown میکنیم تا هزینه hosting صرفهجویی شود. مثلاً برخی تیمها سرور development و test را عصرها یا آخر هفته shutdown میکنند اگر کسی استفاده نمیکند.
اگر rebuild سرور آسان باشد، بسیاری تیمها وقتی استفاده نمیشوند سرور را destroy میکنند و وقتی دوباره لازم است سرور جدید میسازند. تا حدی چون آسان است و شاید کمی بیشتر از shutdown پول save میکند. اما destroy و rebuild بهجای stop و نگهداشتن با فلسفه treat کردن سرور مثل «گاو» نه «حیوان خانگی» («Cattle, Not Pets» در صفحه ۱۶) همخوان است. تیمها ممکن است stop و restart کنند چون rebuild با اطمینه نمیتوانند. اغلب چالش حفظ و restore داده برنامه است. «تداوم داده در سیستم در حال تغییر» در صفحه ۳۸۲ را برای handle این چالش ببینید.
پس سیاست «stop و restart نکن» تیم را مجبور میکند فرایند و ابزار reliable برای rebuild سرور پیاده کند و کار آنها را حفظ کند.
داشتن سرورهای stopped فعالیتهای نگهداری را هم پیچیده میکند. بهروزرسانی پیکربندی و patch سیستم روی سرورهای stopped اعمال نمیشود. بسته به نحوه مدیریت آن بهروزرسانیها، سرورها ممکن است هنگام start دوباره دریافت کنند، یا از قلم بیفتند.
جایگزینی نمونه سرور
یکی از مزایای زیاد رفتن از سرور فیزیکی به مجازی، سهولت ساخت و جایگزینی نمونه سرور است. بسیاری از الگوها و practices این کتاب — از جمله سرورهای immutable («الگو: سرور Immutable» در صفحه ۱۹۵) و بهروزرسانی مکرر image سرور — به توانایی جایگزینی سرور در حال اجرا با ساخت جدید وابستهاند (شکل ۱۲-۲).
شکل ۱۲-۲. چرخه عمر سرور — جایگزینی نمونه سرور
فرایند essential جایگزینی نمونه سرور: ایجاد نمونه جدید، validate آمادگی، reconfigure زیرساخت و سیستمهای دیگر برای استفاده از نمونه جدید، test درست کار کردن، سپس destroy نمونه قدیم.
بسته به برنامهها و سیستمهایی که از نمونه سرور استفاده میکنند، ممکن است جایگزینی بدون downtime یا با downtime minimal ممکن باشد. توصیه در «تغییر زیرساخت زنده» در صفحه ۳۶۸.
برخی بسترهای زیرساخت قابلیت automate فرایند جایگزینی سرور دارند. مثلاً ممکن است تغییر پیکربندی در تعریف سرورها در کلاستر autoscaling server اعمال کنید و مشخص کنید image سرور جدید با patch امنیتی استفاده شود. بستر خودکار نمونه جدید اضافه، سلامت check و نمونه قدیم حذف میکند.
در موارد دیگر، ممکن است خودتان کار جایگزینی سرور را انجام دهید. یک راه در سیستم تحویل تغییر مبتنی بر pipeline، expand and contract است. اول تغییری push میکنید که سرور جدید اضافه کند، سپس تغییری که سرور قدیم را حذف کند. «Expand and Contract» در صفحه ۳۷۲ را ببینید.
بازیابی سرور از کار افتاده
زیرساخت ابری لزوماً reliable نیست. برخی providerها، از جمله AWS، صریحاً هشدار میدهند ممکن است بدون اطلاع قبلی نمونه سرور را terminate کنند — مثلاً وقتی تصمیم به جایگزینی سختافزار زیرین میگیرند.[۵] حتی providerها با تضمین availability قویتر failure سختافزاری دارند که سیستمهای میزبانیشده را تحت تأثیر قرار میدهد.
فرایند recovery سرور failed شبیه جایگزینی سرور است. یک تفاوت ترتیب فعالیتها — نمونه جدید بعد از destroy نمونه قدیم میسازید، نه قبل (شکل ۱۲-۳). تفاوت دیگر اینکه جایگزینی معمولاً عمدی است، failure کمتر intentional.[۶] مثل جایگزینی، recovery ممکن است action دستی نیاز داشته باشد، یا بتوانید بستر و سرویسهای دیگر را برای detect و recover خودکار failure پیکربندی کنید.
[۵] Amazon مستندات سیاست retirement instance را ارائه میدهد.
[۶] استثنا chaos engineering است — practice عمدی ایجاد failure برای اثبات recoverability. «Chaos Engineering» در صفحه ۳۷۹ را ببینید.
شکل ۱۲-۳. چرخه عمر سرور — بازیابی نمونه سرور از کار افتاده
جمعبندی
الگوهایی برای زمان اعمال تغییرات پیکربندی روی سرورها — هنگام تغییر، با اعمال مداوم کد روی سرورهای در حال اجرا، یا با ایجاد نمونه جدید — را بررسی کردیم. الگوهای چگونگی اعمال تغییرات — push و pull — را هم دیدیم. در نهایت، برخی رویدادهای دیگر چرخه عمر سرور — stop، جایگزینی و recovery — را لمس کردیم.
این فصل، همراه با فصل قبلی درباره ایجاد سرورها، رویدادهای هسته چرخه عمر سرور را پوشش میدهد. با این حال، بسیاری از رویکردهای ایجاد و تغییر سرورهایی که بحث کردیم با سفارشیسازی image سرور کار میکنند که سپس برای ایجاد یا بهروز چند نمونه سرور استفاده میکنید. پس فصل بعد رویکردهای تعریف، ساخت و بهروزرسانی image سرور را بررسی میکند.