kubernetes. POD - теория часть 1

Thank you for reading this post, don't forget to subscribe!

(Pods) - наи­мень­шей функ­ци­о­наль­ной еди­ни­цей для раз­вер­ты­ва­ния в объ­ект­ной моде­ли Kubernetes.

Pod (пере­во­дит­ся с англий­ско­го как стру­чок) состо­ит обыч­но из одно­го или несколь­ких кон­тей­не­ров, хра­ни­ли­ща (storage), отдель­но­го IP-адре­са и опций, кото­рые опре­де­ля­ют, как имен­но контейнер(ы) долж­ны запус­кать­ся. Так­же Pod пред­став­ля­ет собой некий запу­щен­ный про­цесс в кла­сте­ре Kubernetes.

Чаще все­го в Pod'ах исполь­зу­ют­ся docker-кон­тей­не­ры, но мож­но исполь­зо­вать и дру­гие кон­тей­не­ры (напри­мер, rkt от CoreOS).

Важ­но Kubernetes управ­ля­ет Pod'ами, а не кон­тей­не­ра­ми напрямую.

В кла­сте­ре Kubernetes Pod'ы исполь­зу­ют­ся дву­мя способами:

  • Pod из одно­го кон­тей­не­ра - наи­бо­лее рас­про­стра­нен­ный слу­чай исполь­зо­ва­ния. В этом вари­ан­те Pod мож­но пред­ста­вить как оберт­ку вокруг одно­го контейнера;
  • Pod из несколь­ких кон­тей­не­ров, рабо­та­ю­щих сооб­ща - кон­тей­не­ры в дан­ном слу­чае обра­зу­ют отдель­ную еди­ни­цу (сер­вис) и исполь­зу­ют общие ресур­сы - напри­мер, фай­лы из одно­го хра­ни­ли­ща (storage). При этом, отдель­ный кон­тей­нер Pod'а может обнов­лять эти файлы.

Каж­дый Pod пред­на­зна­чен для запус­ка одно­го экзем­пля­ра кон­крет­но­го при­ло­же­ния. Если есть необ­хо­ди­мость гори­зон­таль­но­го мас­шта­би­ро­ва­ния, то мож­но запу­стить несколь­ко экзем­пля­ров Pod'а - в тер­ми­но­ло­гии Kubernetes это назы­ва­ет­ся репли­ка­ци­ей. Реп­ли­ци­ро­ван­ные Pod'ы созда­ют­ся и управ­ля­ют­ся как еди­ная груп­па абстрак­ци­ей, кото­рая назы­ва­ет­ся кон­трол­лер (Controller).

Pod'ы спро­ек­ти­ро­ва­ны для под­держ­ки мно­же­ства вза­и­мо­дей­ству­ю­щих про­цес­сов (напри­мер, кон­тей­не­ров), кото­рые обра­зу­ют отдель­ный сер­вис (еди­ни­цу обслу­жи­ва­ния). Кон­тей­не­ры внут­ри Pod'а авто­ма­ти­че­ски раз­ме­ща­ют­ся и управ­ля­ют­ся на одной и той же физи­че­ской (или вир­ту­аль­ной) ноде кла­сте­ра. Кон­тей­не­ры в Pod'е могут сов­мест­но исполь­зо­вать ресур­сы и зави­си­мо­сти, вза­и­мо­дей­ство­вать друг с дру­гом и опре­де­лять, когда и как они будут завершаться.

К сло­ву, груп­пи­ров­ка и запуск несколь­ких кон­тей­не­ров в Pod'е счи­та­ет­ся “про­дви­ну­тым” вари­ан­том исполь­зо­ва­ния, и при­ме­нять этот шаб­лон нуж­но толь­ко при реаль­ной необ­хо­ди­мо­сти. Напри­мер, у вас может быть кон­тей­нер с web-сер­ве­ром, исполь­зу­ю­щий фай­лы из обще­го (отно­си­тель­но Pod'а) хра­ни­ли­ща, и отдель­ный кон­тей­нер, кото­рый обнов­ля­ет эти фай­лы из уда­лен­но­го источника.

Pod'ы предо­став­ля­ют запу­щен­ным внут­ри кон­тей­не­рам два типа общих ресур­сов: сеть и хра­ни­ли­ще.

Сеть

Каж­до­му Pod'у при­сва­и­ва­ет­ся уни­каль­ный IP-адрес. Внут­ри Pod'а каж­дый кон­тей­нер исполь­зу­ет общее про­стран­ство имен (namespace) сети, вклю­чая IP-адрес и сете­вые пор­ты. Меж­ду собой внут­ри Pod'а кон­тей­не­ры вза­и­мо­дей­ству­ют через localhost. При вза­и­мо­дей­ствии с объ­ек­та­ми, нахо­дя­щи­ми­ся за пре­де­ла­ми Pod'а, кон­тей­не­ры “дого­ва­ри­ва­ют­ся” меж­ду собой и коор­ди­ни­ру­ют исполь­зо­ва­ние общих сете­вых ресур­сов (таких как порты).

Хранилище

Pod может опре­де­лить набор общих томов (volumes) для хра­не­ния дан­ных. Кон­тей­не­ры внут­ри Pod'а могут рабо­тать с эти­ми тома­ми и, таким обра­зом, обме­ни­вать­ся дан­ны­ми меж­ду собой. Бла­го­да­ря исполь­зо­ва­нию томов, мож­но сохра­нить дан­ные, если один из кон­тей­не­ров Pod'а (кото­ро­му нуж­ны эти дан­ные для кор­рект­ной рабо­ты) дол­жен быть пере­за­пу­щен. Вре­мя жиз­ни томов сов­па­да­ет с вре­ме­нем жиз­ни само­го Pod'а.

Что каса­ет­ся рабо­ты в кла­сте­ре Kubernetes, то ред­ко когда при­хо­дит­ся созда­вать и запус­кать отдель­ные Pod'ы вруч­ную (вари­ан­ты запус­ка при озна­ком­ле­нии с Kubernetes мы в рас­чет не берем). Свя­за­но это с тем, что Pod'ы изна­чаль­но про­ек­ти­ро­ва­лись как эфе­мер­ные объ­ек­ты, мини­маль­ные еди­ни­цы, “стро­и­тель­ные бло­ки” для сущ­но­стей более высо­ко­го уров­ня (напри­мер, кон­трол­ле­ров). Когда Pod созда­ет­ся (не важ­но, вруч­ную вами или кон­трол­ле­ром), он по пла­ну (за это отве­ча­ет scheduler) запус­ка­ет­ся на одной из нод кла­сте­ра Kubernetes. На этой ноде Podоста­ет­ся до тех пор, пока:

  • не завер­шит­ся про­цесс внут­ри Pod'а (напри­мер, если это одно­ра­зо­вая задача);
  • Pod не будет уда­лен вручную;
  • Pod не будет “высе­лен” с ноды из-за нехват­ки ресурсов;
  • нода не вый­дет из строя.

При­ме­ча­ние Пере­за­пуск кон­тей­не­ра внут­ри Pod'а не сле­ду­ет путать с пере­за­пус­ком само­го Pod'а.

Сами по себе Pod'ы не явля­ют­ся “само­ле­ча­щи­ми­ся” (self-healing) объ­ек­та­ми. Если запуск Pod'а запла­ни­ро­ван на ноде, кото­рая вышла из строя, или сама опе­ра­ция запус­ка потер­пе­ла крах, то Pod уда­ля­ет­ся. Точ­но так­же, при нехват­ке ресур­сов на ноде (когда Pod'ы “высе­ля­ют­ся”) или при пере­во­де ноды в режим обслу­жи­ва­ния, Pod'ы не будут запу­ще­ны на дру­гих узлах и уда­лят­ся. Для обес­пе­че­ния запус­ка на дру­гих нодах (и управ­ле­ния Pod'ами в целом) в Kubernetesисполь­зу­ют­ся абстрак­ции более высо­ко­го уров­ня, назы­ва­е­мые кон­трол­ле­ра­ми - в основ­ном имен­но с ними и при­хо­дит­ся иметь дело.

Кон­трол­лер может управ­лять несколь­ки­ми экзем­пля­ра­ми Pod'ов - в том чис­ле обес­пе­чи­вать репли­ка­цию и само­вос­ста­нов­ле­ние в пре­де­лах кла­сте­ра (при выхо­де из строя ноды, иден­тич­ный экзем­пляр Pod'а будет запу­щен на дру­гой ноде). При­ме­ром кон­трол­ле­ра, кото­рый содер­жит в себе один или несколь­ко экзем­пля­ров Pod'а могут быть:

  • Deployment
  • StatefulSet
  • DaemonSet

Для обес­пе­че­ния тако­го функ­ци­о­на­ла кон­трол­ле­ры исполь­зу­ют шаб­ло­ны Pod'ов (Pod Templates). Шаб­лон Pod'а - спе­ци­фи­ка­ция, кото­рая исполь­зу­ет­ся кон­трол­ле­ра­ми и дру­ги­ми объ­ек­та­ми (напри­мер, зада­ни­я­ми - Jobs/CronJob) для запус­ка насто­я­ще­го, реаль­но­го Pod'а. Ниже при­ве­ден при­мер про­стой спе­ци­фи­ка­ции (ее еще ино­гда назы­ва­ют мани­фе­стом), опи­сы­ва­ю­щей кон­тей­нер, кото­рый напе­ча­та­ет сооб­ще­ние при запус­ке и “уснет” на час:

Пред­ло­жен­ный мани­фест (спе­ци­фи­ка­цию) мож­но сохра­нить в фай­ле single-example-pod.yml и запу­стить Pod с помо­щью ути­ли­ты команд­ной стро­ки kubectl:

Боль­ше инфор­ма­ции о Pod'ах мож­но най­ти в офи­ци­аль­ной доку­мен­та­ции по Kubernetes.