Развертывание PostgreSQL в локальном кластере Kubernetes

В этой статье автор не будет объяснять, зачем нужны все эти манипуляции, или обсуждать преимущества и недостатки данного решения. Он надеется, что читатели достаточно умны. 😎

Рассматривайте эту статью как продолжение истории о постоянных томах и как руководство по развертыванию базы данных в локальном кластере Kubernetes dev.

0. Введение

Можно выделить три основных этапа:

  • Создание PersistentVolume (PV) и PersistentVolumeClaim (PVC) — какая неожиданность, нам нужно stateful приложение.
  • Устанавливаем график Helm целевого приложения.
  • Проверяем, что все работает.

Перед началом работы нам необходимо минимально настроить кластер Kubernetes. Вот небольшие требования:

  • Актуальная версия Kubernetes (v1.22+).
  • Один главный узел и один рабочий узел.
  • Сконфигурированный Ingress-контроллер.

Как вы, возможно, уже знаете, автор предпочитает использовать k3s/k3d в качестве локальной стадии разработки Kubernetes.

1. Подготовка хранилища

При работе с k3s необходимо сначала включить так называемый local-path provisoner.

Установите провизор:

$ kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
Войдите в полноэкранный режим Выйдите из полноэкранного режима

Установите провизор local-path по умолчанию:

$ kubectl patch storageclass local-path -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
Войти в полноэкранный режим Выйти из полноэкранного режима

Проверьте, что провайдер запущен:

$ kubectl --namespace kube-system get pod 
NAME                                      READY   STATUS      RESTARTS        AGE
...
local-path-provisioner-84bb864455-tmpht   1/1     Running     ...
Войти в полноэкранный режим Выйти из полноэкранного режима

С этого момента мы можем создать ресурсы PersistentVolume и PersistentVolumeClaim для нашего выделенного пространства хранения. Для этого вставьте следующий манифест в файл pv.yaml:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-for-pg
  labels:
    type: local
spec:
  capacity:
    storage: 4Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: "local-path"
  hostPath:
    path: /opt/local-path-provisioner
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - k3d-my-cluster-agent-0

---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: pg-pvc
spec:
  storageClassName: "local-path"
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 4Gi
Войти в полноэкранный режим Выйти из полноэкранного режима

В поле matchExpressions указываем имя узла, на котором будет смонтирован диск (здесь это должен быть наш рабочий узел k3d-my-cluster-agent-0).

Для удобства мы смонтируем диск сразу на главном узле, хотя это можно сделать на любом из доступных в списке. K3s смонтирует том в каталог /opt/local-path-provisioner в файловой системе ведущего узла.

$ docker exec -it k3d-my-cluster-agent-0 sh
/ # ls
bin  dev  etc  k3d  lib  opt  proc  run  sbin  sys  tmp  usr  var
/ # cd opt
/opt # ls
local-path-provisioner
/opt # cd local-path-provisioner/
/opt/local-path-provisioner # ls
data
/opt/local-path-provisioner # cd data
/opt/local-path-provisioner/data # ls
PG_VERSION  global    pg_dynshmem    pg_logical    pg_notify    pg_serial     pg_stat      pg_subtrans  pg_twophase  pg_xact           postmaster.opts
base        pg_commit_ts  pg_ident.conf  pg_multixact  pg_replslot  pg_snapshots  pg_stat_tmp  pg_tblspc    pg_wal   postgresql.auto.conf  postmaster.pid
/opt/local-path-provisioner/data #
Вход в полноэкранный режим Выход из полноэкранного режима

Посмотрите результат:

$ kubectl apply -f pvc.yaml 
persistentvolume/pv-for-pg created
persistentvolumeclaim/pg-pvc created
Вход в полноэкранный режим Выход из полноэкранного режима

Хорошо. Проверим состояние продвинутого PersistentVolumeClaim:

$ kubectl get pvc
NAME     STATUS   VOLUME      CAPACITY   ACCESS MODES   STORAGECLASS    AGE
pg-pvc   Bound    pv-for-pg   4Gi        RWO            local-path     1m43s
Войти в полноэкранный режим Выйти из полноэкранного режима

Как мы видим, ресурс PersistentVolumeClaim связан.

2. Установка PostgreSQL

Пришло время развернуть Postgres на кластере. Как раз на этом этапе нам уже нужен helm. Тянем репозиторий Bitnami к себе (они добрые и замечательные, у них там в репозитории ⭐5k+ много полезных готовых схем):

$ helm repo add bitnami https://charts.bitnami.com/bitnami
"bitnami" has been added to your repositories
Входим в полноэкранный режим Выйдите из полноэкранного режима

Продолжаем установку helm install:

$ helm install dev-pg bitnami/postgresql --set primary.persistence.existingClaim=pg-pvc,auth.postgresPassword=pgpass,volumePermissions.enabled=true
NAME: dev-pg
LAST DEPLOYED: Tue May  3 19:25:34 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
Войти в полноэкранный режим Выход из полноэкранного режима

⚠️ Из-за продолжающейся проблемы с разрешениями kubernetes и использованием containerSecurityContext.runAsUser, вы должны включить volumePermissions, чтобы убедиться, что все работает как ожидалось.

🥁 Барабаны тикают! С этого момента Postgres Pod будет способен записывать данные в каталог /opt/local-path-provisioner.

Давайте посмотрим на состояние Pod и StatefulSet:

$ kubectl get pod,statefulset
NAME                                                    READY   STATUS    RESTARTS        AGE
pod/dev-pg-postgresql-0                                 1/1     Running   0               26m

NAME                                 READY   AGE
statefulset.apps/dev-pg-postgresql   1/1     1h
Вход в полноэкранный режим Выход из полноэкранного режима

Проверьте версию:

$ kubectl logs --tail 20  dev-pg-postgresql-0 | grep starting
...[1] LOG:  starting PostgreSQL 14.2 on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
Войти в полноэкранный режим Выйти из полноэкранного режима

Отличная работа.

3. Общение с базой данных

База данных успешно развернута, теперь давайте попробуем подключиться к ней: создадим пользователя, таблицу и настроим учетные данные доступа.

Существует два основных способа взаимодействия с базой данных:

  • Перенаправление портов
  • Привлечение Pod с клиентским инструментом onboard

Переадресация порта

Нам понадобится утилита psql (обратите внимание, в некоторых случаях необходимо добавить PgSQL PPA repo, автор использует Ubuntu Focal):

$ sudo apt install postgresql-client-14
Войдите в полноэкранный режим Выход из полноэкранного режима

Экспортируем пароль от пользователя admin в переменную окружения:

$ export POSTGRES_PASSWORD=$(kubectl get secret --namespace default dev-pg-postgresql -o jsonpath="{.data.postgres-password}" | base64 --decode)
Вход в полноэкранный режим Выйти из полноэкранного режима

Выполните проброс портов. Имейте в виду: после выполнения команды текущая консоль будет заблокирована:

$ kubectl port-forward --namespace default svc/dev-pg-postgresql 5432:5432
Войти в полноэкранный режим Выйти из полноэкранного режима

Или вы можете открыть отдельную консоль:

$ export KUBECONFIG=$(k3d kubeconfig write my-cluster)
kubectl port-forward --namespace default svc/dev-pg-postgresql 5432:5432
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь подключитесь к базе данных:

$ PGPASSWORD="$POSTGRES_PASSWORD" psql --host 127.0.0.1 -U postgres -d postgres -p 5432psql (14.2 (Ubuntu 14.2-1.pgdg20.04+1+b1))
Type "help" for help.

postgres=# 
Войдите в полноэкранный режим Выйти из полноэкранного режима

Привлечение Pod с клиентским инструментом onboard

Экспортируйте пароль от пользователя admin в переменную окружения:

$ export POSTGRES_PASSWORD=$(kubectl get secret --namespace default dev-pg-postgresql -o jsonpath="{.data.postgres-password}" | base64 --decode)
Войти в полноэкранный режим Выйти из полноэкранного режима

Затем создадим Pod с утилитой psql на борту и выполним в нем команду для подключения к базе данных:

$ kubectl run dev-pg-postgresql-client --rm --tty -i --restart='Never' --namespace default --image docker.io/bitnami/postgresql:14.2.0-debian-10-r22 --env="PGPASSWORD=$POSTGRES_PASSWORD" 
>  --command -- psql --host dev-pg-postgresql -U postgres -d postgres -p 5432

If you don't see a command prompt, try pressing enter.

postgres=# 
Войти в полноэкранный режим Выход из полноэкранного режима

Давайте перечислим роли, чтобы убедиться, что мы на связи:

postgres=# du;
                                   List of roles
 Role name |                         Attributes                         | Member of 
-----------+------------------------------------------------------------+-----------
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

postgres=# 
Войти в полноэкранный режим Выйти из полноэкранного режима

🎯 Вот и все, ребята! Мы развернули рабочую базу данных в кластере, она также сохраняет свое состояние, это stateful database.

Я рекомендую всем своим читателям регулярно просматривать блоги разработчиков в сети. Это того стоит. Спасибо Roger Lipscombe 🇬🇧 и Fadhil Yaacob 🇲🇾!

В следующей части автор рассмотрит удивительный инструмент, позволяющий наблюдать за функционированием контейнерной базы данных практически в реальном времени.

Оцените статью
Procodings.ru
Добавить комментарий