Kubernetes: Pods

Pods of K8s

Posted by Vrublevskit Vitaliy on August 20, 2021 · 6 mins read

Kubernetes: Pods

Что это?

Kubernetes содержит свои собственные абстракции, “наименьшей” из них является Pod - это объединение одного или несколько контейнеров. Возьмем для примера небольшое приложение ожидающие HTTP запросы, исходный код приложения:

const http = require('http');
const os = require('os');
console.log("Kubia server starting...");
var handler = function(request, response) {
console.log("Received request from " + request.connection.remoteAddress);
response.writeHead(200);
response.end("You've hit " + os.hostname() + "\n");
};
var www = http.createServer(handler);
www.listen(8080);

Совет: Если у вас не работает “автодоплнение”, добавить его можно командой echo "source <(kubectl completion bash)" >> ~/.bashrc и перезагружает окружение через source ~/.bashrc, теперь при нажатии на TAB вам будет доступно “автодолнение”.

Самым простым способом развернуть что либо в “кубере” является использование Command Line Interface (CLI), давайте попробуем запустить наше приложение исходный код которого я показал выше:

kubectl run my-pod --image=luksa/kubia --port=8080

Пояснение:

kubectl - Вызвает исполняемый файл

run - Команда для создания разного рода сущностей

my-pod - Имя нашего первого “пода”, внутри которого раходится контейнер.

--image - Указываем на то какой “образ” мы ходим запустить внутри пода

luksa/kubia - Репозиторий в dockerhub который содержит образ.

--port=8080 - Сообщаем “куберу” что наше приложение прослушывает порт 8080 (Не пытайтесь проверить работу приложения локально, сейчас мы лишь сообщили куберу что для приложение необходим порт)

Теперь убедимся что создали “под” командой kubectl get pod, далее мы получим ответ:

NAME     READY   STATUS              RESTARTS   AGE
my-pod   0/1     ContainerCreating   0          3s

Что все это значит? Каждый из этих “столбцов” несет полезную нагрузку, а именно:

Name - Имя запущеных подов. (Помните мы использовали в качества названия my-pod?)

Ready - Статус подов сообщает нам что ожидается 1 под, на текущий момент запущено 0 подов.

Status - Текущий статус пода (Если вы только запустили, кубернетесу нужно время чтобы “загрузить” образ из хранилища и запустить из него под)

Restarts - Колличество перезагрузок пода, как правило это происходит если что то идет не так (нет доступа к приватному репозиторию, не проходят какие либо проверки и т.п.)

AGE - Время жизни пода.

Спустя какое то время(это зависит от вашей скорости соединения для загрузки образа), выполнив команду вновь мы можем увидеть что статус пода изменился:

NAME     READY   STATUS    RESTARTS   AGE
my-pod   1/1     Running   0          3m

Поздравляю, вы запустили свой первый под в кубернетесе! Но наше приложение все еще недоступно “локально”, если вы попытаетесь запустить и открыть в браузере http://localhost:8080/ увидите ошибку. Так происходит потому что кубернетес имеет микросервисную архитектуру в которой каждая абстракция(сущность) выполняет только выделеную для нее задачу. Сущность “под” НЕ отвечает за сеть и доступность ее внутри кластера, для этого имеется отдельная абстракция “сервис” (service), давайте сделаем доступным наш под для доступа “снаружи”, для этого мы используем CLI команду:

kubectl expose pod my-pod --name=my-service --type=NodePort --port=8080

kubectl - Вызваем исполняемый файл.

expose - Команда для работы с абстракциями отвечающими за “сеть” и “доступность” других сущностей в kubernetes.

pod - Указываем сущность которую мы хотим сделать доступной.

my-pod - Имя нашего пода который хотим сделать доступным.

--name=my-service - Иия для нашего сервиса который отвечает за доступность.

--type=NodePort - Указываем типа доступа, сейчас мы используем NodePort он вполне подойдет для локальных тестов, далее я познакомлю вас с иными типами доступа и различиях между ними.

--port=8080 - Порт внутри пода который мы ходим сделать доступным.

Теперь наш pod доступен для просмотра и ответа “снаружи”, напирмер для запросов через браузер или curl, но какой у него порт? Для этого необходимо убедиться что все прошло успешно и сервис действительно доступен командой kubectl get svc которая вернет нам такой ответ:

NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
my-service   NodePort    10.105.131.60   <none>        8080:30366/TCP   23s

Видим некоторые похожие колонки из предыдущего ответа, когда мы смотрели запущеные поды, уточним:

Name - Имя сущности в нашем случае сервиса созданого нами my-service.

TYPE - Тип сервиса который мы создали NodePort (о типах поговорим в другой статье).

CLUSTER-IP - Это виртуальный IP адрес внутри кубернетес кластера, зачем и как он используется я объясню позже.

EXTERNAL-IP - Внешний IP который используется для доступа к указаным сервисам, например если мы использовали бы тип сервиса LoadBalancer доступный лишь в облачных системах (Например AWS), тут появился бы адрес балансировкщика который нам выделил AWS.

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

AGE - Время жизни этого сервиса.

Теперь вы можете открыть этот адрес на своей локальной машине и убедиться что ваш первый под работает и отвечает на запросы! (Проверьте внимательно порт который используется для доступа снаружи, кубернетес генерирует их случайным образом каждый раз при создании, в диапозоне от 30000 до 32767).

Пример запроса к поду из примера:

$ curl http://localhost:30366/
You've hit my-pod