تمرین هفته ۴
در این تمرین، مفاهیم کلیدی هفتهی چهارم یعنی تکرارپذیری (Repeatability)، تکنتیجهبودن (Idempotency)، کار با APIها از طریق curl و jq، استانداردسازی وظایف با Makefile و مدیریت پیکربندی با Ansible را در قالب یک سناریوی واقعی DevOps پیادهسازی میکنید.
شما یک وبسرویس پایتونی تحت نام statusapi تحویل میگیرید که وضعیت سیستم و سلامت خود را از طریق REST API گزارش میدهد. هدف شما این است که بدون هیچگونه دخالت دستی، کل فرآیند آمادهسازی کاربر، محیط مجازی، فایلها، راهاندازی سرویس در پسزمینه با systemd و فراخوانی دادهها با کلاینت را بهصورت خودکار پیادهسازی کنید.
پیش از شروع، درسهای این هفته بهویژه اصول Automation در DevOps، Automation با curl و jq، Makefile و Task Runner و آشنایی با Ansible را مرور کنید.
دیمن (Daemon) چیست؟
در سیستمعاملهای شبهیونیکس (از جمله لینوکس)، دیمن (Daemon) به برنامهای گفته میشود که در پسزمینه (Background) و بدون اتصال به یک ترمینال تعاملی (tty) اجرا میشود و بیصدا منتظر رخدادها یا درخواستهای شبکه میماند (مانند sshd، وبسرورها یا systemd).
اجرای دستی برنامهها در پسزمینه با دستوراتی مانند python3 app.py & یا nohup برای محیطهای عملیاتی نامناسب است؛ زیرا در صورت Crash یا ریاستارت سیستم بهطور خودکار راهاندازی نمیشوند و مدیریت چرخهی حیات (Start/Stop/Restart) استانداردی ندارند. به همین دلیل مدیریت دیمنها به ابزاری مانند systemd واگذار میشود تا اجرای پایدار، راهاندازی خودکار پس از خطا، ایزولهسازی کاربر و ثبت منظم لاگها را تضمین کند.
مشخصات فنی و استانداردهای استقرار
پیادهسازی شما باید دقیقاً مطابق با ساختار و مشخصات جدول زیر باشد:
پایبندی به مشخصات فنی (Technical Specifications)
مانند استقرارهای استاندارد در تیمهای DevOps، پایبندی دقیق به مشخصات فنی و مسیرهای استاندارد زیر الزامی است تا سایر ابزارها، اسکریپتهای مانیتورینگ و همتیمیها بتوانند بدون مشکل با سرویس تعامل داشته باشند. هرگونه تغییر در نام فایلها، مسیرها، پورت یا ساختار داده باعث اختلال در سازگاری سرویس خواهد شد.
| مولفه / پارامتر | مقدار استاندارد الزامی | توضیحات |
|---|---|---|
| نام سرویس و اپلیکیشن | statusapi | نام فایل سرویس: /etc/systemd/system/statusapi.service |
| کاربر و گروه سیستمی | statusapi:statusapi | کاربر سیستمی بدون لاگین تعاملی (/usr/sbin/nologin) و بدون نیاز به Home |
| مسیر دایرکتوری برنامه | /opt/statusapi | فایلهای پروژه باید به این مسیر کپی شده و مالکیت آن متعلق به statusapi:statusapi باشد |
| مسیر محیط مجازی پایتون | /opt/statusapi/venv | بستههای پایتون تنها داخل این venv نصب میشوند |
| آدرس و پورت اتصال | 127.0.0.1:8090 | سرویس فقط روی رابط Loopback محلی و پورت 8090 گوش میدهد |
| اندپوینت بررسی سلامت | GET /health | بازگشت کد 200 OK با بدنه JSON به فرمت {"status": "ok"} |
| اندپوینت اطلاعات وضعیت | GET /api/v1/status | بازگشت کد 200 OK شامل کلیدهای service, version, hostname, uptime_seconds, status |
| اسکریپت خودکارسازی نصب | install.sh | استقرار صفر تا صد، با ویژگیهای Idempotency (تکنتیجهبودن) و Self-healing (خودترمیمی در صورت شکست اجرای قبلی) |
| اسکریپت کلاینت خط فرمان | client.sh | ارسال درخواست با curl و تحلیل با jq با سابکامندهای health و status |
| مدیریت وظایف پروژه | Makefile | تارگتهای معتبر: install, start, stop, restart, status, client, health, ansible |
| اسکریپت اعتبارسنجی فایلها | verify.sh | ابزار ارزیابی و تست خودکار فایلهای پوشهی assets/ پیش از ارسال PR |
گام ۱ — دریافت بسته و بررسی اولیه
ابتدا روی ماشین مجازی لینوکس، دایرکتوری کار تمرین را ساخته و فایل فشردهی وبسرویس را دریافت کنید:
محتویات استخراجشده شامل دو فایل است:
app.py: کد وبسرویس نوشتهشده با Flaskrequirements.txt: نیازمندیهای پایتون (Flask==3.0.3)
راهاندازی آزمایشی و محلی
محیطهای مجازی پایتون (venv) و استفاده از هوش مصنوعی
محیط مجازی پایتون (Virtual Environment یا venv) ابزاری برای ایزولهسازی بستهها و نیازمندیهای پروژههای پایتونی از پکیجهای عمومی سیستمعامل است تا نسخههای مختلف کتابخانهها با سیستم یا سایر پروژهها تداخل پیدا نکنند.
از آنجا که توسعه با پایتون و سازوکار داخلی venv در سرفصلهای اصلی این دوره DevOps قرار ندارد و خارج از دامنه (Out of scope) محسوب میشود:
- برای مطالعهی تکمیلی و آشنایی با چرایی و نحوهی کارکرد محیطهای مجازی، مقالهی زیر را مطالعه کنید:
- استفاده آزاد از هوش مصنوعی: در نوشتن بخشهای مرتبط با پایتون و venv (مانند دستورات ایجاد محیط مجازی و نصب requirements در اسکریپت Bash) مجازید از ابزارهای هوش مصنوعی استفاده کنید. تمرکز این تمرین روی اتوماسیون فرآیندها در لینوکس، مدیریت سرویس با systemd و اصول Idempotency و Self-healing است.
پیش از شروع اسکریپتنویسی سیستمی، یک محیط مجازی موقت در دایرکتوری کار بسازید و برنامه را بهصورت دستی تست کنید:
در ترمینال دیگر، با curl عملکرد اندپوینتها را بررسی کنید:
پس از اطمینان از عملکرد، با فشردن Ctrl+C پروسه را خاتمه دهید و با دستور deactivate از محیط مجازی آزمایشی خارج شوید. محیط موقت test-venv را حذف کنید:
نتایج پاسخهای دریافتی از دو اندپوینت و نسخه پایتون ماشین خود را در گزارش 01-manual-test.md یادداشت کنید.
گام ۲ — خودکارسازی استقرار با install.sh (اصول Idempotency و Self-healing)
اکنون باید اسکریپت install.sh را بنویسید. این اسکریپت قلب تمرین است و باید تمام مراحل نصب را از ابتدا تا انتهای بالا آمدن سرویس انجام دهد. در نوشتن این اسکریپت باید دو اصل مهندسی را مدنظر داشته باشید:
- تکنتیجهبودن (Idempotency): اجرای دوبارهی اسکریپت روی سامانهای که قبلاً با موفقیت نصب شده، نباید هیچ خطایی ایجاد کند یا وضعیت مطلوب را به هم بزند.
- خودترمیمی (Self-healing): اگر اجرای قبلی به دلیلی در میانهی راه متوقف شده باشد (مثلاً به دلیل نبود پکیج، قطع اتصال، یا وجود فایلهای نیمهکاره و خراب)، اجرای مجدد اسکریپت باید وضعیت خراب را تشخیص داده، آن را ترمیم یا پاکسازی کند و سیستم را به وضعیت سالم نهایی برساند.
الزامات اسکریپت install.sh:
- با
#!/usr/bin/env bashآغاز شود و دستورset -euo pipefailدر ابتدای آن قرار گیرد. - دسترسی
rootرا بررسی کند؛ اگر بدونsudoاجرا شد، پیامی درstderrچاپ کرده و با کد خروج غیرصفر خارج شود. - پکیجهای پیشنیاز سیستمعامل (
python3,python3-venv,curl) را بررسی کند یا در صورت عدم وجود، بهصورت خودکار باapt-getنصب نماید. - کاربر و گروه سیستمی
statusapi:- اگر این کاربر وجود ندارد، آن را با شل غیرتعاملی (
/usr/sbin/nologin) بسازد. - نکته تکنتیجهبودن: اگر کاربر از قبل ساخته شده بود، اسکریپت نباید با خطا متوقف شود.
- اگر این کاربر وجود ندارد، آن را با شل غیرتعاملی (
- دایرکتوری برنامه و انتقال فایلها:
- دایرکتوری
/opt/statusapiرا بسازد. - فایلهای
app.pyوrequirements.txtرا از محل اجرای اسکریپت به/opt/statusapi/منتقل یا کپی کند.
- دایرکتوری
- محیط مجازی پایتون و پیادهسازی Self-healing:
- محیط مجازی را در مسیر مشخص
/opt/statusapi/venvبسازد (برای نوشتن دستورهای کار با venv در Bash میتوانید از هوش مصنوعی کمک بگیرید). - الزام خودترمیمی: وجود دایرکتوری را بهتنهایی نشانهی سلامت venv ندانید (زیرا اگر اجرای قبلی پایتون نیمهکاره متوقف شده باشد، پوشه ایجاد میشود اما باینری
pipساخته نمیشود). اسکریپت باید سلامت venv را علاوه بر بررسی وجود فایل/opt/statusapi/venv/bin/pip، با بررسی امکان ایمپورت شدن فریمورک اصلی وبسرویس (/opt/statusapi/venv/bin/python -c "import flask") نیز ارزیابی کند؛ اگر ساختار venv ناقص بود یا پکیج قابل ایمپورت نبود، محیط را ترمیم یا بازسازی کند. - پکیجهای موجود در
/opt/statusapi/requirements.txtرا با استفاده از باینری pip محیط مجازی (/opt/statusapi/venv/bin/pip) نصب کند. - تمام دایرکتوری
/opt/statusapiو محتویات آن را در مالکیت کاربرstatusapi:statusapiقرار دهد.
- محیط مجازی را در مسیر مشخص
- پیکربندی و راهاندازی systemd unit:
- فایل
/etc/systemd/system/statusapi.serviceرا ایجاد کرده یا کپی کند. - سرویس باید دارای ساختار استاندارد زیر باشد:
- فایل
- دستور
systemctl daemon-reloadرا اجرا کند. - سرویس را فعال و بلافاصله اجرا کند (
systemctl enable --now statusapi). - با استفاده از
curlیا بررسی وضعیت سیستم، سلامت سرویس را بررسی کرده و پیام موفقیتآمیز چاپ کند.
آزمون Idempotency و Self-healing
اسکریپت خود را در دو سناریو بیازمایید:
- تکنتیجهبودن: دو بار متوالی
sudo ./install.shرا اجرا کنید. بار دوم باید سریع، بدون خطا و با کد خروج0تمام شود. - خودترمیمی: عمداً پوشهی venv را بهصورت ناقص درآورید (مثلاً باینری
pipیا پکیجflaskرا حذف کنید) و دوبارهsudo ./install.shرا اجرا کنید. اسکریپت باید بتواند سلامت venv و قابلیت import فریمورک را ارزیابی کرده و بهصورت خودکار محیط را ترمیم و راهاندازی کند.
پس از پیادهسازی و اجرای اسکریپت، وضعیت سرویس را با systemctl status statusapi بررسی کرده و خروجی را در 02-installation.md مستند کنید.
گام ۳ — پیادهسازی کلاینت خط فرمان (client.sh)
یک کلاینت Bash به نام client.sh بسازید که کارشناس عملیات بتواند با استفاده از آن بهسرعت وضعیت سرویس را بدون تایپ دستورهای طولانی بررسی کند. این اسکریپت از curl و jq استفاده میکند.
الزامات اسکریپت client.sh:
- دارای
#!/usr/bin/env bashوset -euo pipefail. - بررسی وجود ابزارهای
curlوjq. - پشتیبانی از دو سابکامند:
./client.sh health:- درخواست به
http://127.0.0.1:8090/health - بررسی کد وضعیت HTTP: اگر سرویس فعال بود و پاسخ
200داد، دقیقاً عبارتOK: Service is healthyرا در خروجی استاندارد چاپ کند و با کد خروج0تمام شود (جریانstderrباید خالی بماند). - در صورت بروز خطا (عدم دسترسی به سرویس، Timeout یا کد خطای غیر 200)، پیام خطا به
stderrفرستاده شده و با کد خروج1خاتمه یابد.
- درخواست به
./client.sh status:- درخواست به
http://127.0.0.1:8090/api/v1/status - چاپ یک گزارش خوانا برای انسان از فیلدهای خروجی که حتماً شامل خطی با شروع
Service:باشد (مانندService: statusapi). - در خط پایانی، چاپ یک شیء JSON فشرده با دستور
jq -cشامل دقیقاً کلیدهای:service,status,uptime_seconds - خروج با کد
0در صورت موفقیت و کد1در صورت عدم اتصال (با چاپ پیام خطا درstderr).
- درخواست به
- اگر آرگومان نامعتبر یا خالی داده شد، متنی حاوی راهنمای
Usageرا فقط درstderrچاپ کرده و با کد خروج2تمام شود (خروجیstdoutباید خالی بماند).
خروجی اجرای هر دو حالت و یک حالت خطادار (مثلاً هنگام متوقف بودن سرویس) را در 03-client.md قرار دهید.
گام ۴ — استانداردسازی با Makefile
همانطور که در درس Makefile دیدید، یک تسکرانر به اعضای تیم اجازه میدهد بدون حفظ کردن دستورات پیچیده، کارهای روتین را با یک رابط یکنواخت پیش ببرند.
در ریشهی پروژه یک فایل Makefile بسازید که شامل تارگتهای زیر باشد:
مطمئن شوید دستورات Makefile تورفتگی با کاراکتر واقعی Tab دارند. اجرای make install و make client را آزمایش کرده و گزارش کارکرد آن را در 04-makefile.md ثبت کنید.
گام ۵ — استقرار به روش Declarative با Ansible (اختیاری)
اگر مایلید مهارت Configuration Management خود را محک بزنید و درس آشنایی با Ansible را عمیقتر تمرین کنید، تمام فرآیند نصب گام ۲ را به یک Playbook انسیبل تبدیل کنید.
ساختار پوشه Ansible
یک پوشه به نام ansible/ در مسیر تمرین بسازید:
ansible/inventory.ini: تعریف هاست محلی:ansible/playbook.yml: یک Playbook باbecome: yesکه تسکهای زیر را با ماژولهای استاندارد Ansible اجرا میکند:- نصب پیشنیازها با ماژول
apt(python3-venv) - ساخت کاربر و گروه سیستمی با ماژول
userوgroup - ساخت دایرکتوری
/opt/statusapiبا ماژولfile - انتقال فایلهای
app.pyوrequirements.txtبا ماژولcopy - ایجاد محیط مجازی و نصب وابستگیها با ماژول
pip - قرار دادن فایل واحد با ماژول
copyدر/etc/systemd/system/statusapi.service - فعالسازی و استارت سرویس با ماژول
systemd(daemon_reload: yes,state: started,enabled: yes)
- نصب پیشنیازها با ماژول
اجرای این پلیبوک:
اگر پلیبوک را برای بار دوم اجرا کنید، تمام مراحل باید وضعیت ok داشته باشند و خروجی گزارش دهد: changed=0. خروجی اجرای اول و اجرای دوم پلیبوک را در 05-ansible.md قرار دهید.
گام ۶ — خودآزمایی و ارزیابی فایلها با verify.sh
برای اطمینان از صحت کامل عملکرد اسکریپتها، رعایت ساختارها و پاسشدن سناریوهای تکرارپذیری، یک اسکریپت اعتبارسنجی جامع به نام verify.sh در اختیارتان قرار داده شده است. این اسکریپت فایلهای داخل پوشهی assets/ شما را به همان صورتی که اسکریپتهای داوری ارزیابی میکنند، تست خواهد کرد.
هشدار مهم دربارهی اجرای verify.sh
اسکریپت verify.sh در فرآیند راهاندازی و پاکسازی خود، تمام ردپای سرویس statusapi (پروسهی در حال اجرا، لینکها و فایل unit در systemd، پوشهی /opt/statusapi و کاربر و گروه سیستمی statusapi) را حذف میکند تا استقرار را از نقطه صفر و بدون وابستگی به دادههای قبلی آزمایش کند.
این اسکریپت را ترجیحا داخل ماشین مجازی آزمایشی دوره (VM) اجرا کنید، نه روی سیستم اصلی.
دریافت و اجرای اسکریپت:
یا اگر فایلها در مسیر دیگری قرار دارند:
مواردی که verify.sh بررسی میکند:
- تحلیل ایستا (Static Analysis): وجود کلیهی فایلهای مورد نیاز، صحت سینتکس Bash (
bash -n)، رعایت shebang، فعال بودنset -euo pipefail، وجود گارد روت، تورفتگیهای Tab درMakefile، صحت ساختارstatusapi.serviceو بررسی کیفیت کد باshellcheck. - آزمون گارد روت: ممانعت از اجرای غیرمجاز
install.shبدون دسترسی root و هدایت خطا بهstderr. - استقرار اولیه و تکنتیجهبودن (Idempotency): اجرای بار اول و دوم
install.shو اطمینان از موفقیت هر دو با کد خروج0. - سناریوهای خودترمیمی (Self-healing): شبیهسازی شرایط خرابی (مانند خالیماندن دایرکتوری venv، حذف باینری pip، یا آسیب دیدن پکیج Flask) و اطمینان از اینکه
install.shمحیط را ترمیم میکند. - رفتار کلاینت (
client.sh): آزمون سابکامندهایhealthوstatus، دریافت کد خروج2برای ورودیهای نامعتبر، و دریافت کد خروج1به همراه پیام درstderrهنگام خاموش بودن سرویس. - تارگتهای Makefile: اجرای بدون خطای
make healthوmake client. - استقرار و Idempotency با Ansible (در صورت وجود): اجرای متوالی Playbook و اطمینان از بازگشت
changed=0در اجرای دوم.
در صورت قبولی، در انتهای خروجی پیام سبز رنگ زیر نمایش داده میشود:
گام ۷ — ساختار تحویل و Pull Request
مستندات و فایلهای مربوط به این تمرین را در فورک مخزن تمرینها، روی شاخهی week-4 و با ساختار دایرکتوری زیر قرار دهید:
چکلیست - نمایشی
پیش از ارسال نهایی PR، مطمئن شوید تمام موارد زیر را بررسی کردهاید:
- وبسرویس روی پورت
8090و فقط روی127.0.0.1پاسخ میدهد. - اسکریپت
install.shباset -euo pipefailنوشته شده و نیاز به مجوزrootدارد. - پروسه پایتون با کاربر سیستمی و غیر لاگین
statusapiاجرا میشود (نه باroot). - اجرای دو بار متوالی
sudo ./install.shبدون خطا و با کد خروج0پایان مییابد (آزمون Idempotency). - اسکریپت
install.shدر صورت وجود دایرکتوری ناقص یا نامعتبر (مانند نبود باینری pip یا عدم امکان import پکیج flask)، آن را بهصورت خودکار ترمیم و بازسازی میکند (Self-healing). - اسکریپت
client.shاز کدهای وضعیت HTTP وjqبرای بررسی پاسخ استفاده میکند. - فایل
Makefileوظایف اصلی را با کاراکترهای Tab استاندارد اجرا میکند. - (اختیاری) پلیبوک انسیبل در اجرای مجدد
changed=0را نشان میدهد. - اسکریپت
verify.shرا روی پوشهیassets/اجرا کردهام و نتیجهیRESULT: PASSEDدریافت شده است. - تمام فایلهای اسکریپت و کانفیگ درون پوشه
assets/تحویل داده شدهاند. - Pull Request مربوط به هفتهی ۴ در گیتهاب ایجاد شده است.