SSD Nodes Learn Hosting plans →
راهنماها Matt Connorتوسط Matt Connor

بررسی توزیع‌های لینوکس تغییرناپذیر (Immutable) برای سرور

توزیع‌های Immutable مانند Fedora CoreOS یا Talos سیستم را به صورت یک ایمیج واحد مدیریت می‌کنند. در این مطلب هزینه‌ها و چالش‌های استفاده از این سیستم‌ها در VPS را بررسی می‌کنیم.

توزیع لینوکس تغییرناپذیر (Immutable) چیست

یک توزیع لینوکس تغییرناپذیر، سیستم‌عامل را به صورت یک ایمیج واحد ارائه می‌دهد؛ بنابراین به‌جای وصله‌کردن (patch) سیستم در محل، کل آن را جایگزین می‌کنید. در یک سیستم در حال اجرا، هیچ بازنویسی فایلی در apt upgrade تحت /usr وجود ندارد. شما یک ایمیج جدید می‌سازید یا دریافت می‌کنید، دستگاه آن را در کنار ایمیج فعلی آماده می‌کند و با reboot بعدی، ایمیج فعال تغییر می‌کند. ایمیج قبلی همچنان روی دیسک باقی می‌ماند، بنابراین بازگرداندن یک به‌روزرسانی ناموفق تنها با یک reboot انجام می‌شود.

واژه «تغییرناپذیر» (immutable) کمی اغراق‌آمیز است. هیچ مانع فیزیکی وجود ندارد که root را از نوشتن روی دیسک بازدارد. کاری که این سیستم‌ها انجام می‌دهند این است که دایرکتوری‌های سیستمی را به صورت read-only mount می‌کنند و مالکیت آن‌ها را به ایمیج می‌سپارند. داده‌های ماندگار در /var قرار می‌گیرند. پیکربندی‌های مختص هر ماشین در /etc ذخیره می‌شوند. هر چیزی در /usr متعلق به ایمیج است؛ به همین دلیل است که دو سرور با یک تگ ایمیج مشابه، فایل‌های سیستمی یکسانی دارند.

نام‌گذاری‌های Red Hat برای این دو مدل، واضح‌ترین آن‌هاست: حالت بسته (package mode) و حالت ایمیج (image mode). حالت بسته، یک سیستم در حال اجرا به همراه یک مدیر بسته است که آن را ویرایش می‌کند. حالت ایمیج، یک مرحله ساخت در جایی دیگر است که یک آرتیفکت تولید می‌کند، و سروری که تنها وظیفه‌اش بوت کردن آرتیفکتی است که به آن اشاره می‌کنید. تمام موارد زیر از همین یک تفاوت ناشی می‌شوند.

چرا سیستم فقط‌خواندنی (read-only) در سرور اهمیت بیشتری دارد

سروری که دو سال در حال اجرا بوده، تاریخی دارد که هیچ‌کس آن را ثبت نکرده است. یک make install از یک شب پرشتاب. یک مخزن شخص ثالث که برای نصب یک بسته اضافه شده است. یک فایل پیکربندی که در حین قطعی ویرایش شده و هرگز به سیستم مدیریت پیکربندی شما بازگردانده نشده است. نام این پدیده «انحراف پیکربندی» (configuration drift) است و به همین دلیل است که بازسازی «همان» سرور بر اساس یادداشت‌هایتان، اغلب منجر به تولید ماشینی می‌شود که رفتار متفاوتی دارد. یادداشت‌ها حاوی نیت شما هستند، اما دیسک حاوی حقیقت است.

حالت Image mode مکانی که انحراف در آن جمع می‌شود را حذف می‌کند. /usr در زمان اجرا فقط‌خواندنی است، بنابراین نصبی که به‌صورت دستی انجام شود یا بلافاصله با شکست مواجه می‌شود یا به‌عنوان لایه‌ای ثبت می‌گردد که می‌توانید با یک دستور آن را فهرست کنید. این موضوع باعث می‌شود تفاوت بین دو ماشین به‌جای آنکه مانند باستان‌شناسی باشد، کاملاً قابل مشاهده شود. این همان مشکلی است که چک‌لیست نگهداری معمول سرور لینوکس با انضباط شخصی به آن می‌پردازد، اما در اینجا توسط سیستم فایل مدیریت می‌شود.

بازگشت به نسخه قبل (Rollback) تنها یک ریبوت است و همین تمام ماجراست

شکستی که این مدل برای آن طراحی شده، همان موردی است که قبلاً مستند کرده‌ایم: یک VPS که پس از به‌روزرسانی هسته (kernel) بوت نمی‌شود. در حالت package-based، شما از طریق کنسول rescue ارائه‌دهنده بازیابی را انجام می‌دهید. دیسک را mount می‌کنید، chroot می‌شوید و یک بسته هسته را به‌صورت دستی حذف می‌کنید. این روش کار می‌کند چون bootloader هسته‌های قدیمی را نگه می‌دارد، اما فقط هسته است که به این شکل نسخه‌بندی می‌شود. به‌روزرسانی glibc و تغییرات systemd که در همان تراکنش اعمال شده‌اند، قبلاً جای‌گذاری شده‌اند و هیچ دستور واحدی آن‌ها را با هم به عقب برنمی‌گرداند.

در حالت image-based، واحد اصلی کل سیستم است. روی یک میزبان bootc:

sudo bootc status
sudo bootc rollback
sudo systemctl reboot

دستور bootc rollback ترتیب bootloader را به ورودی بوت قبلی برمی‌گرداند؛ یعنی همان تصویری (image) که یک ساعت پیش اجرا می‌کردید، شامل هسته و فضای کاربری (userspace) با هم. هیچ چیزی دانلود یا بازسازی نمی‌شود، چون تصویر قدیمی هرگز دیسک را ترک نکرده است. اگر تایمر به‌روزرسانی خودکار را که در ادامه توضیح داده شده فعال کرده‌اید، ابتدا آن را متوقف کنید: مستندات bootc هشدار می‌دهند که عاملی (agent) که ارتقاهای خودکار را انجام می‌دهد، می‌تواند rollback را خنثی کند.

Fedora CoreOS همین کار را با نام‌های متفاوتی انجام می‌دهد:

sudo systemctl stop zincati.service
sudo rpm-ostree rollback -r

ابتدا Zincati را متوقف کنید. Zincati عاملی است که ماشین Fedora CoreOS را روی جدیدترین نسخه نگه می‌دارد. این عامل، نسخه‌ای که به‌تازگی به آن بازگشته‌اید را دوباره نصب نمی‌کند، اما همچنان به جستجوی به‌روزرسانی‌ها ادامه می‌دهد و به محض انتشار نسخه جدیدتر، آن را ارتقا می‌دهد؛ بنابراین اگر قرار است ماشین تا زمان انتشار اصلاحیه در همین وضعیت باقی بماند، sudo systemctl disable --now zincati.service را اجرا کنید. دستور -r پس از آماده‌سازی rollback، سیستم را ریبوت می‌کند. برای جلوگیری از حذف نسخه‌ای که به آن اطمینان دارید توسط garbage collector:

sudo ostree admin pin 0
rpm-ostree status

دستور rpm-ostree status نسخه‌های مستقر (deployments) را به ترتیبی که bootloader ارائه می‌دهد فهرست می‌کند، نسخه در حال اجرا را با یک نقطه مشخص می‌کند و روی نسخه‌ای که پین کرده‌اید، Pinned: yes را نمایش می‌دهد.

Talos این کار را با یک فراخوانی API از ایستگاه کاری شما انجام می‌دهد:

talosctl rollback --nodes 10.20.30.40

Flatcar دو پارتیشن /usr نگه می‌دارد و بین آن‌ها سوئیچ می‌کند. هر اسلات دارای یک اولویت و یک شمارنده تلاش در جدول پارتیشن است؛ بنابراین اسلاتی که هرگز با موفقیت بوت نشود، تعداد تلاش‌هایش تمام شده و bootloader اسلات دیگر را انتخاب می‌کند. بررسی کنید که در کدام اسلات هستید و آیا وضعیت آن به عنوان سالم (good) علامت‌گذاری شده است یا خیر:

sudo cgpt show "$(rootdev -s /usr)" | grep successful=1

یک اسلات سالم در حال اجرا، خطی شامل tries=0 successful=1 چاپ می‌کند. عدد اولویت در همان خط فقط نشان‌دهنده ترجیح bootloader برای اسلات است، بنابراین در یک ماشین کاملاً سالم می‌تواند 1 یا 2 باشد. عدم وجود خط مشابه به این معنی است که اسلات فعلی هرگز تأیید نشده است؛ این وضعیتی است که ماشین بین یک به‌روزرسانی و اولین بوت موفق خود در آن قرار دارد.

جایگزین «نصب بسته»: bootc و Containerfile

ابزار bootc این الگو را تعمیم داده است. این ابزار خود را به‌روزرسانی تراکنشی و درجا (in-place) سیستم‌عامل با استفاده از ایمیج‌های کانتینری OCI (مخفف Open Container Initiative) معرفی می‌کند و یک پروژه در CNCF Sandbox است. در این مدل، سرور شما به یک Containerfile تبدیل می‌شود. تا اوت 2026، ایمیج پایه Fedora برابر با quay.io/fedora/fedora-bootc:44 و ایمیج پایه CentOS Stream برابر با quay.io/centos-bootc/centos-bootc:stream10 است.

FROM quay.io/fedora/fedora-bootc:44
RUN dnf -y install nginx && dnf clean all
RUN systemctl enable nginx

آن را مانند هر ایمیج دیگری بسازید و push کنید:

sudo podman build -t registry.example.com/edge/web:2026-08-19 .
sudo podman push registry.example.com/edge/web:2026-08-19

سپس روی سرور:

sudo bootc upgrade --check
sudo bootc upgrade --apply

دستور bootc upgrade منبع ایمیج را پرس‌وجو کرده و ایمیج جدید را برای بوت بعدی در صف قرار می‌دهد. دستور --check گزارش می‌دهد که آیا به‌روزرسانی موجود است یا خیر و هیچ تغییری ایجاد نمی‌کند. دستور --apply سیستم را با ایمیج جدید ریبوت می‌کند. دستور bootc switch registry.example.com/edge/web:next دستگاه را به یک ایمیج متفاوت اشاره می‌دهد، در حالی که /etc و /var حفظ می‌شوند؛ این همان روشی است که بدون نیاز به نصب مجدد، سرور را بین جریان‌های ایمیج مختلف جابه‌جا می‌کنید.

برای به‌روزرسانی‌های خودکار (unattended)، تایمری که همراه پروژه ارائه می‌شود را فعال کنید:

sudo systemctl enable --now bootc-fetch-apply-updates.timer

این پاسخِ «حالت ایمیج» (image-mode) به unattended upgrades در اوبونتو و dnf-automatic در راکی و آلما است. تفاوت در چیزی است که اعمال می‌شود. تایمر در «حالت بسته» (package-mode) هر نسخه‌ای که آن شب در مخزن موجود باشد را اعمال می‌کند، بنابراین مجموعه نهایی بسته‌ها در هر ماشین کمی متفاوت خواهد بود. تایمر در «حالت ایمیج» یک آرتیفکت واحد را اعمال می‌کند که قبلاً در جای دیگری آن را بوت کرده‌اید.

دو قانون ساخت از آن Containerfile استخراج می‌شود. داده‌های قابل‌نوشتن متعلق به /var هستند، بنابراین نرم‌افزاری که اصرار دارد داخل دایرکتوری نصب خود بنویسد، به یک symlink یا یک خط BindPaths= در systemd نیاز دارد که در زمان ساخت اضافه شود. همچنین /etc هنگام به‌روزرسانی به صورت three-way merge ادغام می‌شود؛ این یعنی فایلی که هرگز تغییر نداده‌اید، نسخه جدید ایمیج را دریافت می‌کند، در حالی که فایلی که به‌صورت محلی ویرایش کرده‌اید، حفظ می‌شود.

هنگامی که برای یک جلسه عیب‌یابی به ابزاری روی یک سیستم زنده نیاز دارید:

sudo bootc usr-overlay
sudo dnf -y install strace

این دستور یک لایه (overlay) موقت و قابل‌نوشتن روی /usr اضافه می‌کند که در ریبوت بعدی حذف می‌شود. این کار برای بررسی مشکل است، نه برای رفع آن. شما نمی‌توانید هسته (kernel) را به این روش تغییر دهید و هر چیزی که نصب می‌کنید طبق طراحی، با ریبوت ناپدید می‌شود.

Fedora CoreOS: یک‌بار پیکربندی، به‌روزرسانی همیشگی

Fedora CoreOS فاقد نصب‌کننده تعاملی است. شما یک فایل Butane YAML می‌نویسید، آن را به Ignition JSON تبدیل می‌کنید و در اولین بوت به ماشین تحویل می‌دهید:

podman run --interactive --rm quay.io/coreos/butane:release \
       --pretty --strict < your_config.bu > transpiled_config.ign

Ignition فقط در اولین بوت و در محیط initramfs اجرا می‌شود. این بخشی است که کاربرانِ آشنا با cloud-init را به اشتباه می‌اندازد. اگر پیکربندی فاقد کلید SSH باشد، ماشین بدون هیچ راه ورودی بالا می‌آید و تنها راه حل، پیکربندی مجدد از صفر است. پیش از اعمال پیکربندی روی سرور اصلی، آن را روی یک ماشین آزمایشی تست کنید.

نصب روی دیسک از یک محیط live:

sudo coreos-installer install /dev/sda \
    --ignition-url https://example.com/example.ign

به‌روزرسانی‌ها به‌صورت پیش‌فرض خودکار هستند. شما زمان آن را کنترل می‌کنید، نه اصلِ انجام آن را. یک فایل TOML در مسیر /etc/zincati/config.d/55-updates-strategy.toml قرار دهید که استراتژی دوره‌ای را تعیین می‌کند:

[updates]
strategy = "periodic"

تحت این استراتژی، برای هر ورودی در آرایه جداول، یک پنجره نگهداری (maintenance window) اضافه می‌کنید؛ به‌طوری که هر پنجره با نام updates.periodic.window داخل دو کروشه به عنوان سرتیتر شروع شده و با سه کلید دنبال می‌شود:

  • days، فهرستی از نام روزها، مانند "Sat" و "Sun".
  • start_time، لحظه باز شدن پنجره، که به صورت "22:30" نوشته می‌شود.
  • length_minutes، مدت زمان باز ماندن پنجره، مانند 60.

این زمان‌ها بر اساس UTC هستند. برای توقف کامل به‌روزرسانی‌ها، دستور sudo systemctl disable --now zincati.service را اجرا کنید و بپذیرید که اکنون مسئولیت زمان‌بندی وصله‌ها (patching) بر عهده شماست.

قابلیت Package layering به عنوان یک راه خروج اضطراری وجود دارد:

sudo rpm-ostree install --allow-inactive vim
sudo systemctl reboot

این دستور یک deployment جدید با بسته اضافه شده می‌سازد و تغییرات تنها پس از reboot اعمال می‌شوند. هزینه این کار بعداً مشخص می‌شود. مجموعه بسته‌های لایه‌بندی‌شده شما روی هر ایمیج پایه جدید دوباره اعمال می‌شود؛ بنابراین اگر بسته‌ای در روز به‌روزرسانی از مخزن حذف شده باشد، آن به‌روزرسانی با شکست مواجه خواهد شد. مستندات خودِ Fedora برای هر کار اساسی، شما را به سمت استفاده از کانتینرها و برای زمانی که واقعاً نیاز به تغییر سیستم‌عامل دارید، به سمت استفاده از ایمیج‌های bootc هدایت می‌کند.

Flatcar Container Linux: بدون هیچ‌گونه مدیر بسته

Flatcar ادامهٔ مسیر CoreOS Container Linux و سخت‌گیرانه‌ترین گزینه در میان سیستم‌عامل‌های عمومی است. در این سیستم هیچ مدیر بسته‌ای برای استفاده وجود ندارد. هر چیزی که اجرا می‌کنید، یک container است. تأمین منابع (Provisioning) از طریق Ignition انجام می‌شود که مشابه Fedora CoreOS است. به‌روزرسانی‌ها از طریق دو پارتیشن A/B که در /usr ذکر شد صورت می‌گیرد و توسط update_engine مدیریت می‌شود؛ در حالی که locksmithd زمان راه‌اندازی مجدد (reboot) را تعیین می‌کند.

update_engine_client -status
update_engine_client -check_for_update

وضعیت UPDATE_STATUS_UPDATED_NEED_REBOOT به این معناست که اسلات غیرفعال (passive slot) از قبل تصویر جدید را دریافت کرده و تنها مرحلهٔ باقی‌مانده، reboot است. استراتژی پیش‌فرض برای reboot، گزینه reboot با تأخیر 5 دقیقه‌ای است؛ بنابراین یک VPS تکی در محیط production طبق زمان‌بندی خودکار خود ری‌استارت می‌شود، مگر آنکه خلاف آن را تنظیم کنید. یک بازه زمانی در /etc/flatcar/update.conf تعیین کنید:

REBOOT_STRATEGY=reboot
LOCKSMITHD_REBOOT_WINDOW_START="Thu 04:00"
LOCKSMITHD_REBOOT_WINDOW_LENGTH=1h

گزینه REBOOT_STRATEGY=off مسئولیت reboot را به عهده شما می‌گذارد. تنظیم SERVER=disabled در همان فایل، بررسی به‌روزرسانی را به‌طور کامل متوقف می‌کند. برای یک کلاستر، استفاده از REBOOT_STRATEGY=etcd-lock در ترکیب با locksmithctl set-max 4 محدودیت تعداد گره‌هایی که می‌توانند هم‌زمان reboot شوند را تعیین می‌کند تا یک به‌روزرسانی هرگز باعث از دسترس خارج شدن کل ناوگان نشود.

Talos Linux: بدون شل، بدون SSH، بدون کنسول

Talos محدودترین گزینه در میان این چهار مورد است و هدف آن از همه شفاف‌تر است. این سیستم‌عامل نودهای Kubernetes را اجرا می‌کند. در آن هیچ daemon مربوط به SSH، هیچ شل ورود (login shell) و هیچ کنسول ورودی وجود ندارد. کنسول فیزیکی به‌جای نمایش اعلان ورود، یک داشبورد برای بررسی وضعیت ماشین نمایش می‌دهد. هر عملیات، یک فراخوانی gRPC API است که با استفاده از talosctl از ایستگاه کاری شما و بر اساس پیکربندی ماشینی که در git نگهداری می‌کنید، انجام می‌شود.

talosctl upgrade --nodes 10.20.30.40 \
  --image factory.talos.dev/metal-installer/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba:v1.14.2

از زمان انتشار Talos 1.14، ایمیج ghcr.io/siderolabs/installer دیگر منتشر نمی‌شود و ایمیج‌های نصب‌کننده از طریق Image Factory ارائه می‌شوند. شناسه طولانی در آن مسیر، شماتیک خالی برای ماشینی بدون شخصی‌سازی است. از همان شماتیکی استفاده کنید که نود شما با آن نصب شده است تا افزونه‌های سیستمی (system extensions) نیز همراه آن باشند، و تگ را با نسخه‌ای که قصد ارتقا به آن را دارید جایگزین کنید. ارتقا از طرح A-B استفاده می‌کند که هسته و ایمیج سیستم‌عامل قبلی را حفظ می‌کند؛ بنابراین اگر نسخه جدید بوت نشود، Talos به‌طور خودکار و بدون نیاز به مداخله، به نسخه قبلی بازمی‌گردد (rollback). عیب‌یابی در این سیستم متفاوت است زیرا شل ورودی وجود ندارد: شما به‌جای استفاده از journalctl روی خود دستگاه، از talosctl logs و talosctl dmesg استفاده می‌کنید. هنگامی که به ابزارهایی روی نود نیاز دارید، talosctl debug یک کانتینر دارای دسترسی‌های ویژه (privileged) را از ایمیجی که شما ارائه می‌دهید اجرا کرده و شما را به شل آن وارد می‌کند؛ پس از خروج، کانتینر حذف می‌شود.

اگر workload شما Kubernetes نیست، Talos انتخاب مناسبی نخواهد بود. اما اگر هست، Talos یک دسته کامل از حوادث را حذف می‌کند، زیرا امکان وقوع سناریوی «کسی به نود وارد شده و چیزی را تغییر داده است» وجود ندارد.

آنچه مستأجر VPS در واقع از دست می‌دهد

نصب‌های موردی (Ad-hoc) روی سیستم در حال اجرا. این مهم‌ترین مورد است. اجرای sudo apt install htop در ساعت 2 بامداد هنگام بروز یک حادثه، دیگر امکان‌پذیر نیست. در bootc شما یک overlay گذرا دریافت می‌کنید که با reboot از بین می‌رود. در Fedora CoreOS شما یک deployment لایه‌بندی‌شده دارید که نیاز به reboot دارد. در Flatcar و Talos شما هیچ‌کدام را ندارید.

خط لوله ساخت (Build pipeline) که قبلاً نداشتید. افزودن یک بسته به معنای ویرایش یک Containerfile، ساخت image، ارسال آن به یک registry و به‌روزرسانی سرورها است. وقتی خط لوله از قبل وجود داشته باشد، این کار کم‌هزینه است. اما راه‌اندازی آن از صفر کار دشواری است و به یک registry نیاز دارد که سرورها بتوانند به آن دسترسی داشته باشند؛ که خود یک سرویس دیگر برای اجرا یا یک هزینهٔ اضافی است.

ماژول‌های هسته (Kernel modules). هسته از طریق image تأمین می‌شود، بنابراین ماژولی که برای هستهٔ در حال اجرا کامپایل شده باشد، پس از به‌روزرسانی بعدی باقی نمی‌ماند. ماژول‌های خارج از درخت (Out-of-tree) و بسته‌های DKMS (پشتیبانی پویا از ماژول هسته) باید درون image و متناسب با هستهٔ همان image ساخته شوند. هر چیزی که به ماژولی نیاز داشته باشد که در image پایه وجود ندارد، به جای یک مشکل نصب، به یک مشکل در فرآیند ساخت تبدیل می‌شود.

عامل‌های (Agents) فروشنده و ارائه‌دهنده. عامل‌های مانیتورینگ و پشتیبان‌گیری معمولاً به صورت یک .deb یا .rpm همراه با یک اسکریپت نصب عرضه می‌شوند که در /usr می‌نویسد و یک unit را فعال می‌کند. در یک سیستم فقط‌خواندنی (read-only)، آن اسکریپت با شکست مواجه می‌شود. برخی فروشندگان یک container منتشر می‌کنند یا روش نصب در حالت image را مستند کرده‌اند. بسیاری این کار را نمی‌کنند. پیش از تعهد، این مورد را بررسی کنید، زیرا ناوگانی که نتوانید مانیتور کنید، از ناوگانی که دچار drift (انحراف پیکربندی) شده، بدتر است.

خودِ image. تقریباً هیچ پنل مدیریتی VPS، سیستم‌عامل‌های Fedora CoreOS یا Flatcar یا Talos را در کنار Ubuntu و Debian فهرست نمی‌کند. شما باید دیسک را تأمین کنید، که موضوع بخش بعدی است.

انتقال یکی از این سیستم‌عامل‌ها به VPS اجاره‌ای

ابتدا دو مورد را در مورد ارائه‌دهنده خدمات خود تأیید کنید: دسترسی کنسول خارج از باند (out-of-band) داشته باشید، یعنی VNC یا کنسول سریال، و اینکه بتوانید سیستم را در حالت rescue بوت کنید. بدون کنسول، ماشینی که پس از تغییرات بالا نمی‌آید، به جای یک تعمیر 5 دقیقه‌ای، تبدیل به یک تیکت پشتیبانی می‌شود.

اگر ارائه‌دهنده اجازه استفاده از ایمیج‌های سفارشی را می‌دهد، ایمیج raw یا qcow2 ارائه‌دهنده را آپلود کنید، اما آپلود به‌تنهایی به معنای داشتن ماشینی نیست که بتوانید به آن وارد شوید. کاربر core در Fedora CoreOS هیچ رمز عبور یا کلید SSH پیش‌فرضی ندارد، بنابراین همچنان باید یک پیکربندی Ignition حاوی کلید خود را ارائه دهید، یا در پلتفرم‌های ابری که Afterburn از آن‌ها پشتیبانی می‌کند، کلید را از طریق قابلیت SSH key خودِ ارائه‌دهنده تنظیم کنید. در غیر این صورت، باید دیسک را خودتان از داخل سیستم rescue بنویسید. Flatcar یک اسکریپت مستقل دقیقاً برای همین کار ارائه می‌دهد که از هر توزیع لینوکسی اجرا می‌شود:

curl -fsSLO https://raw.githubusercontent.com/flatcar/init/flatcar-master/bin/flatcar-install
chmod +x flatcar-install
sudo ./flatcar-install -d /dev/sda -i ignition.json

این اسکریپت را از داخل سیستم rescue اجرا کنید، هرگز آن را از سروری که قصد جایگزینی‌اش را دارید اجرا نکنید، زیرا اسکریپت در حین کار، پارتیشن‌های دستگاه مقصد را بازنویسی می‌کند. این کار حداقل به 8 GB فضای قابل استفاده روی دستگاه نیاز دارد و محیط rescue باید bash، bzip2 یا lbzip2، lsblk، wget، udevadm، gpg و gawk را فراهم کند. فایل ignition.json شما باید حاوی یک کلید SSH باشد، در غیر این صورت سیستم نصب‌شده راهی برای ورود شما نخواهد داشت.

Fedora CoreOS ساختار مشابهی دارد و نصب‌کننده آن به صورت یک container اجرا می‌شود:

sudo podman run --pull=always --privileged --rm \
    -v /dev:/dev -v /run/udev:/run/udev -v .:/data -w /data \
    quay.io/coreos/coreos-installer:release \
    install /dev/vdb -i config.ign

پیش از اجرا، نام دستگاه را با lsblk بررسی کنید. نوشتن روی دستگاه اشتباه، تمام اطلاعات موجود روی آن را از بین می‌برد و هیچ اعلان تأییدی (confirmation prompt) نمایش داده نمی‌شود.

ابزار bootc تنها مسیری است که نیاز به حالت rescue را حذف می‌کند، زیرا یک سیستم لینوکسی در حال اجرا را در همان محل تبدیل می‌کند:

sudo podman run --rm --privileged -v /dev:/dev -v /var/lib/containers:/var/lib/containers -v /:/target \
             --pid=host --security-opt label=type:unconfined_t \
             quay.io/fedora/fedora-bootc:44 \
             bootc install to-existing-root

پیش از اجرای این دستور، مستندات ایمیج پایه‌ای که استفاده می‌کنید را مطالعه کنید و آن را روی سروری تست کنید که امکان از دست دادنش را دارید. پس از reboot، ماشین ایمیج جدید را اجرا می‌کند و مجموعه بسته‌های قبلی شما حذف خواهند شد.

چه کسانی باید از سرور تغییرناپذیر (Immutable) استفاده کنند و چه کسانی نباید

اگر سرورهای خود را مانند «گله» مدیریت می‌کنید، به این رویکرد نیاز دارید. یعنی ماشین‌های متعددی که همگی از یک دستورالعمل واحد ساخته شده‌اند. نمونه‌هایی از این دست عبارتند از: CI runners که عمر آن‌ها تنها یک ساعت است، یا نودهای k3s و Kubernetes که به‌جای تعمیر، جایگزین می‌شوند. هر سناریویی که در آن پاسخ به خرابی یک ماشین، «حذف آن و ساخت یک ماشین جدید» باشد، برای این مدل مناسب است. همچنین زمانی که باید به یک حسابرس ثابت کنید دقیقاً چه چیزی روی ماشین در حال اجراست، این روش کارآمد است؛ چرا که پاسخ شما یک image digest خواهد بود، نه یک لیست طولانی از بسته‌های نصب‌شده.

اگر یک VPS دارید که به‌صورت دستی مدیریت می‌شود و سه سرویس روی آن اجرا کرده‌اید، هر زمان که نیاز باشد چیزی نصب می‌کنید و هیچ خط لوله (pipeline) ساخت‌وسازی ندارید، نباید از این روش استفاده کنید. حالت Image-based کار را حذف نمی‌کند، بلکه آن را از سرور به مرحله ساخت (build) منتقل می‌کند و هزینه استفاده از یک registry و یک pipeline را به شما تحمیل می‌کند. اگر زیرساختی برای مدیریت این فرآیند دارید، سرورهایی یکسان خواهید داشت که بازگشت به نسخه قبلی (rollback) در آن‌ها تنها با یک reboot انجام می‌شود. در غیر این صورت، تنها پیچیدگی‌های غیرضروری به سیستمی که به‌خوبی کار می‌کرد اضافه کرده‌اید و عیب‌یابی در ساعت 2 بامداد را دشوارتر ساخته‌اید.

رویکرد میانه و مطمئن همچنان کارآمد است: استفاده از یک توزیع معمولی با به‌روزرسانی‌های امنیتی خودکار، به‌علاوه یک فرآیند بازسازی (rebuild) که واقعاً آن را تمرین کرده‌اید. انتخاب سیستم‌عامل پایه، تصمیمی مستقل است که در انتخاب سیستم‌عامل برای اجرا روی VPS به آن پرداخته شده است. حالت Image-based تنها جدیدترین دور از یک بحث بسیار قدیمی درباره نحوه انتقال نرم‌افزار به ماشین است و تاریخچه توزیع‌های لینوکس تا حد زیادی بازتاب تکرار همین بحث است.

FAQ

آیا توزیع‌های لینوکس تغییرناپذیر (Immutable) واقعاً تغییرناپذیر هستند؟

خیر، و این نام باعث سردرگمی می‌شود. کاربر root همچنان می‌تواند روی دیسک بنویسد. آنچه در واقع رخ می‌دهد این است که /usr در زمان اجرا به‌صورت read-only مانت می‌شود و در به‌روزرسانی بعدی، کل آن با یک image جدید جایگزین می‌گردد، در حالی که /etc و /var قابل‌نوشتن باقی می‌مانند و پس از به‌روزرسانی‌ها حفظ می‌شوند. تغییراتی که در /usr اعمال می‌کنید یا در همان لحظه رد می‌شوند و یا در به‌روزرسانی بعدی از بین می‌روند؛ بنابراین نتیجهٔ عملی این است که دایرکتوری‌های سیستم فقط زمانی تغییر می‌کنند که image تغییر کند.

آیا می‌توانم Fedora CoreOS یا Flatcar را روی VPSای که آن‌ها را ارائه نمی‌دهد اجرا کنم؟

معمولاً بله، اگر ارائه‌دهنده به شما یک سیستم rescue و دسترسی کنسول بدهد. شما سیستم rescue را بوت می‌کنید، image دیسک توزیع موردنظر را روی block device می‌نویسید و سپس سیستم را reboot می‌کنید. اسکریپت flatcar-install در Flatcar این کار را از هر سیستم‌عاملی انجام می‌دهد و Fedora CoreOS نیز coreos-installer را به‌عنوان یک container ارائه می‌دهد که می‌توانید به همان روش اجرا کنید. هر دو به یک فایل Ignition حاوی کلید SSH شما نیاز دارند، زیرا هیچ مرحله‌ای برای تنظیم رمز عبور در اولین بوت وجود ندارد که بتوانید به آن تکیه کنید. بدون دسترسی کنسول، این کار را انجام ندهید: اگر ماشین پس از تغییرات بالا نیاید، هیچ راهی برای بررسی وضعیت آن نخواهید داشت.

چگونه می‌توانم یک پکیج را روی سرور تغییرناپذیر نصب کنم؟

شما آن را به image اضافه کرده و دوباره مستقر (redeploy) می‌کنید. در bootc این کار با یک خط RUN dnf -y install ... در Containerfile، بازسازی (rebuild)، push کردن و سپس اجرای sudo bootc upgrade --apply روی ماشین انجام می‌شود. در Fedora CoreOS می‌توانید آن را با sudo rpm-ostree install لایه‌بندی (layer) کرده و reboot کنید، با این هزینه که آن پکیج در هر به‌روزرسانی بعدی دوباره اعمال می‌شود. در Flatcar و Talos مدیر پکیج وجود ندارد، بنابراین پاسخ استفاده از container است. برای یک ابزار عیب‌یابی موقت روی میزبان bootc، دستور sudo bootc usr-overlay یک /usr قابل‌نوشتن به شما می‌دهد که با reboot بعدی ناپدید می‌شود.

آیا حالت image mode، مشکل VPSای که پس از به‌روزرسانی هسته (kernel) بوت نمی‌شود را حل می‌کند؟

این کار بازیابی سیستم را از یک عملیات دشوار در کنسول rescue به یک reboot ساده تبدیل می‌کند. image قبلی، شامل هسته و فضای کاربری (userspace)، همچنان روی دیسک باقی می‌ماند، بنابراین sudo bootc rollback یا sudo rpm-ostree rollback -r شما را به وضعیت قبلی بازمی‌گرداند. Talos و Flatcar فراتر می‌روند و اگر slot جدید بوت نشود، به‌طور خودکار به نسخه قبل بازمی‌گردند، زیرا یک ورودی بوت تنها پس از یک بوت موفق به حالت پیش‌فرض در می‌آید. هیچ‌کدام از این‌ها از بروز یک به‌روزرسانی بد جلوگیری نمی‌کنند، اما بازگرداندن آن را بسیار آسان و کم‌هزینه می‌سازند.

برای سرور کدام توزیع تغییرناپذیر را انتخاب کنم؟

اگر یک سرور لینوکس عمومی می‌خواهید که آن را مانند یک container image بسازید و روی ماشین فعلی خود نصب کنید، bootc را انتخاب کنید. اگر همان مدل را می‌خواهید که ساخت آن برای شما انجام شده و به‌روزرسانی‌های خودکار را به‌صورت پیش‌فرض دارد، Fedora CoreOS را انتخاب کنید. اگر یک میزبان container حداقلی با طرح به‌روزرسانی A/B و بدون مدیر پکیج می‌خواهید تا کسی وسوسه نشود چیزی نصب کند، Flatcar را انتخاب کنید. Talos را فقط زمانی انتخاب کنید که ماشین شما یک نود Kubernetes باشد، زیرا این سیستم shell برای ورود ندارد و هیچ چیز دیگری را اجرا نمی‌کند.

آیا این مقاله مفید بود؟

#bootc#immutable#atomic#coreos#updates