Лабораторна робота №8. Об'єкти Kubernates

Мета: Ознайомитися з основними об'єктами Kubernetes

Теоретичні відомості

Об'єкти Kubernetes — це сутності, які зберігаються в Kubernetes і використовуються для представлення стану кластера. Вони описують наступну інформацію:

  • Які контейнеризовані застосунки запущені (і на яких вузлах).
  • Доступні ресурси для цих застосунків.
  • Стратегії управління застосунками, що стосуються, наприклад, перезапуску, оновлення чи забезпечення відмовостійкості.

Після створення об'єкта Kubernetes слідкує за тим, щоб цей об'єкт існував. Створюючи об'єкт, ви вказуєте системі Kubernetes, яким має бути бажаний стан робочого навантаження у кластері.

Для створення, зміни або видалення об'єктів Kubernetes використовується API Kubernetes. Наприклад, CLI-інструмент kubectl звертається до API Kubernetes. Також ви можете використовувати API Kubernetes у своїх програмах за допомогою однієї з клієнтських бібліотек.

У кожному об'єкті Kubernetes зазвичай є два вкладені поля-об’єкти, які управляють його конфігурацією:

  • spec - описує бажаний стан об'єкта, що задається під час його створення (характеристики, які повинен мати об'єкт);
  • status - описує поточний стан об'єкта. Це поле створюється та оновлюється самою системою Kubernetes.

Керуючий шар Kubernetes постійно стежить за фактичним станом кожного об'єкта і приводить його у відповідність до бажаного стану, зазначеного користувачем.

Опис об'єкта Kubernetes

Під час створення об'єкта Kubernetes потрібно надати специфікацію, яка визначає бажаний стан, а також базову інформацію про об'єкт (наприклад, ім'я). Якщо ви використовуєте API Kubernetes для створення об'єкта (безпосередньо або через kubectl), API-запит має включати всю цю інформацію у форматі JSON. Однак у більшості випадків для передачі даних в kubectl використовується файл у форматі YAML. kubectl перетворює його в JSON під час виконання запиту до API.

Обов'язкові поля

У .yaml-файлі об'єкта Kubernetes необхідно вказати такі поля:

  • apiVersion — версія API Kubernetes, яка використовується для створення об'єкта;
  • kind — тип об'єкта (наприклад, Pod, Deployment тощо);
  • metadata — метадані для ідентифікації об'єкта (ім'я, UID та необов’язкове поле namespace);
  • spec — бажаний стан об'єкта.

Формат поля spec залежить від типу об'єкта Kubernetes і може містити вкладені поля, унікальні для цього об'єкта. У довіднику API Kubernetes можна знайти формат специфікації для будь-якого об'єкта.

Основна структура Pod

apiVersion: v1        # Версія API для об'єкта Pod
kind: Pod             # Тип ресурсу (Pod)
metadata:             # Метаінформація про Pod
  name: my-pod        # Унікальне ім'я Pod у межах одного namespace
  namespace: default  # Простір імен (опціонально, за замовчуванням "default")
  labels:             # Набір міток для ідентифікації Pod
    app: my-app
    env: production
  annotations:        # Додаткові мета-дані (наприклад, для інтеграції зі сторонніми інструментами)
    description: "This is my Pod"
spec:                 # Специфікація Pod
  containers:         # Список контейнерів у Pod
    - name: my-container          # Унікальне ім'я контейнера в Pod
      image: nginx:latest         # Образ Docker для контейнера
      imagePullPolicy: Always     # Політика завантаження образу (Always, IfNotPresent, Never)
      ports:                      # Список відкритих портів контейнера
        - containerPort: 80       # Порт всередині контейнера
      env:                        # Список змінних середовища
        - name: ENV_VAR           # Назва змінної
          value: production       # Значення змінної
      resources:                  # Обмеження і запити на ресурси
        requests:
          memory: "64Mi"          # Мінімальний об'єм пам'яті
          cpu: "250m"             # Мінімальна кількість CPU
        limits:
          memory: "128Mi"         # Максимальний об'єм пам'яті
          cpu: "500m"             # Максимальна кількість CPU

Основна структура Deployment

apiVersion: apps/v1           # Версія API для Deployment
kind: Deployment              # Тип об'єкта (Deployment)
metadata:                     # Метаінформація про Deployment
  name: my-deployment         # Унікальне ім'я Deployment
  namespace: default          # Простір імен (за замовчуванням "default")
  labels:                     # Мітки для ідентифікації Deployment
    app: my-app
    environment: production
spec:                         # Специфікація Deployment
  replicas: 3                 # Кількість реплік (Pod)
  selector:                   # Вибір Pod для цього Deployment
    matchLabels:
      app: my-app             # Має збігатися з мітками у spec.template.metadata.labels
  template:                   # Шаблон для створення Pod
    metadata:                 # Метаінформація Pod
      labels:                 # Мітки для ідентифікації Pod
        app: my-app
    spec:                     # Специфікація Pod
      containers:             # Список контейнерів у Pod
      - name: my-container    # Ім'я контейнера
        image: nginx:latest   # Образ контейнера
        ports:                # Список портів, відкритих у контейнері
        - containerPort: 80   # Порт контейнера
        resources:            # Обмеження і запити на ресурси
          requests:
            memory: "64Mi"    # Мінімальний обсяг пам'яті
            cpu: "250m"       # Мінімальна кількість CPU
          limits:
            memory: "128Mi"   # Максимальний обсяг пам'яті
            cpu: "500m"       # Максимальна кількість CPU
        env:                  # Налаштування змінних середовища
        - name: ENV_VAR       # Назва змінної
          value: production   # Значення змінної

Основна структура файлу YAML для Service

apiVersion: v1                   # Версія API для Service
kind: Service                    # Тип об'єкта (Service)
metadata:                        # Метаінформація про Service
   name: my-service              # Унікальне ім'я Service
   namespace: default            # Простір імен (default, якщо не вказано)
   labels:                       # Мітки для ідентифікації Service
      app: my-app
spec:                            # Специфікація Service
   selector:                     # Вибір Pod для цього Service
      app: my-app                # Має збігатися з мітками у Pod
   ports:                        # Список портів, що відкриває Service
      - protocol: TCP            # Протокол (TCP/UDP)
        port: 80                 # Порт, доступний ззовні
        targetPort: 8080         # Порт, на який перенаправляється трафік
   type: ClusterIP               # Тип Service (ClusterIP, NodePort, LoadBalancer, ExternalName)
   sessionAffinity: None         # Афінність сесії (None або ClientIP)

Управління об'єктами Kubernetes

У командному інструменті kubectl є кілька способів створення та управління об'єктами Kubernetes.

Імперативні команди

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

Приклади

#Запустіть екземпляр контейнера nginx шляхом створення об'єкта Deployment:
kubectl run nginx --image nginx
#або
kubectl create deployment nginx --image nginx

Декларативна конфігурація об'єкта

Під час використання декларативної конфігурації об'єкта користувач працює з локальними конфігураційними файлами об'єкта, не визначаючи операцій, які потрібно виконати над цими файлами. Операції створення, оновлення та видалення автоматично визначаються kubectl для кожного об'єкта. Цей механізм дозволяє працювати з каталогами, у ситуаціях, коли для різних об'єктів можуть знадобитися різні операції.

Декларативна конфігурація об'єкта зберігає зміни, внесені іншими користувачами, навіть якщо ці зміни не будуть знову зафіксовані у конфігураційному файлі об'єкта. Це досягається шляхом використання API-операції patch, яка записує лише виявлені зміни, замість API-операції replace, що повністю замінює конфігурацію об'єкта.

Приклад

Обробити всі конфігураційні файли об'єктів у каталозі configs та створити або частково оновити активні об'єкти. Спочатку можна виконати diff, щоб побачити, які зміни будуть внесені, а потім застосувати їх:

kubectl diff -f configs/
kubectl apply -f configs/

#Рекурсивна обробка каталогів:

kubectl diff -R -f configs/
kubectl apply -R -f configs/

Завдання

  1. Ознайомитися з теоретичним матеріалом.
  2. Створити контейнери для додатків з лабораторної роботи №6 (Таблиця 1)

    Таблиця 1

    | Service Name | Image | Ports | Environment Variables | Description | |--------------|---------------------------------------|-------|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | frontend-build | node:20 | - | VITE_ARTICLES_URL, VITE_USERS_URL | сервіс, який виконую билд VueJS додатку допомогою команди npm run build:all та очикую пареметри середовища VITE_ARTICLES_URL та VITE_USERS_URL значення яких знаходиться в .env файлі. | | web | nginx:latest | 80, 443 | - | сервіс, який відкриває порт 80 та 443, обслуговую запити до VueJs додатку, виступаэ revers-proxy сервером для запитиів на /api/users та /api/articles, отримуэ конфігурації з файлу ./nginx/nginx.conf. | | python-app | custom dockerfile based on python:3.8 | 5000 | - | сервіс, який запускає Flask додаток, відповідає на запити /api/articles | | | php-app | webdevops/php-apache:7.4 | 8080 | WEB_DOCUMENT_ROOT=/app, DB_HOST, DB_NAME, DB_USER, DB_PASS | сервіс, який запускає PHP додаток, відповідає на запити /api/users, приймаэ параметри середовища для підключення до сервісу баз даних. | | mysql | mysql:latest | 3306 | MYSQL_ROOT_PASSWORD | сервіс, який запускає MySQL базу даних використовуючи скрипт ініціалізації бази даних. |

  3. Створити деплойменти та сервіси для кожного контейнера.

  4. Визначити всі необхідні змінні середовища для кожного деплойменту.
  5. Створити Ingress для доступу до сервісів.
  6. Перевірити роботу сервісів в браузері.
  7. Всі команди та результати виконання відобразити у звті.

Контрольні питання

  • Яка різниця між імперативним і декларативним підходами управління об’єктами Kubernetes?
  • Як працює декларативна конфігурація в Kubernetes і як зберігаються зміни?
  • Які основні обов'язкові поля потрібно вказати у файлі YAML для створення Deployment?
  • Що таке Ingress в Kubernetes і для чого він використовується?
  • Як налаштувати Ingress у Minikube для локального доступу до сервісів?
  • Як Ingress відрізняється від сервісу типу LoadBalancer?
  • Для чого використовується pathType в конфігурації Ingress?
  • Які ролі виконують поля spec та status в об'єктах Kubernetes?
  • Як працює NodePort сервіс і в яких випадках його доцільно використовувати?
  • Які переваги декларативного управління конфігураціями перед імперативним?

Література