Рецепт 10. Симуляция продакшн-среды PostgreSQL в Kubernetes с помощью Kind

Как создать многонодовый Kubernetes-кластер в Kind с выделенными узлами для PostgreSQL, используя node labels и nodeSelector для изоляции рабочих нагрузок.
Опубликовано:

Как использовать Kind для создания многонодового Kubernetes-кластера на локальной машине, имитирующего продакшн-среду, — с выделением узлов под PostgreSQL, приложения и инфраструктуру.


Kind (Kubernetes IN Docker) позволяет запускать полноценный Kubernetes-кластер, используя Docker-контейнеры в качестве узлов. Это портативная и воспроизводимая среда для тестирования приложений и интеграции в GitOps-пайплайны.

В Рецепте 1 рассматривались основы начала работы. Здесь — следующий шаг: многонодовый кластер с разделением ролей узлов.

Прежде чем начать

Убедитесь, что установлены:

Многонодовый кластер

По умолчанию Kind создаёт одноузловой кластер — этого достаточно для многих сценариев, но не для работы с node selectors, taints & tolerations, affinity и anti-affinity. Для этого нужен многонодовый кластер.

Kind позволяет настроить кластер через конфигурационный файл. Создадим кластер со следующей топологией:

Соглашение по именам меток: ROLE.node.kubernetes.io, где ROLEinfra, app или postgres. Причины такого выбора описаны ниже.

Конфигурация Kind:

YAML
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: multi-node-template
nodes:
- role: control-plane
- role: worker
  labels:
    infra.node.kubernetes.io:
- role: worker
  labels:
    app.node.kubernetes.io:
- role: worker
  labels:
    postgres.node.kubernetes.io:
- role: worker
  labels:
    postgres.node.kubernetes.io:
- role: worker
  labels:
    postgres.node.kubernetes.io:
Нажмите, чтобы развернуть и увидеть больше

Создание кластера:

SH
kind create cluster --config multi-node-template.yaml --name cnpg
Нажмите, чтобы развернуть и увидеть больше

Проверяем узлы:

SH
kubectl get nodes
Нажмите, чтобы развернуть и увидеть больше
PLAINTEXT
NAME                 STATUS   ROLES           AGE     VERSION
cnpg-control-plane   Ready    control-plane   5m4s    v1.35.0
cnpg-worker          Ready    <none>          4m44s   v1.35.0
cnpg-worker2         Ready    <none>          4m44s   v1.35.0
cnpg-worker3         Ready    <none>          4m45s   v1.35.0
cnpg-worker4         Ready    <none>          4m44s   v1.35.0
cnpg-worker5         Ready    <none>          4m45s   v1.35.0
Нажмите, чтобы развернуть и увидеть больше

Роль отображается только у cnpg-control-plane. У остальных — <none>. Почему?

Стандартные метки ролей узлов в Kubernetes

Kubernetes использует метку node-role.kubernetes.io/control-plane для идентификации узлов control plane. Команда kubectl get nodes извлекает роль из строки после node-role.kubernetes.io/.

Чтобы отображались роли worker-узлов, нужно вручную назначить метки:

По умолчанию kubelet запрещает назначение меток в пространстве kubernetes.io, если у них нет префикса kubelet или node (мера безопасности). Обходной путь — назначить метки после создания через kubectl label node:

SH
kubectl label node -l postgres.node.kubernetes.io node-role.kubernetes.io/postgres=
kubectl label node -l infra.node.kubernetes.io node-role.kubernetes.io/infra=
kubectl label node -l app.node.kubernetes.io node-role.kubernetes.io/app=
Нажмите, чтобы развернуть и увидеть больше

Теперь kubectl get nodes покажет:

PLAINTEXT
NAME                 STATUS   ROLES           AGE   VERSION
cnpg-control-plane   Ready    control-plane   19m   v1.35.0
cnpg-worker          Ready    infra           19m   v1.35.0
cnpg-worker2         Ready    app             19m   v1.35.0
cnpg-worker3         Ready    postgres        19m   v1.35.0
cnpg-worker4         Ready    postgres        19m   v1.35.0
cnpg-worker5         Ready    postgres        19m   v1.35.0
Нажмите, чтобы развернуть и увидеть больше

Шесть узлов с понятным распределением ролей: control plane, приложения, инфраструктура и Postgres.

Дополнительно

Выбранная конвенция ROLE.node.kubernetes.io удобна тем, что позволяет назначать метки через селекторы. Можно также маркировать узлы по одному:

SH
kubectl label node cnpg-worker5 node-role.kubernetes.io/postgres=
Нажмите, чтобы развернуть и увидеть больше

Планирование CNPG-кластеров на узлах postgres

Задача: декларативно создать PostgreSQL-кластер через CloudNativePG и обеспечить его запуск только на узлах с ролью postgres.

Это решается через node selectors . В CloudNativePG — поле .spec.affinity.nodeSelector:

YAML
  affinity:
    nodeSelector:
      node-role.kubernetes.io/postgres: ""
Нажмите, чтобы развернуть и увидеть больше

Запуск

Установите оператор CloudNativePG (рекомендуется последняя стабильная версия):

SH
curl -sSfL \
  https://raw.githubusercontent.com/cloudnative-pg/artifacts/main/manifests/operator-manifest.yaml | \
  kubectl apply --server-side -f -
Нажмите, чтобы развернуть и увидеть больше

Дождитесь готовности оператора:

SH
kubectl get pods -A -o wide
Нажмите, чтобы развернуть и увидеть больше

Создайте PostgreSQL-кластер:

YAML
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: cluster-example
spec:
  instances: 3

  storage:
    size: 1Gi

  affinity:
    nodeSelector:
      node-role.kubernetes.io/postgres: ""
Нажмите, чтобы развернуть и увидеть больше

Примените манифест:

SH
kubectl apply -f cluster-example.yaml
Нажмите, чтобы развернуть и увидеть больше

Проверка:

SH
kubectl get pods -o wide
Нажмите, чтобы развернуть и увидеть больше
PLAINTEXT
NAME                READY   STATUS    RESTARTS   AGE   IP           NODE           NOMINATED NODE   READINESS GATES
cluster-example-1   1/1     Running   0          96s   10.244.4.4   cnpg-worker4   <none>           <none>
cluster-example-2   1/1     Running   0          54s   10.244.1.4   cnpg-worker3   <none>           <none>
cluster-example-3   1/1     Running   0          13s   10.244.2.5   cnpg-worker5   <none>           <none>
Нажмите, чтобы развернуть и увидеть больше

Все три инстанса PostgreSQL запущены исключительно на узлах с ролью postgres.

Заключение

Kind — мощный инструмент, позволяющий моделировать реальные сценарии прямо на ноутбуке. В связке с Kubernetes, CloudNativePG и PostgreSQL (всё — open-source) можно проектировать, тестировать и автоматизировать инфраструктуру от разработки до продакшна, в том числе через GitOps-пайплайны.

Благодаря портативности Kubernetes эти рекомендации применимы к любому облачному окружению — частному, публичному, самоуправляемому или полностью управляемому.

Node labels — ключевой механизм контроля «физического» размещения PostgreSQL-нагрузок через декларативную конфигурацию. Можно выделять конкретные машины под один PostgreSQL-кластер или использовать bare-metal узлы с локальными дисками.

Однако одних меток недостаточно для полной изоляции. В примере выше оператор (cnpg-controller-manager) мог запуститься на одном из postgres-узлов. Если на этом узле возникнет проблема, это может замедлить failover. Решение — taints и tolerations — рассматривается в следующем рецепте.

Начать поиск

Введите ключевые слова для поиска статей

↑↓
ESC
⌘K Горячая клавиша