Лепшыя практыкі для кантэйнераў Kubernetes: праверкі працаздольнасці

Лепшыя практыкі для кантэйнераў Kubernetes: праверкі працаздольнасці

TL, д-р

  • Каб дамагчыся высокай назіральнасці кантэйнераў і мікрасэрвісаў, часопісаў і першасных метрык мала.
  • Для больш хуткага аднаўлення і павышэння адмоваўстойлівасці прыкладання павінны прымяняць Прынцып высокай назіральнасці (HOP, High Observability Principle).
  • На ўзроўні прыкладанне для НОР патрабуецца: належнае часопісаванне, дбайны маніторынг, праверкі працаздольнасці і трасіроўкі прадукцыйнасці/пераходаў.
  • У якасці элемента НОР выкарыстоўвайце праверкі readinessProbe и livenessProbe Kubernetes.

Што такое Шаблон праверкі працаздольнасці?

Калі праектуеш крытычна важнае і высокадаступнае прыкладанне, вельмі важна падумаць аб такім аспекце, як адмоваўстойлівасць. Дадатак лічыцца адмоваўстойлівасцю, калі яно хутка аднаўляецца пасля адмовы. Тыповая хмарнае прыкладанне выкарыстоўвае архітэктуру мікрасэрвісаў - калі кожны кампанент змяшчаецца ў асобны кантэйнер. А для таго, каб пераканацца, што дадатак на k8s высокадаступна, калі праектуеш кластар, трэба прытрымлівацца пэўных шаблонаў. Сярод іх - Шаблон праверкі працаздольнасці. Ён вызначае, як дадатак паведамляе k8s аб сваёй працаздольнасці. Гэта не толькі інфармацыя аб тым, ці працуе pod, а яшчэ і аб тым, як ён прымае запыты і адказвае на іх. Чым больш Kubernetes ведае аб працаздольнасці pod'а, тым больш разумныя рашэнні прымае аб маршрутызацыі трафіку і балансаванні нагрузкі. Такім чынам, Прынцып высокай назіральнасці з дадаткам своечасова адказваць на запыты.

Прынцып высокай назіральнасці (НОР)

Прынцып высокай назіральнасці - гэта адзін з прынцыпаў праектавання кантэйнерызаваных прыкладанняў. У мікрасеўрыснай архітэктуры сэрвісам абыякава, як іх запыт апрацоўваецца (і гэта правільна), але важна, як атрымаць адказы ад якія прымаюць сэрвісаў. Да прыкладу, для аўтэнтыфікацыі карыстальніка адзін кантэйнер пасылае іншаму запыт HTTP, чакаючы адказу ў вызначаным фармаце - вось і ўсё. Апрацоўваць запыт можа і PythonJS, а адказаць - Python Flask. Кантэйнеры адзін для аднаго - што чорныя скрыні са схаваным змесцівам. Аднак прынцып НОР патрабуе, каб кожны сэрвіс расчыняў некалькі канчатковых кропак API, якія паказваюць, наколькі ён працаздольны, а таксама стан яго гатовасці і адмоваўстойлівасці. Гэтыя паказчыкі і запытвае Kubernetes, каб прадумваць наступныя крокі па маршрутызацыі і балансіроўка нагрузкі.

Пісьменна спраектаванае хмарнае прыкладанне часопісуе свае асноўныя падзеі выкарыстоўваючы стандартныя патокі ўводу-вываду STDERR і STDOUT. Следам працуе дапаможны сэрвіс, да прыкладу filebeat, logstash або fluentd, якія дастаўляюць часопісы ў цэнтралізаваную сістэму маніторынгу (напрыклад Prometheus) і сістэму збору часопісаў (набор ПА ELK). На схеме ніжэй паказана, як хмарнае прилоежние працуе ў адпаведнасці з Шаблонам праверкі працаздольнасці і Прынцыпам высокай назіральнасці.

Лепшыя практыкі для кантэйнераў Kubernetes: праверкі працаздольнасці

Як прымяніць Шаблон праверкі працаздольнасці ў Kubernetes?

Са скрынкі k8s маніторыць стан pod'ов пры дапамозе аднаго з кантролераў.разгортвання, ReplicaSets, DaemonSets, StatefulSets і інш., інш.). Выявіўшы, што pod па нейкім чынніку зваліўся, кантролер спрабуе отрестартить яго ці перашэдуліць на іншы вузел. Аднак pod можа паведаміць, што ён запушчаны і працуе, а сам пры гэтым не функцыянуе. Прывядзем прыклад: ваша прыкладанне выкарыстоўвае ў якасці вэб-сервера Apache, вы ўстанавілі кампанент на некалькі pod'аў кластара. Паколькі бібліятэка была настроена некарэктна – усе запыты да дадатку адказваюць кодам 500 (унутраная памылка сервера). Пры праверцы пастаўкі праверка стану pod`ов дае паспяховы вынік, аднак кліенты лічаць інакш. Гэтую непажаданую сітуацыю мы апішам наступным чынам:

Лепшыя практыкі для кантэйнераў Kubernetes: праверкі працаздольнасці

У нашым прыкладзе k8s выконвае праверку працаздольнасці. У гэтым выглядзе праверкі kubelet увесь час правярае стан працэсу ў кантэйнеры. Варта яму зразумець, што працэс устаў, і ён яго рэстартуе. Калі памылка ўстараняецца простым перазапускам прыкладання, а праграма спраектавана так, каб адключацца пры любой памылцы, тады вам для прытрымлівання НОР і Шаблону праверкі працаздольнасці дастаткова праверкі працаздольнасці працэсу. Шкада толькі, што не ўсе памылкі ўхіляюцца перазапускам. На гэты выпадак k8s прапануе 2 глыбейшых спосабу выяўлення непаладак у працы pod'а: livenessProbe и readinessProbe.

LivenessProbe

Падчас livenessProbe kubelet выконвае 3 тыпы праверак: не толькі высвятляе, ці працуе pod, але і ці гатовы ён атрымліваць і адэкватна адказваць на запыты:

  • Усталяваць HTTP-запыт да pod'у. Адказ павінен утрымоўваць HTTP-код адказу ў дыяпазоне ад 200 да 399. Такім чынам, коды 5хх і 4хх сігналізуюць аб тым, што ў pod'а праблемы, няхай нават працэс працуе.
  • Для праверкі pod'аў з не-HTTP сэрвісамі (напрыклад, паштовы сервер Postfix), трэба ўсталяваць TCP-сувязь.
  • Выкананне адвольнай каманды для pod'а (унутрана). Праверка лічыцца паспяховай, калі код завяршэння каманды - 0.

Прыклад таго, як гэта працуе. Вызначэнне наступнага pod'а ўтрымоўвае NodeJS дадатак, якое на HTTP-запыты выдае памылку 500. Каб пераканацца, што кантэйнер перазапускаецца, атрымаўшы такую ​​памылку, мы выкарыстаем параметр 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

Праз некалькі секунд можна праверыць змесціва pod'а з дапамогай наступнай каманды:

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')
})

Докер-файл

FROM node
COPY app.js /
EXPOSE 3000
ENTRYPOINT [ "node","/app.js" ]

Важна звярнуць увагу вось на што: livenessProbe перазапусціць кантэйнер, толькі пры адмове. Калі перазапуск не выправіць памылку, якая замінае працы кантэйнера, kubelet не зможа прыняць меры для ўхілення няспраўнасці.

readinessProbe

readinessProbe працуе аналагічна livenessProbes (GET-запыты, ТСР сувязі і выкананне каманд), за выключэннем дзеянняў па ўхіленні няспраўнасцяў. Кантэйнер, у якім зафіксаваны збой, не перазапускаецца, а ізалюецца ад уваходнага трафіку. Прадстаўце, адзін з кантэйнераў выконвае шмат вылічэнняў ці падвяргаецца цяжкай нагрузцы, з-за чаго вырастае час адказу на запыты. У выпадку livenessProbe спрацоўвае праверка даступнасці адказу (праз параметр праверкі timeoutSeconds), пасля чаго kubelet перазапускае кантэйнер. Пры запуску кантэйнер пачынае выконваць рэсурсаёмістыя задачы, і яго зноў перазапускаюць. Гэта можа быць крытычна для прыкладанняў, якім важна хуткасць адказу. Напрыклад, машына прама ў шляхі чакае адказу ад сервера, адказ затрымоўваецца і машына пападае ў аварыю.

Давайце напішам вызначэнне redinessProbe, якое ўсталюе час адказу на GET-запыт не больш за дзве секунды, а дадатак будзе адказваць на GET-запыт праз 5 секунд. Файл 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

У канцы вываду можна ўбачыць, што частка падзей аналагічная вось гэтаму.

Як бачыце, kubectl не стаў перазапускаць pod, калі час праверкі перавысіла 2 секунды. Замест гэтага ён адмяніў запыт. Уваходныя сувязі перанакіроўваюцца на іншыя, працоўныя pod'ы.

Заўважце: зараз, калі з pod'а знятая лішняя нагрузка, 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, д-р
Да з'яўлення хмарных прыкладанняў асноўным сродкам маніторынгу і праверкі стану прыкладанняў былі логі. Аднак не было сродкаў прадпрымаць нейкія меры па ўхіленні непаладак. Логі і сёння карысныя, іх трэба збіраць і адпраўляць у сістэму зборкі логаў для аналізу аварыйных сітуацый і прыняцці рашэнняў. [гэта ўсё можна было рабіць і без хмарных прыкладанняў з дапамогай monit, да прыкладу, але з k8s гэта стала значна прасцей 🙂 – заўв.рэд. ]

Сёння ж выпраўленні даводзіцца ўносіць ці ледзь не ў рэжыме рэальнага часу, таму прыкладанні больш не павінны быць чорнымі скрынямі. Не, яны павінны паказваць канчатковыя кропкі, якія дазваляюць сістэмам маніторынгу запытваць і збіраць каштоўныя дадзеныя аб стане працэсаў, каб у выпадку неабходнасці рэагаваць імгненна. Гэта называецца Шаблон праектавання праверкі працаздольнасці, які варта Прынцыпу высокай назіральнасці (НОР).

Kubernetes па змаўчанні прапануе 2 віды праверкі працаздольнасці: readinessProbe і livenessProbe. Абодва выкарыстоўваюць аднолькавыя тыпы праверак (HTTP GET запыты, ТСР-сувязі і выкананне каманд). Адрозніваюцца яны ў тым, якія рашэнні прымаюць у адказ на непаладкі ў pod'ах. livenessProbe перазапускае кантэйнер у надзеі, што памылка больш не паўторыцца, а readinessProbe ізалюе pod ад уваходнага трафіку - да ўхілення чынніку непаладкі.

Правільнае праектаванне прыкладання павінна ўключаць і той, і іншы від праверкі, і каб яны збіралі дастаткова дадзеных, асабліва калі створана выключная сітуацыя. Яно таксама павінна паказваць неабходныя канчатковыя кропкі API, якія перадаюць сістэме маніторынгу (таму ж Prometheus) важныя метрыкі стану працаздольнасці.

Крыніца: habr.com

Дадаць каментар