У цьому посібнику я детально описав концепцію Kubernetes pod, використовуючи практичні приклади та сценарії використання.
Мета цього посібника - допомогти вам зрозуміти будівельні блоки, з яких складається pod, і виконати практичну реалізацію розгортання pod і доступу до запущеної на ньому програми.
Крім того, існує багато понять, пов'язаних з об'єктом Pod. Тому я надав всю інформацію та концепції, пов'язані з под, щоб надалі спиратися на основи, які ви вже вивчили.
Зауваження: Перш ніж почати вивчати контейнери Kubernetes, переконайтеся, що ви добре розумієте концепцію контейнерів Linux.
Що таке Kubernetes Pod?
Перш ніж перейти до концепції Kubernetes Pod, давайте розберемося з контейнерами.
Контейнер, як ми всі знаємо, це автономне середовище, в якому ми пакуємо застосунки та їхні залежності. Зазвичай контейнер запускає один процес (хоча існують способи запуску декількох процесів). Кожен контейнер отримує IP-адресу і може приєднувати томи, керувати ресурсами процесора і пам'яті, та багато іншого. Все це відбувається за допомогою просторів імен та груп керування.
Kubernetes - це система оркестрування контейнерів для розгортання, масштабування та керування контейнерними програмами, яка має власний спосіб запуску контейнерів. Ми називаємо його "pod". Контейнер - це найменша одиниця розгортання у Kubernetes, яка являє собою один екземпляр програми.
Наприклад, якщо ви хочете запустити програму Nginx, ви запускаєте її в поді.
Чим же він відрізняється від контейнера?
Контейнер - це одна одиниця. Однак, в одному под може міститися більше одного контейнера. Ви можете уявити собі под як коробку, яка може містити один або декілька контейнерів разом.
Pod надає вищий рівень абстракції, який дозволяє вам керувати декількома контейнерами як єдиним цілим. У цьому випадку замість того, щоб кожен контейнер отримував окрему IP-адресу, блок отримує єдину унікальну IP-адресу, а контейнери, що працюють всередині блоку, використовують localhost для з'єднання один з одним через різні порти.
Це означає, що контейнери всередині Kubernetes мають спільний доступ до наступних ресурсів
- Мережевий простір імен - всі контейнери у поді взаємодіють через localhost.
- Простір імен IPC: Всі контейнери використовують спільний простір імен для міжпроцесної взаємодії.
- Простір імен UTS: Всі контейнери мають однакове ім'я хоста.
Що не ділиться між контейнерами в межах одного сокета?
- За замовчуванням, простір імен PID не є спільним, однак у kubernetes передбачено можливість увімкнути спільний доступ до процесів між контейнерами в поді за допомогою опції
shareProcessNamespace
. - Простір імен монтування не є спільним для контейнерів. Кожен контейнер має власну приватну файлову систему і каталоги. Однак, томи монтування у подах є спільними для всіх контейнерів.
У двох словах, ось що ви повинні знати про под:
- Поди - це найменші розгортаємі одиниці в Kubernetes.
- Поди ефемерні за своєю природою; їх можна створювати, видаляти та оновлювати.
- В одному поді може бути більше одного контейнера; немає ніяких обмежень на кількість контейнерів, які ви можете запустити всередині одного поду.
- Кожен под отримує унікальну IP-адресу.
- Контейнери спілкуються один з одним використовуючи IP-адресу.
- Контейнери всередині одного поду з'єднуються за допомогою
localhost
на різних портах. - Контейнери, що працюють в межах одного поду, повинні мати різні номери портів, щоб уникнути конфліктів портів.
- Ви можете налаштувати ресурси процесора і пам'яті для кожного контейнера, що працює всередині поду.
- Контейнери всередині поду мають спільну точку монтування для томів.
- Усі контейнери в межах одного поду розміщуються на одному вузлі; він не може охоплювати декілька вузлів.
Pod YAML (визначення об'єкта)
Тепер, коли ми маємо базове уявлення про под, розглянемо, як ми його визначаємо. Под - це нативний об'єкт Kubernetes, і якщо ви хочете створити под, вам потрібно задекларувати вимоги до нього у форматі YAML. Ви також можете створити под за допомогою імперативної команди kubectl
. Про це ми поговоримо у наступній темі.
Ось приклад Pod YAML, який створює под для веб-сервера Nginx. Цей YAML є нічим іншим, як декларативним описом бажаного стану подів.
apiVersion: v1
kind: Pod
metadata:
name: web-server-pod
labels:
app: web-server
environment: production
annotations:
description: This pod runs the web server
spec:
containers:
- name: web-server
image: nginx:latest
ports:
- containerPort: 80
Розберімося в цьому YAML. Як тільки ви зрозумієте базовий YAML, вам буде легше працювати з подами та пов'язаними з ними об'єктами, такими як deployment
, daemonset
, statefulset
тощо.
Кожен об'єкт Kubernetes має певний загальний набір параметрів. Значення змінюються залежно від типу об'єкта, який ми створюємо.
Розгляньмо об'єкт Kubernetes pod.
Параметр | Опис |
---|---|
apiVersion | Версія API pod. У нашому випадку це v1 |
kind | Вид об'єкта. Його pod |
metadata | метадані використовуються для однозначної ідентифікації та опису стручка - labels (набір пар ключ-значення для представлення кадру). Це схоже на тегування у хмарних середовищах. Кожен об'єкт має бути позначений стандартними мітками. Це допомагає групувати об'єкти. - name (ім'я тома) - namespace (простір імен для подів) - annotations (додаткові дані у форматі ключ-значення) |
spec | У секції spec ми оголошуємо бажаний стан контейнера. Це специфікації контейнерів, які ми хочемо запустити всередині бода. |
containers | У розділі containers ми оголошуємо бажаний стан контейнерів усередині бода. Зображення контейнера, відкритий порт тощо. |
Ми розглянули базовий маніфест Pod YAML. Важливо зазначити, що цей маніфест підтримує багато параметрів. Ми будемо поступово вивчати ці додаткові параметри, застосовуючи практичний підхід.
Тепер, коли у нас є базові уявлення про pod, перейдемо до створення pod'а.
Створення Pod
Створити pod можна двома способами
-
За допомогою імперативної команди
kubectl
: Переважно використовується для навчання та тестування. Імперативна команда має свої обмеження. - Декларативний підхід: Використання маніфесту YAML. При роботі над проєктами для розгортання подів використовується маніфест YAML.
Тепер розглянемо обидва варіанти. Ми збираємося розгорнути nginx-под з наступними даними
- Ім'я поду -
web-server-pod
- Він повинен мати мітки
app: web-server
іenvironment: production
- Додайте анотацію, щоб описати pod.
- Використовуйте образ контейнера
nginx:1.14.2
. - Відкрийте для контейнера порт
80
.
Створення поду за допомогою імперативної команди Kubectl
Примітка: Імперативні команди Kubectl дуже важливі, коли ви подаєтесь на сертифікацію Kubernetes.
Ось команда kubectl для описаних вище вимог
kubectl run web-server-pod \
--image=nginx:1.14.2 \
--restart=Never \
--port=80 \
--labels=app=web-server,environment=production \
--annotations description="This pod runs the web server"
Тут под розгортається у стандартному просторі імен. Ви можете отримати статус розгорнутого поду за допомогою kubectl
.
kubectl get pods
Після розгортання подів ви побачите статус запущеного поду, як показано нижче.
Якщо ви хочете дізнатися подробиці про запущений pod, ви можете отримати всі необхідні відомості, використовуючи наступну команду яка виведе опис поду.
kubectl describe pod web-server-pod
У наступному виводі ви можете побачити всі деталі щодо Поду. Інформація про її IP-адресу, простір імен, деталі контейнера, QoS, тощо.
Тепер видалимо pod за допомогою наступної команди.
kubectl delete pod web-server-pod
Створення подів за допомогою декларативного YAML
Працюючи над реальними проєктами, вам доведеться створювати поди здебільшого за допомогою декларативного підходу.
Розглянемо, як створити под за допомогою маніфесту YAML.
Створіть файл з ім'ям nginx.yaml
з наступним вмістом
apiVersion: v1
kind: Pod
metadata:
name: web-server-pod
labels:
app: web-server
environment: production
annotations:
description: This pod runs the web server
spec:
containers:
- name: web-server
image: nginx:1.14.2
ports:
- containerPort: 80
Тепер, щоб розгорнути маніфест, вам потрібно виконати наступну команду kubectl
з ім'ям файлу.
kubectl create -f nginx.yaml
Чи потрібно запам'ятовувати кожен параметр для створення YAML? Ні. Ви можете використовувати прапорець --dry-run
для створення YAML-файлу.
Ось приклад.
kubectl run nginx-pod --image=nginx:1.14.2 --dry-run=client -o yaml
Ви можете зберегти вивід у форматі YAML, перенаправивши вивід dry-run
до файлу.
kubectl run nginx-pod --image=nginx:1.14.2 --dry-run=client -o yaml > nginx-pod.yaml
Доступ до запущеної в поді програми
Тепер у нас є робочий блок з веб-сервером Nginx. Вся ідея полягає в тому, щоб розгорнути та отримати доступ до програми, запущеної всередині цього блоку.
Kubectl пропонує команду переадресації портів для доступу до запущених подів у кластері Kubernetes з локальної робочої станції.
У нас є запущений блок з назвою web-server-pod
. Скористаємося командою port-forward
для доступу до нього.
kubectl port-forward pod/web-server-pod 8080:80
Ви повинні побачити результат, як показано нижче.
Тепер, якщо ви відкриєте браузер і перейдете за адресою http://localhost:8080, ви побачите домашню сторінку Nginx, як показано нижче. Веб-сторінка обслуговується нашим веб-сервером Nginx.
Тепер ви можете вимкнути перенаправлення портів за допомогою комбінації клавіш CTRL+C.
Ось що станеться, коли ви запустите kubectl port-forward
- Kubectl прив'язує вказаний порт у вашій локальній системі. У нашому випадку це
8080
. - Потім він зв'язується з API кластера Kubernetes, щоб встановити тунель (одне HTTP-з'єднання) до потрібного вузла,а потім до вказаного поду та порту контейнера, тобто 80.
Примітка: kubectl port forward
- це скоріше утиліта для налагодження. Вам потрібно використовувати об'єкт Kubernetes Service, щоб показати програму, запущену в поді.
Доступ до Pod Shell
Ми дізналися, як отримати доступ до програми, запущеної всередині под.
Тепер, що робити, якщо ви хочете отримати доступ до командного рядка поду?
Існує багато випадків використання, коли вам потрібен термінальний доступ до подів. Одним з основних випадків використання є налагодження та усунення несправностей.
Саме тут у пригоді стане команда kubectl exec
.
Ви можете отримати доступ до командної оболонки веб-сервера поду за допомогою наступної команди.
kubectl exec -it web-server-pod -- /bin/sh
У наступному виводі я виконую команду whoami
всередині пода.
Зауваження: Контейнерні образи зазвичай створюються з мінімальними можливостями, тому ви можете виявити, що не зможете виконати всі команди, які ви могли б виконати у звичайних системах Linux. Це обмеження залежить від способу створення образу та утиліт, які входять до складу образу контейнера
Життєвий цикл пода
Ще одна важлива концепція, яку ви повинні знати про под - це його життєвий цикл.
Зазвичай под керується контролером, наприклад, контролером ReplicaSet Controller
, контролером розгортання тощо. Коли ви створюєте окремий под за допомогою YAML, він не керується жодним контролером. В обох випадках, под проходить різні фази життєвого циклу.
Нижче наведено фази життєвого циклу подів.
- Pending: Це означає, що запит на створення подів успішно виконано, але планування ще триває. Наприклад, це процес завантаження зображення контейнера.
- Running: Контейнер успішно запущено і він працює як очікувалося. Наприклад, под обслуговує клієнтські запити.
-
Succeeded: Усі контейнери всередині поду були успішно завершені. Наприклад, успішне завершення об'єкта
CronJob
. - Failed: Усі контейнери завершено, але принаймні один з них завершився з помилкою. Наприклад, програма, що працює всередині пакета, не може запуститися через проблему з конфігурацією, і контейнер завершує роботу з ненульовим вихідним кодом.
- Unknown: Невідомий стан контейнера. Наприклад, кластер не може відслідковувати стан поду.
Якщо ви зробите запит на опис пода, ви зможете переглянути його стан. Ось приклад.
Можливості подів
Ми розгорнули простий блок Nginx з дуже мінімальними конфігураціями. Однак, він має багато можливостей для управління ресурсами, конфігурацією, доступністю, безпекою і т.д.
Якщо ви новачок, вивчення всіх цих концепцій за один раз буде надмірним. Має сенс вивчити всі ці концепції під час роботи з об'єктами, пов'язаними зі структурою, такими як розгортання з практичними прикладами використання.
Крім того, вам потрібно детально зрозуміти кожну функцію на практичному прикладі використання.
Нижче наведені ключові особливості, пов'язані з подами.
- Запити на ресурси та ліміти: Розподіл процесора/пам'яті для подів
- Мітки: пари ключ-значення, прикріплені до подів для категоризації ресурсів.
- Селектори: Групування ресурсів на основі міток.
- Індикатори життєздатності, готовності та запуску: Перевірка стану контейнера
- Карти конфігурацій: Для керування конфігураціями
- Секрети: Для управління секретами
- Томи: Постійне зберігання даних
- Початкові контейнери: Контейнери, які запускаються перед основними контейнерами.
- Ефемерні контейнери: Тимчасові контейнери, що додаються до поду для налагодження або усунення несправностей.
- Обліковий запис служби: Обмеження доступу до об'єктів та ресурсів Kubernetes.
- SecurityContext: Дозволи та привілеї хоста.
- Правила спорідненості та анти-спорідненості: Керування розміщенням подів на різних вузлах.
- Витіснення та пріоритети подів: Встановлення пріоритетів для планування та вилучення подів.
- Бюджет на випадок збою: Мінімальна кількість реплік контейнерів, які потрібно запустити під час добровільного переривання.
- Хуки життєвого циклу контейнера: Виконання кастомних скриптів на основі змін фаз життєвого циклу контейнера.
Розширена конфігурація Pod YAML
Примітка: Я навів наступний приклад лише для ознайомлення. Не перевантажуйте себе всіма параметрами. Це не так складно, як здається. Як тільки ви зрозумієте основи, це буде досить легко.
Якщо ви додасте перераховані мною вище функції, ви отримаєте повну конфігурацію YAML для подів, як показано нижче. Крім того, ці параметри будуть використовуватися разом з такими об'єктами, як Deployment
, Statefulset
і т.д.
apiVersion: v1
kind: Pod
metadata:
name: web-server-pod
spec:
initContainers:
- name: init-myservice
image: busybox:1.28
command: ['sh', '-c', 'echo "Init container started!"']
containers:
- name: web-server
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
- name: secret-volume
mountPath: /etc/my-secret
- name: configmap-volume
mountPath: /etc/config
securityContext:
capabilities:
add: ["NET_ADMIN", "SYS_TIME"]
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
readinessProbe:
httpGet:
path: /index.html
port: 80
initialDelaySeconds: 5
periodSeconds: 5
livenessProbe:
httpGet:
path: /index.html
port: 80
initialDelaySeconds: 15
periodSeconds: 20
startupProbe:
httpGet:
path: /index.html
port: 80
failureThreshold: 30
periodSeconds: 10
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo 'PostStart'"]
preStop:
exec:
command: ["/bin/sh", "-c", "echo 'PreStop'"]
serviceAccountName: nginx-service-account
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
shareProcessNamespace: true
volumes:
- name: shared-data
emptyDir: {}
- name: secret-volume
secret:
secretName: nginx-secret
- name: configmap-volume
configMap:
name: nginx-configmap
Об'єкти, пов'язані з подами (Pod Associated Objects)
Коли мова йде про запуск програм на Kubernetes, ми не запускаємо окремий блок. Тому що Kubernetes орієнтований на масштабування та підтримання доступності модулів.
Тож якщо ви запустите окремий блок, він стане єдиною точкою відмови. Тому що самі поди не можуть бути безпосередньо масштабовані.
Як ми обговорювали в архітектурі Kubernetes, нам потрібні контролери, такі як Replicaset, щоб забезпечити постійну роботу потрібної кількості подів.
У Kubernetes є різні типи об'єктів, асоційованих з подів для різних сценаріїв використання.
Нижче наведені важливі об'єкти, пов'язані з подами.
- Replicaset: Для підтримки стабільного набору реплік подів, що працюють у будь-який момент часу.
- Deployment: Для запуску програм без стану, таких як веб-сервери, API тощо.
- StatefulSets: Для запуску програм зі станом, таких як розподілені бази даних.
- Daemonsets: Запуск агентів на всіх вузлах Kubernetes.
- Jobs: Для пакетної обробки
- CronJobs: Завдання за розкладом
Висновок
У цьому посібнику ми розглянули всі основні концепції Kubernetes Pod. Як я вже згадував у вступі, у кожного з них є багато особливостей, коли мова йде про реалізацію Kubernetes на рівні продакшена.
Ще немає коментарів