# Рекомендації щодо конфігурації Kubernetes

LLMS index: [llms.txt](/llms.txt)

---

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

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

_Цей блог створено на основі оригінальної сторінки "Кращі практики конфігурації", яка розвивалася завдяки участі багатьох членів спільноти Kubernetes._

## Загальні практики конфігурації {#general-configuration-practices}

### Використовуйте останню стабільну версію API {#use-the-latest-stable-api-version}

Kubernetes швидко розвивається. Старі API з часом стають застарілими і перестають працювати. Тому, коли ви визначаєте ресурси, переконайтеся, що ви використовуєте останню стабільну версію API.
Ви завжди можете перевірити це за допомогою

```bash
kubectl api-resources
```

Цей простий крок вбереже вас від майбутніх проблем із сумісністю.

### Зберігайте конфігурацію в системі контролю версій {#store-configuration-in-version-control}

Ніколи не застосовуйте маніфест-файли безпосередньо з робочого столу. Завжди зберігайте їх у системі контролю версій, такій як Git, це ваша страховка. Якщо щось зламається, ви зможете миттєво повернутися до попереднього коміту, порівняти зміни або відтворити налаштування кластера без паніки.

### Використовуйте YAML, а не JSON для створення конфігурацій {#write-configs-in-yaml-not-json}

Використовуйте YAML, а не JSON для створення файлів конфігурації. Технічно обидва формати працюють, але YAML простіший для сприйняття. Він чіткіший, менш захаращений і широко використовується в спільноті.

YAML має деякі підступні пастки з булевими значеннями: використовуйте тільки `true` або `false`. Не пишіть `yes`, `no`, `on` або  `off`. Вони можуть працювати в одній версії YAML, але не працювати в іншій. Щоб бути впевненим, беріть в лапки все, що виглядає як булеве значення (наприклад, `"yes"`).

### Зберігайте конфігурацію простою та мінімальною {#keep-configuration-simple-and-minimal}

Уникайте встановлення стандартних значень, які вже обробляються Kubernetes. Мінімальні маніфести легше налагоджувати, вони чіткіші для перегляду та менш схильні до поломок у майбутньому.

### Групуйте повʼязані обʼєкти разом {#group-related-objects-together}

Якщо ваші Deployment, Service та ConfigMap належать до одного застосунка, розмістіть їх в одному файлі маніфесту. Так легше відстежувати зміни та застосовувати їх як єдине ціле. Приклад цієї синтаксичної конструкції дивіться у файлі [Guestbook all-in-one.yaml](https://github.com/kubernetes/examples/blob/master/web/guestbook/all-in-one/guestbook-all-in-one.yaml).

Ви навіть можете застосувати цілі теки за допомогою:

```bash
kubectl apply -f configs/
```

Одна команда — і все, що знаходиться в цій теці, розгортається.

### Додайте корисні анотації {#add-helpful-annotations}

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

Найкориснішим коментарем є `kubernetes.io/description`. Він схожий на звичайний коментар, але копіюється в API, щоб усі могли його бачити навіть після розгортання.

## Управління робочими навантаженнями: Pods, Deployments та Jobs {#managing-workloads-pods-deployments-and-jobs}

Поширеною помилкою на початку роботи з Kubernetes є безпосереднє створення Podʼів. Podʼи працюють, але вони не переплановують себе, якщо щось йде не так.

_Naked Pods_ (Pods, які не управляються контролером, таким як [Deployment](/docs/concepts/workloads/controllers/deployment/) або [StatefulSet](/docs/concepts/workloads/controllers/statefulset/)) підходять для тестування, але в реальних умовах їх використання є ризикованим.

Чому? Тому що якщо вузол, на якому розміщений цей Pod, вийде з ладу, Pod також вийде з ладу, і Kubernetes не відновить його автоматично.

### Використовуйте Deployments для застосунків, які повинні завжди працювати {#use-deployments-for-apps-that-should-always-be-running}

Розгортання (Deployment), яке створює ReplicaSet для забезпечення постійної доступності необхідної кількості Podʼів і визначає стратегію заміни Podʼів (наприклад, [RollingUpdate](/docs/concepts/workloads/controllers/deployment/#rolling-update-deployment)), майже завжди є кращим варіантом, ніж безпосереднє створення Podʼів. Ви можете розгорнути нову версію, а якщо щось не спрацює, миттєво повернути попередню.

### Використовуйте Job для завдань, які повинні бути завершені {#use-jobs-for-tasks-that-should-finish}

Job (/docs/concepts/workloads/controllers/job/) ідеально підходить, коли вам потрібно виконати щось один раз, а потім зупинити, наприклад, міграцію бази даних або пакетну обробку завдань. Він повторить спробу, якщо podʼи зазнають збою, і повідомить про успішне виконання, коли все буде готово.

## Конфігурація Services та мережа {#service-configuration-and-networking}

Services — це спосіб, у який ваші робочі навантаження спілкуються між собою всередині (а іноді й поза межами) вашого кластера. Без них ваші podʼи існують, але не можуть ні з ким звʼязатися. Подбаємо про те, щоб цього не сталося.

### Створіть Services перед робочими навантаженнями, які їх використовують {#create-services-before-workloads-that-use-them}

Коли Kubernetes запускає Pod, він автоматично вводить змінні середовища для наявних Services. Отже, якщо Pod залежить від Service, створіть [Service](/docs/concepts/services-networking/service/) **перед** відповідними робочими навантаженнями бекенду (Deployments або StatefulSets) і перед будь-якими робочими навантаженнями, які потребують доступу до нього.

Наприклад, якщо існує Service з назвою foo, всі контейнери отримають у своєму початковому середовищі такі змінні:

```console
FOO_SERVICE_HOST=<хост, на якому працює Service>
FOO_SERVICE_PORT=<порт, на якому працює Service>
```

Виявлення на основі DNS не має цієї проблеми, але все одно варто дотримуватися цієї хорошої звички.

### Використання DNS для виявлення Service {#use-dns-for-service-discovery}

Якщо ваш кластер має [надбудову](/docs/concepts/cluster-administration/addons/) DNS (як і більшість), кожен Service автоматично отримує запис DNS. Це означає, що ви можете отримати до нього доступ за назвою, а не за IP-адресою:

```bash
curl http://my-service.default.svc.cluster.local
```

Це одна з тих функцій, які роблять мережу Kubernetes такою чарівною.

### Уникайте використання `hostPort` та `hostNetwork`, якщо це не є абсолютно необхідним {#avoid-hostport-and-hostnetwork-unless-absolutely-necessary}

Іноді ви можете побачити такі опції в маніфестах:

```yaml
hostPort: 8080
hostNetwork: true
```

Але ось у чому справа:
Вони привʼязують ваші Podʼи до конкретних вузлів, що ускладнює їх планування та масштабування. Оскільки кожна комбінація <`hostIP`, `hostPort`, `protocol`> повинна бути унікальною. Якщо ви не вкажете `hostIP` та `protocol` явно, Kubernetes буде використовувати `0.0.0.0` як типовий `hostIP` та `TCP` як типовий `protocol`. Якщо ви не займаєтеся відлагодженням або створенням чогось на зразок мережевого втулка, уникайте їх.

Якщо вам потрібен лише локальний доступ для тестування, спробуйте [`kubectl port-forward`](/docs/reference/kubectl/generated/kubectl_port-forward/):

```bash
kubectl port-forward deployment/web 8080:80
```

Докладнішу інформацію див. у розділі [Використання переадресації портів для доступу до застосунків у кластері](/docs/tasks/access-application-cluster/port-forward-access-application-cluster/). Або, якщо вам дійсно потрібен зовнішній доступ, використовуйте [`type: NodePort` Service](/docs/concepts/services-networking/service/#type-nodeport). Це безпечніший, природний для Kubernetes спосіб.

### Використовуйте headless Services для внутрішнього виявлення {#use-headless-services-for-internal-discovery}

Іноді ви не хочете, щоб Kubernetes балансував трафік. Ви хочете спілкуватися безпосередньо з кожним Podʼом. Саме тут на допомогу приходять [headless Services](/docs/concepts/services-networking/service/#headless-services).

Ви створюєте їх, встановивши `clusterIP: None`. Замість однієї IP-адреси DNS надає вам список усіх IP-адрес Podʼа, що ідеально підходить для застосунків, які самостійно керують зʼєднаннями.

## Ефективна робота з мітками {#working-with-labels-effectively}

[Мітки](/docs/concepts/overview/working-with-objects/labels/) — це пари ключ/значення, які прикріплюються до обʼєктів, таких як Podʼи. Мітки допомагають організовувати, шукати та групувати ресурси. Самі по собі вони нічого не роблять, але завдяки їм все інше, від Services до Deployments, працює злагоджено.

### Використовуйте семантичні мітки {#use-semantics-labels}

Хороші мітки допомагають зрозуміти, що до чого, навіть через кілька місяців. Визначте та використовуйте [мітки](/docs/concepts/overview/working-with-objects/labels/), які ідентифікують семантичні атрибути вашого застосунку або розгортання. Наприклад:

```yaml
labels:
  app.kubernetes.io/name: myapp
  app.kubernetes.io/component: web
  tier: frontend
  phase: test
```

- `app.kubernetes.io/name` : що це за застосунок
- `tier` : до якого шару він належить (frontend/backend)
- `phase` : на якому етапі він знаходиться (test/prod)

Потім ви можете використовувати ці мітки для створення потужних селекторів. Наприклад:

```bash
kubectl get pods -l tier=frontend
```

Це відобразить список усіх фронтенд-подів у вашому кластері, незалежно від того, з якого розгортання вони походять. По суті, ви не вказуєте імена подів вручну, а лише описуєте, що вам потрібно. Приклади такого підходу дивіться в застосунку [guestbook](https://github.com/kubernetes/examples/tree/master/web/guestbook/).

### Використовуйте загальні мітки Kubernetes {#use-common-kubernetes-labels}

Kubernetes фактично рекомендує набір [загальних міток](/docs/concepts/overview/working-with-objects/common-labels/). Це стандартизований спосіб називати обʼєкти у різних робочих навантаженнях або проєктах. Дотримання цієї домовленості робить ваші маніфести чіткішими, а це означає, що такі інструменти, як [Headlamp](https://headlamp.dev/), [dashboard](https://github.com/kubernetes/dashboard#introduction) або сторонні системи моніторингу, можуть автоматично розуміти, що саме працює.

### Маніпулювання мітками для відлагодження {#manipulate-labels-for-debugging}

Оскільки контролери (такі як ReplicaSets або Deployments) використовують мітки для управління Podʼами, ви можете видалити мітку, щоб тимчасово «відʼєднати» Pod.

Приклад:

```bash
kubectl label pod mypod app-
```

Частина `app-` видаляє ключ мітки `app`. Після цього контролер більше не буде керувати цим Podʼом. Це схоже на ізоляцію для перевірки, «режим карантину» для налагодження. Щоб інтерактивно видаляти або додавати мітки, використовуйте [`kubectl label`](/docs/reference/kubectl/generated/kubectl_label/).

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

## Корисні поради щодо kubectl {#handy-kubectl-tips}

Ці невеликі поради значно полегшують роботу з декількома файлами маніфесту або кластерами.

### Застосування цілих текстових файлів {#apply-entire-directories}

Замість того, щоб застосовувати файл за файлом, застосуйте цілу теку:

```bash
# Використання серверного застосування також є гарною практикою.
kubectl apply -f configs/ --server-side
```

Ця команда шукає файли `.yaml`, `.yml` та `.json` у цій теці та застосовує їх усі разом. Це швидше, чистіше та допомагає групувати елементи за застосунками.

### Використовуйте селектори міток для отримання або видалення ресурсів {#use-label-selectors-to-get-or-delete-resources}

Не завжди потрібно вводити імена ресурсів по одному. Замість цього використовуйте [селектори](/docs/concepts/overview/working-with-objects/labels/#label-selectors), щоб одночасно працювати з цілими групами:

```bash
kubectl get pods -l app=myapp
kubectl delete pod -l phase=test
```

Це особливо корисно в конвеєрах CI/CD, де потрібно динамічно очищати тестові ресурси.

### Швидке створення Deployments і Services {#quickly-create-deployments-and-services}

Для швидких експериментів не завжди потрібно писати маніфест. Ви можете запустити Deployment прямо з CLI:

```bash
kubectl create deployment webapp --image=nginx
```

Потім експонуйте його як Service:

```bash
kubectl expose deployment webapp --port=80
```

Це чудово підходить, коли ви просто хочете щось протестувати перед написанням повних маніфестів. Також дивіться приклад у статті [Використання Service для доступу до застосунку в кластері](/docs/tasks/access-application-cluster/service-access-application-cluster/).

## Підсумок {#conclusion}

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

А що найкраще? Чисті конфігурації залишаються читабельними. Навіть через кілька місяців ви або будь-хто з вашої команди зможете поглянути на них і точно зрозуміти, що відбувається.
