Kubernetes Pod - що це таке, пояснюємо на практичних прикладах

Kubernetes Pod - що це таке, пояснюємо на практичних прикладах
Переклад 19 хв. читання
30 серпня 2023

У цьому посібнику я детально описав концепцію Kubernetes pod, використовуючи практичні приклади та сценарії використання.

Мета цього посібника - допомогти вам зрозуміти будівельні блоки, з яких складається pod, і виконати практичну реалізацію розгортання pod і доступу до запущеної на ньому програми.

Крім того, існує багато понять, пов'язаних з об'єктом Pod. Тому я надав всю інформацію та концепції, пов'язані з под, щоб надалі спиратися на основи, які ви вже вивчили.

Зауваження: Перш ніж почати вивчати контейнери Kubernetes, переконайтеся, що ви добре розумієте концепцію контейнерів Linux.

Що таке Kubernetes Pod?

Перш ніж перейти до концепції Kubernetes Pod, давайте розберемося з контейнерами.

Контейнер, як ми всі знаємо, це автономне середовище, в якому ми пакуємо застосунки та їхні залежності. Зазвичай контейнер запускає один процес (хоча існують способи запуску декількох процесів). Кожен контейнер отримує IP-адресу і може приєднувати томи, керувати ресурсами процесора і пам'яті, та багато іншого. Все це відбувається за допомогою просторів імен та груп керування.

Kubernetes - це система оркестрування контейнерів для розгортання, масштабування та керування контейнерними програмами, яка має власний спосіб запуску контейнерів. Ми називаємо його "pod". Контейнер - це найменша одиниця розгортання у Kubernetes, яка являє собою один екземпляр програми.

Наприклад, якщо ви хочете запустити програму Nginx, ви запускаєте її в поді.

Чим же він відрізняється від контейнера?

Контейнер - це одна одиниця. Однак, в одному под може міститися більше одного контейнера. Ви можете уявити собі под як коробку, яка може містити один або декілька контейнерів разом.

Pod надає вищий рівень абстракції, який дозволяє вам керувати декількома контейнерами як єдиним цілим. У цьому випадку замість того, щоб кожен контейнер отримував окрему IP-адресу, блок отримує єдину унікальну IP-адресу, а контейнери, що працюють всередині блоку, використовують localhost для з'єднання один з одним через різні порти.

Kubernetes Pod - що це таке, пояснюємо на практичних прикладах

Це означає, що контейнери всередині 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 можна двома способами

  1. За допомогою імперативної команди kubectl: Переважно використовується для навчання та тестування. Імперативна команда має свої обмеження.
  2. Декларативний підхід: Використання маніфесту YAML. При роботі над проєктами для розгортання подів використовується маніфест YAML.

Тепер розглянемо обидва варіанти. Ми збираємося розгорнути nginx-под з наступними даними

  1. Ім'я поду - web-server-pod
  2. Він повинен мати мітки app: web-server і environment: production
  3. Додайте анотацію, щоб описати pod.
  4. Використовуйте образ контейнера nginx:1.14.2.
  5. Відкрийте для контейнера порт 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

Після розгортання подів ви побачите статус запущеного поду, як показано нижче.

Kubernetes Pod - що це таке, пояснюємо на практичних прикладах

Якщо ви хочете дізнатися подробиці про запущений pod, ви можете отримати всі необхідні відомості, використовуючи наступну команду яка виведе опис поду.

kubectl describe pod web-server-pod

У наступному виводі ви можете побачити всі деталі щодо Поду. Інформація про її IP-адресу, простір імен, деталі контейнера, QoS, тощо.

Kubernetes Pod - що це таке, пояснюємо на практичних прикладах

Тепер видалимо 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

Ви повинні побачити результат, як показано нижче.

Kubernetes Pod - що це таке, пояснюємо на практичних прикладах

Тепер, якщо ви відкриєте браузер і перейдете за адресою http://localhost:8080, ви побачите домашню сторінку Nginx, як показано нижче. Веб-сторінка обслуговується нашим веб-сервером Nginx.

Kubernetes Pod - що це таке, пояснюємо на практичних прикладах

Тепер ви можете вимкнути перенаправлення портів за допомогою комбінації клавіш 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 всередині пода.

Kubernetes Pod - що це таке, пояснюємо на практичних прикладах

Зауваження: Контейнерні образи зазвичай створюються з мінімальними можливостями, тому ви можете виявити, що не зможете виконати всі команди, які ви могли б виконати у звичайних системах Linux. Це обмеження залежить від способу створення образу та утиліт, які входять до складу образу контейнера

Життєвий цикл пода

Ще одна важлива концепція, яку ви повинні знати про под - це його життєвий цикл.

Зазвичай под керується контролером, наприклад, контролером ReplicaSet Controller, контролером розгортання тощо. Коли ви створюєте окремий под за допомогою YAML, він не керується жодним контролером. В обох випадках, под проходить різні фази життєвого циклу.

Нижче наведено фази життєвого циклу подів.

  1. Pending: Це означає, що запит на створення подів успішно виконано, але планування ще триває. Наприклад, це процес завантаження зображення контейнера.
  2. Running: Контейнер успішно запущено і він працює як очікувалося. Наприклад, под обслуговує клієнтські запити.
  3. Succeeded: Усі контейнери всередині поду були успішно завершені. Наприклад, успішне завершення об'єкта CronJob.
  4. Failed: Усі контейнери завершено, але принаймні один з них завершився з помилкою. Наприклад, програма, що працює всередині пакета, не може запуститися через проблему з конфігурацією, і контейнер завершує роботу з ненульовим вихідним кодом.
  5. Unknown: Невідомий стан контейнера. Наприклад, кластер не може відслідковувати стан поду.

Якщо ви зробите запит на опис пода, ви зможете переглянути його стан. Ось приклад.

Kubernetes Pod - що це таке, пояснюємо на практичних прикладах

Можливості подів

Ми розгорнули простий блок Nginx з дуже мінімальними конфігураціями. Однак, він має багато можливостей для управління ресурсами, конфігурацією, доступністю, безпекою і т.д.

Якщо ви новачок, вивчення всіх цих концепцій за один раз буде надмірним. Має сенс вивчити всі ці концепції під час роботи з об'єктами, пов'язаними зі структурою, такими як розгортання з практичними прикладами використання.

Крім того, вам потрібно детально зрозуміти кожну функцію на практичному прикладі використання.

Нижче наведені ключові особливості, пов'язані з подами.

  1. Запити на ресурси та ліміти: Розподіл процесора/пам'яті для подів
  2. Мітки: пари ключ-значення, прикріплені до подів для категоризації ресурсів.
  3. Селектори: Групування ресурсів на основі міток.
  4. Індикатори життєздатності, готовності та запуску: Перевірка стану контейнера
  5. Карти конфігурацій: Для керування конфігураціями
  6. Секрети: Для управління секретами
  7. Томи: Постійне зберігання даних
  8. Початкові контейнери: Контейнери, які запускаються перед основними контейнерами.
  9. Ефемерні контейнери: Тимчасові контейнери, що додаються до поду для налагодження або усунення несправностей.
  10. Обліковий запис служби: Обмеження доступу до об'єктів та ресурсів Kubernetes.
  11. SecurityContext: Дозволи та привілеї хоста.
  12. Правила спорідненості та анти-спорідненості: Керування розміщенням подів на різних вузлах.
  13. Витіснення та пріоритети подів: Встановлення пріоритетів для планування та вилучення подів.
  14. Бюджет на випадок збою: Мінімальна кількість реплік контейнерів, які потрібно запустити під час добровільного переривання.
  15. Хуки життєвого циклу контейнера: Виконання кастомних скриптів на основі змін фаз життєвого циклу контейнера.

Розширена конфігурація 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 є різні типи об'єктів, асоційованих з подів для різних сценаріїв використання.

Нижче наведені важливі об'єкти, пов'язані з подами.

  1. Replicaset: Для підтримки стабільного набору реплік подів, що працюють у будь-який момент часу.
  2. Deployment: Для запуску програм без стану, таких як веб-сервери, API тощо.
  3. StatefulSets: Для запуску програм зі станом, таких як розподілені бази даних.
  4. Daemonsets: Запуск агентів на всіх вузлах Kubernetes.
  5. Jobs: Для пакетної обробки
  6. CronJobs: Завдання за розкладом

Висновок

У цьому посібнику ми розглянули всі основні концепції Kubernetes Pod. Як я вже згадував у вступі, у кожного з них є багато особливостей, коли мова йде про реалізацію Kubernetes на рівні продакшена.

Джерело: Kubernetes Pod Explained With Practical Examples
Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація