TL؛ DR
- برای دستیابی به قابلیت مشاهده بالای کانتینرها و ریزسرویس ها، لاگ ها و معیارهای اولیه کافی نیستند.
- برای بازیابی سریعتر و بهبود تحمل خطا، برنامه های کاربردی باید از اصل مشاهده پذیری بالا (HOP) استفاده کنند.
- در سطح برنامه، HOP به موارد زیر نیاز دارد: ورود به سیستم مناسب، نظارت دقیق، بررسی سلامت، و ردیابی عملکرد/انتقال.
- از چک ها به عنوان عنصر HOR استفاده کنید ReadinessProbe и livenessProbe کوبرنتیس
الگوی بررسی سلامت چیست؟
هنگام طراحی یک برنامه کاربردی حیاتی و بسیار در دسترس، بسیار مهم است که به جنبه ای مانند تحمل خطا فکر کنید. اگر یک برنامه به سرعت پس از یک شکست بهبود یابد، قابل تحمل خطا در نظر گرفته می شود. یک برنامه ابری معمولی از معماری میکروسرویس استفاده می کند - جایی که هر جزء در یک ظرف جداگانه قرار می گیرد. و برای اطمینان از اینکه برنامه در k8s بسیار در دسترس است، هنگام طراحی یک کلاستر، باید از الگوهای خاصی پیروی کنید. از جمله آنها الگوی بررسی سلامت است. تعریف می کند که چگونه برنامه سلامت خود را به k8s گزارش می دهد. این نه تنها اطلاعاتی در مورد اینکه آیا پاد در حال اجرا است، بلکه نحوه دریافت درخواست ها و پاسخ به آنها نیز است. هرچه Kubernetes درباره سلامت یک پاد اطلاعات بیشتری داشته باشد، تصمیمات هوشمندانهتری در مورد مسیریابی ترافیک و تعادل بار میگیرد. بنابراین، اصل مشاهده پذیری بالا از برنامه به موقع به درخواست ها پاسخ می دهد.
اصل مشاهده پذیری بالا (HOP)
اصل مشاهده پذیری بالا یکی از موارد است
یک برنامه ابری با طراحی خوب، رویدادهای اصلی خود را با استفاده از جریانهای ورودی/خروجی استاندارد STDERR و STDOUT ثبت میکند. سپس یک سرویس کمکی مانند filebeat، logstash یا fluentd ارائه میشود که گزارشها را به یک سیستم نظارت متمرکز (مانند Prometheus) و یک سیستم جمعآوری گزارش (مجموعه نرمافزار ELK) تحویل میدهد. نمودار زیر نحوه عملکرد یک برنامه ابری را بر اساس الگوی بررسی سلامت و اصل مشاهده پذیری بالا نشان می دهد.
چگونه الگوی بررسی سلامت را در Kubernetes اعمال کنیم؟
خارج از جعبه، k8s وضعیت پادها را با استفاده از یکی از کنترلرها (
در مثال ما، k8s این کار را انجام می دهد بررسی سلامت. در این نوع اعتبارسنجی، kubelet به طور مداوم وضعیت فرآیند را در ظرف بررسی می کند. به محض اینکه بفهمد این روند متوقف شده است، آن را دوباره راه اندازی می کند. اگر خطا به سادگی با راه اندازی مجدد برنامه برطرف شد و برنامه به گونه ای طراحی شده است که در صورت هرگونه خطا خاموش شود، یک بررسی سلامت فرآیند برای شما کافی است تا HOP و الگوی بررسی سلامت را دنبال کنید. تنها تاسف بار این است که همه خطاها با راه اندازی مجدد از بین نمی روند. برای این مورد، k8s 2 راه عمیق تر برای عیب یابی یک pod ارائه می دهد:
LivenessProbe
در طول livenessProbe kubelet 3 نوع بررسی را انجام می دهد: نه تنها اینکه آیا پاد در حال اجرا است، بلکه همچنین آماده دریافت و پاسخ مناسب به درخواست ها است:
- یک درخواست HTTP را روی پاد تنظیم کنید. پاسخ باید حاوی کد پاسخ HTTP از 200 تا 399 باشد. بنابراین، کدهای 5xx و 4xx نشان میدهند که پاد مشکل دارد، حتی اگر فرآیند در حال اجرا باشد.
- برای آزمایش پادها با خدمات غیر HTTP (مانند سرور پست الکترونیکی Postfix)، باید یک اتصال TCP برقرار شود.
- اجرای یک فرمان دلخواه برای یک pod (داخلی). اگر کد خروج دستور 0 باشد، بررسی موفقیت آمیز در نظر گرفته می شود.
نمونه ای از نحوه عملکرد آن. تعریف پاد زیر شامل یک برنامه NodeJS است که یک خطای 500 را روی درخواست های HTTP می اندازد. برای اطمینان از راه اندازی مجدد کانتینر پس از دریافت چنین خطایی، از پارامتر livenessProbe استفاده می کنیم:
apiVersion: v1
kind: Pod
metadata:
name: node500
spec:
containers:
- image: magalix/node500
name: node500
ports:
- containerPort: 3000
protocol: TCP
livenessProbe:
httpGet:
path: /
port: 3000
initialDelaySeconds: 5
این هیچ تفاوتی با سایر تعریف های pod ندارد، اما ما یک شی اضافه می کنیم .spec.containers.livenessProbe
. پارامتر httpGet
مسیری را طی می کند که از طریق آن یک درخواست HTTP GET ارسال می کند (در مثال ما، این است /
، اما در سناریوهای جنگی ممکن است چیزی شبیه به این وجود داشته باشد /api/v1/status
). LivenessProbe دیگر یک پارامتر می گیرد initialDelaySeconds
، که باعث می شود عملیات اعتبارسنجی تعداد ثانیه های مشخص شده منتظر بماند. تأخیر لازم است زیرا کانتینر برای شروع به زمان نیاز دارد و پس از راه اندازی مجدد، برای مدتی در دسترس نخواهد بود.
برای اعمال این تنظیمات در یک خوشه، از:
kubectl apply -f pod.yaml
پس از چند ثانیه می توانید با دستور زیر محتویات پاد را بررسی کنید:
kubectl describe pods node500
در پایان خروجی را پیدا کنید
همانطور که می بینید، livenessProbe یک درخواست HTTP GET را آغاز کرد، کانتینر یک خطای 500 را برگرداند (که برای انجام آن برنامه ریزی شده بود)، و kubelet آن را دوباره راه اندازی کرد.
اگر تعجب می کنید که برنامه NideJS چگونه برنامه ریزی شده است، در اینجا app.js و Dockerfile استفاده شده است:
app.js
var http = require('http');
var server = http.createServer(function(req, res) {
res.writeHead(500, { "Content-type": "text/plain" });
res.end("We have run into an errorn");
});
server.listen(3000, function() {
console.log('Server is running at 3000')
})
dockerfile
FROM node
COPY app.js /
EXPOSE 3000
ENTRYPOINT [ "node","/app.js" ]
توجه به این مهم است: livenessProbe فقط در صورت خرابی ظرف را مجددا راه اندازی می کند. اگر راهاندازی مجدد خطایی را که مانع از اجرای کانتینر میشود برطرف نکند، kubelet نمیتواند برای رفع مشکل اقدامی انجام دهد.
ReadinessProbe
ReadinessProbe مشابه livenessProbes (درخواست های دریافت، ارتباطات TCP و اجرای فرمان) عمل می کند، به جز برای عیب یابی. کانتینری که در آن خرابی شناسایی شده است مجددا راه اندازی نمی شود، بلکه از ترافیک ورودی جدا می شود. تصور کنید که یکی از کانتینرها در حال انجام محاسبات زیادی است یا تحت بار سنگینی است که زمان پاسخگویی به درخواست ها را افزایش می دهد. در مورد livenessProbe، یک بررسی در دسترس بودن پاسخ (از طریق پارامتر بررسی timeoutSeconds) راهاندازی میشود، پس از آن کوبلت ظرف را مجددا راهاندازی میکند. هنگامی که کانتینر راه اندازی می شود، شروع به انجام وظایف با منابع فشرده می کند و دوباره راه اندازی می شود. این می تواند برای برنامه هایی که سرعت پاسخگویی را ارزش گذاری می کنند بسیار مهم باشد. به عنوان مثال، یک ماشین در راه منتظر پاسخ از سرور است، پاسخ به تأخیر می افتد - و ماشین تصادف می کند.
بیایید یک تعریف redinessProbe بنویسیم که زمان پاسخگویی یک درخواست GET را بیش از دو ثانیه تنظیم کند و برنامه بعد از 5 ثانیه به درخواست GET پاسخ دهد. فایل pod.yaml باید به شکل زیر باشد:
apiVersion: v1
kind: Pod
metadata:
name: nodedelayed
spec:
containers:
- image: afakharany/node_delayed
name: nodedelayed
ports:
- containerPort: 3000
protocol: TCP
readinessProbe:
httpGet:
path: /
port: 3000
timeoutSeconds: 2
یک pod با kubectl مستقر کنید:
kubectl apply -f pod.yaml
بیایید چند ثانیه صبر کنیم و سپس خواهیم دید که ReadinessProbe چگونه کار می کند:
kubectl describe pods nodedelayed
در پایان خروجی مشاهده می کنید که برخی از رویدادها مشابه هستند
همانطور که می بینید، وقتی زمان بررسی بیش از 2 ثانیه بود، کوبکتل پاد را مجددا راه اندازی نکرد. در عوض او این درخواست را لغو کرد. اتصالات ورودی به سایر غلاف های کاری هدایت می شوند.
توجه داشته باشید که اکنون که پاد بارگیری شده است، kubectl دوباره درخواستهایی را برای آن ارسال میکند: پاسخهای GET دیگر تأخیر ندارند.
برای مقایسه، فایل app.js اصلاح شده در زیر آمده است:
var http = require('http');
var server = http.createServer(function(req, res) {
const sleep = (milliseconds) => {
return new Promise(resolve => setTimeout(resolve, milliseconds))
}
sleep(5000).then(() => {
res.writeHead(200, { "Content-type": "text/plain" });
res.end("Hellon");
})
});
server.listen(3000, function() {
console.log('Server is running at 3000')
})
TL؛ DR
قبل از ظهور اپلیکیشن های ابری، لاگ ها ابزار اصلی نظارت و بررسی وضعیت اپلیکیشن ها بودند. با این حال، هیچ وسیله ای برای انجام هر گونه اقدام اصلاحی وجود نداشت. گزارشها هنوز هم امروزه مفید هستند، آنها باید جمعآوری شوند و برای تجزیه و تحلیل شرایط اضطراری و تصمیمگیری به سیستم جمعآوری گزارش ارسال شوند. [همه اینها را میتوان بدون برنامههای ابری با استفاده از monit انجام داد، اما با k8s بسیار آسانتر شد 🙂 - ed. ]
امروزه، اصلاحات باید تقریباً در زمان واقعی انجام شود، بنابراین دیگر برنامه ها نباید جعبه سیاه باشند. نه، آنها باید نقاط پایانی را نشان دهند که به سیستم های نظارتی اجازه می دهد تا در صورت لزوم، داده های ارزشمندی را در مورد وضعیت فرآیندها جستجو و جمع آوری کنند تا در صورت لزوم فوراً پاسخ دهند. این الگوی طراحی بررسی سلامت نامیده می شود که از اصل بسیار قابل مشاهده (HOP) پیروی می کند.
Kubernetes به طور پیش فرض 2 نوع بررسی سلامت ارائه می دهد: ReadinessProbe و livenessProbe. هر دو از یک نوع چک استفاده می کنند (درخواست های HTTP GET، ارتباطات TCP و اجرای دستور). آنها در تصمیماتی که در پاسخ به مشکلات موجود در غلاف می گیرند، متفاوت هستند. livenessProbe به امید اینکه خطا دوباره رخ ندهد، کانتینر را مجددا راه اندازی می کند، و ReadinessProbe پاد را از ترافیک ورودی جدا می کند تا زمانی که علت مشکل اصلاح شود.
طراحی مناسب برنامه باید شامل هر دو نوع اعتبار سنجی باشد، و اینکه آنها داده های کافی را جمع آوری کنند، به خصوص زمانی که یک استثنا پرتاب می شود. همچنین باید نقاط پایانی API لازم را نشان دهد که معیارهای مهم وضعیت سلامت را به سیستم نظارت (مانند Prometheus) منتقل می کند.
منبع: www.habr.com