? بات تلگرام برای مانیتور و گزارش وضعیت داکر کانتینرها

لینک گیت هاب gist

برای پیاده سازی یه سیستم مانیتورینگ وضعیت داکر کانتینرها کلی ابزار خوب برای محیط پروداکشن داریم (مثال: Grafana) و منم بدنبال ساخت دوباره چرخ نیستم، هدف من فقط یادگیری و شاید یادآوری یک سری ابزارها و مفهوم ها است.

قبل از هرکاری باید یه بات تلگرام ساخته باشین تا یه توکن براتون ساخته بشه

برای پیدا کردن ای دی چت خودتون یا یه کانال خاص که میخواید پیام ها ارسال بشه میتونید از api زیر استفاده کنید
https://api.telegram.org/bot{BOT_TOKEN}/getUpdates

من برای دریافت خروجی دستور docker stats خروجی شل این دستور رو با کتابخونه subprocess پایتون گرفتم به این شکل:

import subprocess
docker_ps = &quotecho -n <password> | sudo docker ps --format '{{.Status}}' | awk '{print $1}'&quot
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(&quotutf-8&quot).split('\n')
docker_ps_output = docker_ps_output[:-1]

حالا یه آرایه داریم که به این شکله: ["Up","Up","Up"] برای تبدیل این آرایه یه روش پایتونیک باحال داریم:

docker_ps_output = [True if item == &quotUp&quot 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 = &quotsudo docker stats --all --no-stream --format 'table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}'&quot

به همراه دستور من چندتا فلگ هم قرار دادم که به ترتیب:

فلگ --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

استفاده کنید که نوتیفیکیشن صدادار ارسال نشه

در آخر برنامه ما همچین چیزی باید بشه:

https://gist.github.com/arsalanses/aece4b47c88e2c6287244789bfbba1e9

برای بهتر کردن این برنامه میتونید برای پسورد ها فایل env تعریف کنید

یا بجای اجرای دستورات مستقیم روی شل از کتابخونه docker استفاده کنید

حالا برای اجرای این اسکریپت مثلا ساعتی یکبار میتونید داخل crontab -e تعریفش کنید مثلا:

0 */1 * * * bash -c &quotcd /home/telegram-bot && source venv/bin/activate && echo <password> | sudo -S python3 docker-bot.py && deactivate&quot

لطفا سوالات خودتون رو برام کامنت کنید

لینک گیست گیتهاب رو اینجا قرار میدم تا اگه خواستید بهترش کنید راحت و همین پایین تو کامنت ها به اشتراک بذارید

تامام/.