بهترین روش ها برای ظروف Kubernetes: بررسی های سلامت

بهترین روش ها برای ظروف Kubernetes: بررسی های سلامت

TL؛ DR

  • برای دستیابی به قابلیت مشاهده بالای کانتینرها و ریزسرویس ها، لاگ ها و معیارهای اولیه کافی نیستند.
  • برای بازیابی سریعتر و بهبود تحمل خطا، برنامه های کاربردی باید از اصل مشاهده پذیری بالا (HOP) استفاده کنند.
  • در سطح برنامه، HOP به موارد زیر نیاز دارد: ورود به سیستم مناسب، نظارت دقیق، بررسی سلامت، و ردیابی عملکرد/انتقال.
  • از چک ها به عنوان عنصر HOR استفاده کنید ReadinessProbe и livenessProbe کوبرنتیس

الگوی بررسی سلامت چیست؟

هنگام طراحی یک برنامه کاربردی حیاتی و بسیار در دسترس، بسیار مهم است که به جنبه ای مانند تحمل خطا فکر کنید. اگر یک برنامه به سرعت پس از یک شکست بهبود یابد، قابل تحمل خطا در نظر گرفته می شود. یک برنامه ابری معمولی از معماری میکروسرویس استفاده می کند - جایی که هر جزء در یک ظرف جداگانه قرار می گیرد. و برای اطمینان از اینکه برنامه در k8s بسیار در دسترس است، هنگام طراحی یک کلاستر، باید از الگوهای خاصی پیروی کنید. از جمله آنها الگوی بررسی سلامت است. تعریف می کند که چگونه برنامه سلامت خود را به k8s گزارش می دهد. این نه تنها اطلاعاتی در مورد اینکه آیا پاد در حال اجرا است، بلکه نحوه دریافت درخواست ها و پاسخ به آنها نیز است. هرچه Kubernetes درباره سلامت یک پاد اطلاعات بیشتری داشته باشد، تصمیمات هوشمندانه‌تری در مورد مسیریابی ترافیک و تعادل بار می‌گیرد. بنابراین، اصل مشاهده پذیری بالا از برنامه به موقع به درخواست ها پاسخ می دهد.

اصل مشاهده پذیری بالا (HOP)

اصل مشاهده پذیری بالا یکی از موارد است اصول طراحی برای کاربردهای کانتینری. در معماری میکرو سرور، سرویس‌ها اهمیتی نمی‌دهند که درخواستشان چگونه پردازش می‌شود (و به درستی چنین است)، اما مهم است که چگونه از سرویس‌های دریافت‌کننده پاسخ دریافت کنیم. به عنوان مثال، برای احراز هویت یک کاربر، یک کانتینر یک درخواست HTTP را به دیگری ارسال می کند و انتظار دارد پاسخی در قالب خاصی داشته باشد - همین. PythonJS می تواند درخواست را مدیریت کند و Python Flask می تواند پاسخ دهد. ظروف برای یکدیگر مانند جعبه های سیاه با محتویات پنهان هستند. با این حال، اصل HOP هر سرویس را ملزم می‌کند که چندین نقطه پایانی API را نشان دهد که نشان‌دهنده سلامت آن و همچنین در دسترس بودن و وضعیت شکست آن است. این معیارها همان چیزی است که Kubernetes برای در نظر گرفتن مراحل بعدی در مسیریابی و تعادل بار درخواست می کند.

یک برنامه ابری با طراحی خوب، رویدادهای اصلی خود را با استفاده از جریان‌های ورودی/خروجی استاندارد STDERR و STDOUT ثبت می‌کند. سپس یک سرویس کمکی مانند filebeat، logstash یا fluentd ارائه می‌شود که گزارش‌ها را به یک سیستم نظارت متمرکز (مانند Prometheus) و یک سیستم جمع‌آوری گزارش (مجموعه نرم‌افزار ELK) تحویل می‌دهد. نمودار زیر نحوه عملکرد یک برنامه ابری را بر اساس الگوی بررسی سلامت و اصل مشاهده پذیری بالا نشان می دهد.

بهترین روش ها برای ظروف Kubernetes: بررسی های سلامت

چگونه الگوی بررسی سلامت را در Kubernetes اعمال کنیم؟

خارج از جعبه، k8s وضعیت پادها را با استفاده از یکی از کنترلرها (استقرار, ReplicaSets, DaemonSets, StatefulSets و غیره و غیره). کنترلر پس از اینکه متوجه شد غلاف به دلایلی از کار افتاده است، سعی می کند آن را مجددا راه اندازی کند یا به گره دیگری منتقل کند. با این حال، یک pod ممکن است گزارش دهد که آماده و در حال اجرا است، در حالی که خودش کار نمی کند. بیایید مثالی بزنیم: برنامه شما از Apache به عنوان یک وب سرور استفاده می کند، شما کامپوننت را روی چندین Cluster pod نصب کرده اید. از آنجایی که کتابخانه به درستی پیکربندی نشده است، تمام درخواست های برنامه با یک کد 500 پاسخ داده می شود (خطای سرور داخلی). هنگام تأیید یک تحویل، بررسی وضعیت غلاف ها با موفقیت انجام می شود، اما مشتریان طور دیگری فکر می کنند. ما این وضعیت نامطلوب را به شرح زیر توصیف می کنیم:

بهترین روش ها برای ظروف Kubernetes: بررسی های سلامت

در مثال ما، k8s این کار را انجام می دهد بررسی سلامت. در این نوع اعتبارسنجی، kubelet به طور مداوم وضعیت فرآیند را در ظرف بررسی می کند. به محض اینکه بفهمد این روند متوقف شده است، آن را دوباره راه اندازی می کند. اگر خطا به سادگی با راه اندازی مجدد برنامه برطرف شد و برنامه به گونه ای طراحی شده است که در صورت هرگونه خطا خاموش شود، یک بررسی سلامت فرآیند برای شما کافی است تا HOP و الگوی بررسی سلامت را دنبال کنید. تنها تاسف بار این است که همه خطاها با راه اندازی مجدد از بین نمی روند. برای این مورد، k8s 2 راه عمیق تر برای عیب یابی یک pod ارائه می دهد: livenessProbe и ReadinessProbe.

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

اضافه کردن نظر