Зачем контейнер паузы в модуле K8s?

Как работать с контейнером паузы в модуле K8s?

Вы когда-нибудь задумывались, зачем существуют контейнеры паузы? Когда мы создаем поды, мы не помним, что когда-либо создавали эти контейнеры паузы, так откуда они берутся? Вы можете подумать, что раз мы не создавали эти контейнеры сами, может быть, кластер K8s создал их автоматически? .Сегодня выясним как работать с контейнером паузы в модуле K8s?

Когда вы проверяете контейнеры, работающие в вашем кластере K8s, вы часто видите приостановленные контейнеры, как в следующем примере:

эти контейнеры паузы созданы K8s, и вы можете рассматривать их как бесплатные контейнеры, предоставленные K8s. 

Так называемый контейнер паузы в K8s иногда называют инфра-контейнером. Он «связан» с пользовательским контейнером и работает в том же поде.

Контейнер паузыэто суть сетевой модели Pod. Понимание контейнера паузы может помочь вам лучше понять первоначальный замысел дизайна K8s Pod.

Контейнер паузы

При создании пода процесс kubelet сначала вызывает интерфейс CRI RuntimeService.RunPodSandbox, чтобы создать среду песочницы и настроить базовую операционную среду, например сеть.

Как только Pod Sandbox установлен, kubelet может создавать в нем пользовательские контейнеры. Когда придет время удалить под, kubelet сначала удалит песочницу пода, а затем остановит все контейнеры внутри.

Контейнер паузы — это контейнер, который существует в каждом модуле, он похож на шаблон или родительский контейнер, от которого все новые контейнеры в модуле наследуют пространства имен. Контейнер паузы запускается, а затем переходит в «спящий режим».

Это «шаблонный» контейнер, который резервирует пространства имен, которые являются общими для всех контейнеров внутри модуля.

Как видно из следующего исходного кода pause.c:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>#define STRINGIFY(x) #x
#define VERSION_STRING(x) STRINGIFY(x)#ifndef VERSION
#define VERSION HEAD
#endifstatic void sigdown(int signo) {
  psignal(signo, "Shutting down, got signal");
  exit(0);
}static void sigreap(int signo) {
  while (waitpid(-1, NULL, WNOHANG) > 0)
    ;
}int main(int argc, char **argv) {
  int i;
  for (i = 1; i < argc; ++i) {
    if (!strcasecmp(argv[i], "-v")) {
      printf("pause.c %s\n", VERSION_STRING(VERSION));
      return 0;
    }
  }if (getpid() != 1)
    /* Not an error because pause sees use outside of infra containers. */
    fprintf(stderr, "Warning: pause should be the first process\n");if (sigaction(SIGINT, &(struct sigaction){.sa_handler = sigdown}, NULL) < 0)
    return 1;
  if (sigaction(SIGTERM, &(struct sigaction){.sa_handler = sigdown}, NULL) < 0)
    return 2;
  if (sigaction(SIGCHLD, &(struct sigaction){.sa_handler = sigreap,
                                             .sa_flags = SA_NOCLDSTOP},
                NULL) < 0)
    return 3;for (;;)
    pause();
  fprintf(stderr, "Error: infinite loop terminated\n");
  return 42;
}

Вы можете видеть, что контейнер pause выполняет следующие две функции.

  1. зарегистрировать различные функции обработки сигналов, которые в основном обрабатывают два типа информации: сигналы выхода и дочерние сигналы. Когда он получает SIGINT или SIGTERM, он сразу же завершает работу. Когда сигнал SIGCHLD получен, вызовите waitpid и перезапустите выходящий процесс.
  2. Основной процесс for loop вызывает функцию pause(), которая переводит процесс в спящий режим до тех пор, пока он не завершится или не получит сигнал.

Таким образом, даже если последний контейнер в поде выйдет из строя, общее пространство имен все равно будет там, потому что контейнер паузы удерживает пространство имен.

Приостановлние демонстрации контейнера

Когда вы запускаете новый процесс в системе Linux, этот процесс наследует свое пространство имен от родительского процесса. Способ запустить процесс в пространстве имен — создать новое пространство имен, отменив общее пространство имен с родительским процессом. Ниже приведен пример запуска оболочки в новом пространстве имен PID, UTS, IPC и монтирования с использованием инструмента unshare.

$ unshare --pid --uts --ipc --mount -f chroot rootfs /bin/sh

После запуска процесса вы можете добавить другие процессы в пространство имен этого процесса, чтобы сформировать под, где контейнеры в поде совместно используют пространство имен.

Используйте docker в качестве примера, давайте посмотрим, как мы можем создать под с нуля, используя контейнеры паузы и общее пространство имен.

Создане контейнера паузы

$ docker run -d --name pause gcr.io/google_containers/pause-amd64:3.0
Unable to find image 'gcr.io/google_containers/pause-amd64:3.0' locally
3.0: Pulling from google_containers/pause-amd64
a3ed95caeb02: Pull complete
f11233434377: Pull complete
Digest: sha256:163ac025575b775d1c0f9bf0bdd0f086883171eb475b5068e7defa4ca9e76516
Status: Downloaded newer image for gcr.io/google_containers/pause-amd64:3.0
aa603afaba05b18f8e53844f216d965fb2487feddd32937f56611499af24c0a1

Запуск контейнера nginx

Далее запускаем контейнер nginx:

$ docker run -d --name nginx --net=container:pause --pid=container:pause nginx

Проверка сетевых пространство имен

Сначала давайте получим PID для контейнеров pause и nginx:

$ ps -ef | grep pause
root      9377  9353  0 15:47 ?        00:00:00 /pause$ ps -ef | grep nginx
root      9932  9910  0 15:53 ?        00:00:00 nginx: master process nginx -g daemon off;

Теперь давайте проверим идентификатор сетевого пространства имен:

$ lsns | grep pause | grep net
4026532388 net 4 9377 root /pause

Как видите, идентификатор сетевого пространства имен для контейнера паузы — 4026532388.

Теперь давайте узнаем идентификатор сетевого пространства имен для nginx.

$ readlink /proc/9932/task/9932/ns/net
net:[4026532388]

Таким образом, мы можем подтвердить, что контейнер nginx использует то же сетевое пространство имен, что и контейнер pause.

Заключение

В рабочих участках расположены поды, представляющие элементами приложения. область управления управляет рабочими узлами и подами в кластере. В промышленных сферах область управления естественно запускается на некоторых компьютерах, а кластер, как правило, развёртывается на нескольких узлах, гарантируя отказоустойчивость и высокую надёжность.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Click to rate this post!
[Total: 0 Average: 0]

Leave a reply:

Your email address will not be published.