https://arsalanse.ir
? بات تلگرام برای مانیتور و گزارش وضعیت داکر کانتینرها
برای پیاده سازی یه سیستم مانیتورینگ وضعیت داکر کانتینرها کلی ابزار خوب برای محیط پروداکشن داریم (مثال: Grafana) و منم بدنبال ساخت دوباره چرخ نیستم، هدف من فقط یادگیری و شاید یادآوری یک سری ابزارها و مفهوم ها است.
قبل از هرکاری باید یه بات تلگرام ساخته باشین تا یه توکن براتون ساخته بشه
برای پیدا کردن ای دی چت خودتون یا یه کانال خاص که میخواید پیام ها ارسال بشه میتونید از api زیر استفاده کنید
https://api.telegram.org/bot{BOT_TOKEN}/getUpdates
من برای دریافت خروجی دستور docker stats خروجی شل این دستور رو با کتابخونه subprocess پایتون گرفتم به این شکل:
import subprocess
docker_ps = "echo -n <password> | sudo docker ps --format '{{.Status}}' | awk '{print $1}'"
docker_ps_output = subprocess.check_output(docker_ps, shell=True)
اینجا چند تا مشکل پیش میاد که با خلاقیت خودتون میتونید روش های دیگه ای رو امتحان کنید
اول اینکه داکر sudoer نیست به صورت دیفالت، و باید یا به user دسترسی بدین یا پسورد رو پایپ کنید مثل چیزی که بالا نوشته شده به کمک echo تا وقتی ترمینال پسورد خواست بهش پاس داده بشه
مشکل دوم اینکه داکر ps خروجی این شکلی داره:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4c01db0b339c ubuntu:12.04 bash 17 seconds ago Up 16 seconds 3300-3310/tcp webapp d7886598dbe2 crosbymichael/redis:latest /redis-server --dir 33 minutes ago Up 33 minutes 6379/tcp redis,webapp/db
ما فقط به ستون status نیاز داریم، اینجاست که با ابزار awk میایم فقط اون ستون رو جدا میکنیم و داخل یه آرایه می ریزیم (یوتیوب وحید ناینی آموزش مفصل awk نگاه کنید)
docker_ps_output = docker_ps_output.decode("utf-8").split('\n')
docker_ps_output = docker_ps_output[:-1]
حالا یه آرایه داریم که به این شکله: ["Up","Up","Up"] برای تبدیل این آرایه یه روش پایتونیک باحال داریم:
docker_ps_output = [True if item == "Up" else False for item in docker_ps_output] //[True, True]
if all(docker_ps_output):
pass
خروجی ما میشه یه آرایه به شکل [True, True, True] که با متد all میتونیم چک کنیم آیا همه اعضا مقدار True دارن یا نه...
تنها کاری که میمونه اینه که در صورتی که شرط بالا برقرار نشد پیام بدیم که وضعیت کانتینر ها مشکل پیدا کرده
اما برای اینکه اطلاعاتی هم همراه با ارسال خطا ارسال کنیم باید خروجی docker stats هم همراهش ارسال کنیم
docker_stats = "sudo docker stats --all --no-stream --format 'table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}'"
به همراه دستور من چندتا فلگ هم قرار دادم که به ترتیب:
فلگ --all که نه فقط وضعیت کانتینر های در حال اجرا کانتینر های خاموش شده هم برامون ارسال بشه
فلگ --no-stream به صورت پیش فرض وضعت استریم میشه و شل رو پس نمیده، این دستور باعث جلوگیری از این اتفاق میشه
فلگ --format با فرمت دهی ستون ها اونهایی که بهشون نیازی نداریم رو به سمت بات نمیفرستیم
حالا کافیه api تلگرام رو کال کنیم تا پیام رو برامون ارسال کنه تو پایتون میتونید از requests برای ارسال درخواست استفاده کنید
requests.get(f'{BASE_URL}System is up and running enjoy!&disable_notification=true')
requests.get(f'{BASE_URL}{docker_stats_output}')
پیام هایی که وضعیت سالم بودن سیستم رو گذارش میدن میتونید پاک کنید یا از پارامتر
&disable_notification=true
استفاده کنید که نوتیفیکیشن صدادار ارسال نشه
در آخر برنامه ما همچین چیزی باید بشه:
برای بهتر کردن این برنامه میتونید برای پسورد ها فایل env تعریف کنید
یا بجای اجرای دستورات مستقیم روی شل از کتابخونه docker استفاده کنید
حالا برای اجرای این اسکریپت مثلا ساعتی یکبار میتونید داخل crontab -e تعریفش کنید مثلا:
0 */1 * * * bash -c "cd /home/telegram-bot && source venv/bin/activate && echo <password> | sudo -S python3 docker-bot.py && deactivate"
لطفا سوالات خودتون رو برام کامنت کنید
لینک گیست گیتهاب رو اینجا قرار میدم تا اگه خواستید بهترش کنید راحت و همین پایین تو کامنت ها به اشتراک بذارید
تامام/.
مطلبی دیگر از این انتشارات
اتوماتیک کردن کانفیگ اولیه سرور cloud-init
مطلبی دیگر از این انتشارات
ارسال نوتیفیکیشن به تلگرام با پایپلاین گیت لب?
مطلبی دیگر از این انتشارات
جست و جو یک فیلد خاص در تعداد زیادی فایل json حجیم