Pods
Links
Articles
- Readiness Probes
Readiness & Liveness Probes configuring and logging
- Resources
Resource Requests & Limits
- Security Contexts
Pod and container security contexts
- Selectors and Affinity
Node Selectors and Affinity
- Taints & Tolerations
Pod taints and tolerations
PODs
Pod - наименьшая сущность в k8s. Обычно, pod = контейнер по принципу 1:1. Однако, можно несколько контейнеров разместить в 1 pod, при условии, что они функционально разные. Обычно это главный контейнер приложения и вспомогательные контейнеры, которые с ним связаны.
В обычном Docker, если развернуть множество копий “контейнер приложения” + “вспомогательный контейнер”, то нужно будет иметь карту взаимосвязей между ними всеми. Более того, в случае выхода из строя контейнера с приложением, нужно будет вручную удалять сопутствующий вспомогательный контейнер. От этого всего избавляют pod-ы, в рамках которых всё размещается, обеспечивается внутренняя связность, и далее k8s размножает готовые копии pod-ов в рамках кластера.
Pod-ы добавляют функционал к контейнерам:
- Labels and annotations
- Restart policies
- Probes (startup probes, readiness probes, liveness probes, and potentially more)
- Affinity and anti-affinity rules
- Termination control
- Security policies
- Resource requests and limits
Работа с pod-ами ведётся с помощью API или инструмента kubectl:
kubectl run nginx --image nginx # образ nginx будет скачан с DockerHub
kubectl get pods # список всех pod-ов и их статусов
kubectl get pods --selector app=App1 # отфильтровать вывод по заданному label
Создание Pod через файл YAML
Создадим pod-definition.yml:
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
Далее создаём pod командой:
kubectl create -f pod-definition.yml
kubectl get pods
Посмотреть доступные поля, подробную информацию о поле у pod:
kubectl explain pods --recursive
kubectl explain pod.spec.restartPolicy
Посмотреть конкретное поле у всех pod, например, образ image, из которого он сделан:
kubectl get pods -o jsonpath={.items[*].spec.containers[*].image}
Можно у работающего Pod получить спецификацию в YAML, из которой он сделан:
kubectl get pod <имя pod> -o yaml > pod-definition.yaml
Удалить Pod
kubectl delete pod <имя Pod> --now
Зайти внутрь Pod и выполнить команды:
kubectl exec -it <имя pod> -- /bin/sh
Обновить Pod
В конфигурацию pod можно добавить период обновления (например, 30 секунд) и установить “imagePullPolicy: “Always”. Удалить Pod с помощью kubectl delete pod pod_name
. Новый контейнер будет создан на последней версии образа, после чего старый контейнер будет удалён.
spec:
terminationGracePeriodSeconds: 30
containers:
- name: my_container
image: my_image:latest
imagePullPolicy: "Always"
Есть вариант “дёргать” за Deployment, вызывая тем самым обновление:
kubectl patch deployment <имя deployment> -p \
'{"spec":{"template":{"spec":{"terminationGracePeriodSeconds":31}}}}'
Выполнение задач в Pod
Если необходимо, чтобы Pod поработал и выключился, без перезапуска, то необходимо поменять его restartPolicy
, которая по умолчанию стоит в Always
- то есть перезапуск всегда по завершении работы.
spec:
containers:
- name: my_container
image: my_image:latest
restartPolicy: Never # ещё вариант OnFailure
Императивные команды
В отличие от декларативных, такие команды позволяют быстро решить однократную задачу.
kubectl run nginx --image=nginx --dry-run=client -o yaml # --dry-run=client - не создаёт объект, сообщает о возможности его создания
kubectl run httpd --image=httpd:alpine --port=80 --expose=true # создать Pod из образа httpd:alpine и к нему сразу создать ClusterIP с публикацией порта
Multi-Container PODs
Несколько контейнеров в 1 POD делят один адрес IP (между собой они общаются через адаптер localhost), хранилище. Есть несколько типовых сценариев:
- Sidecar pattern - самый популярный случай, один контейнер отрабатывает задачу (например, выгрузки данных на веб-сайт), а другой решает вспомогательную задачу (например, синхронизация данных для последующей выгрузки);
- Init pattern - перед запуском контейнера с основным ПО сначала стартует вспомогательный контейнер, который производит настройку окружения;
- Adapter pattern - ПО в основном контейнере обрабатывает данные, а вспомогательный контейнер передаёт эти данные в другое приложение в понятном ему формате. Например, система SIEM не понимает формат логов приложения, и вспомогательный модуль парсит и транслирует логи в понятный для SIEM формат;
- Ambassador pattern - ПО в основном контейнере отрабатывает задачи, а вспомогательный контейнер вызывает через API внешние системы, чтобы собрать с них данные для обработки, либо передать данные в эти системы.
PODы стартуют атомарно - только после успешного старта всех контейнеров POD считается запущенным. Частичный запуск не допускается. POD целиком всеми контейнерами размещается на одной ноде worker.
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: nginx-container
image: nginx
ports:
- containerPort: 8080
- name: log-agent
image: log-agent
InitContainer - не живёт постоянно, а выполняется ДО загрузки остальных контейнеров в Pod, поэтому его инициализация - в отдельной секции:
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: nginx
ports:
- containerPort: 8080
initContainers:
- name: init-service
image: busybox
command: [ 'sh', '-c', 'git clone <some repo to be used by app>' ]
Если таких InitContainer несколько, они будут выполняться последовательно один за другим. Если любой InitContainer не сможет выполниться успешно, k8s будет перезапускать Pod, пока InitContainer успешно не завершится.
Ручное распределение (manual scheduling)
Если в кластере нет распределения, можно указать вручную параметр nodeName:
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
spec:
containers:
- name: nginx-container
image: nginx
nodeName: node01
Без указания этого параметра в отсутствии распределения Pod будет висеть как Pending. K8s не даст указать этот параметр на лету, после добавления Pod надо заменить kubectl replace --force -f nginx-pod.yaml