Рецепт 2. Что CloudNativePG создаёт по умолчанию

Разбираем, какие ConfigMaps, Secrets и глобальные объекты PostgreSQL автоматически создаются вместе с кластером CloudNativePG: TLS-сертификаты, mTLS для replication, пользователь app и БД app.
Опубликовано:

Разбираем, что именно CloudNativePG создаёт «бесплатно» при поднятии кластера. Предполагается, что у вас уже есть cluster-example из Рецепта 1 и установлен плагин cnpg.

ConfigMaps по умолчанию

BASH
kubectl get configmaps
Нажмите, чтобы развернуть и увидеть больше
PLAINTEXT
NAME                      DATA   AGE
cnpg-default-monitoring   1      14h
Нажмите, чтобы развернуть и увидеть больше

cnpg-default-monitoring содержит встроенные метрики для встроенного Prometheus exporter. Содержимое:

BASH
kubectl get -o yaml configmaps cnpg-default-monitoring | less
Нажмите, чтобы развернуть и увидеть больше

CloudNativePG автоматически привязывает этот ConfigMap к кластеру. Проверить:

BASH
kubectl get cluster cluster-example \
  -o jsonpath="{.spec.monitoring}" | jq -C
Нажмите, чтобы развернуть и увидеть больше

Получите что-то вроде:

JSON
{
  "customQueriesConfigMap": [
    {
      "key": "queries",
      "name": "cnpg-default-monitoring"
    }
  ],
  "disableDefaultQueries": false,
  "enablePodMonitor": false
}
Нажмите, чтобы развернуть и увидеть больше

Secrets по умолчанию

BASH
kubectl get secrets
Нажмите, чтобы развернуть и увидеть больше
PLAINTEXT
NAME                          TYPE                       DATA   AGE
cluster-example-app           kubernetes.io/basic-auth   9      14h
cluster-example-ca            Opaque                     2      14h
cluster-example-replication   kubernetes.io/tls          2      14h
cluster-example-server        kubernetes.io/tls          2      14h
Нажмите, чтобы развернуть и увидеть больше

Что хранят:

Секрет пользователя app

Тип kubernetes.io/basic-auth. Внутри — username, password, pgpass-файл, connection string. Всё в base64 — стандарт для Secret-ресурсов.

BASH
kubectl describe secret cluster-example-app
Нажмите, чтобы развернуть и увидеть больше

Извлечь pgpass:

BASH
kubectl get secret cluster-example-app \
  -o jsonpath="{.data.pgpass}" | base64 -d
Нажмите, чтобы развернуть и увидеть больше

В тестовой среде покажет что-то вроде:

PLAINTEXT
cluster-example-rw:5432:app:app:<password>
Нажмите, чтобы развернуть и увидеть больше

Этот секрет можно монтировать как projected volume в контейнер приложения — пароль доступен через файл, а не через переменные окружения. Безопаснее.

Секреты для PKI и TLS

Один из принципов CloudNativePG — secure by default (shift-left на безопасность). По умолчанию оператор поднимает CA для кластера, выпускает с ней TLS-сертификаты для каждого Postgres-сервера и реализует mTLS для клиентских приложений.

Посмотреть CA:

BASH
kubectl get secret cluster-example-ca \
  -o jsonpath="{.data['ca\.crt']}" | \
  base64 -d | \
  openssl x509 -text -noout
Нажмите, чтобы развернуть и увидеть больше

Пример вывода:

PLAINTEXT
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            d2:a1:0f:48:4b:c4:33:38:72:f9:64:cf:d9:b0:56:e5
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: OU=default, CN=cluster-example
        Validity
            Not Before: Mar  7 17:09:44 2024 GMT
            Not After : Jun  5 17:09:44 2024 GMT
        Subject: OU=default, CN=cluster-example
        ...
        X509v3 extensions:
            X509v3 Key Usage: critical
                Certificate Sign
            X509v3 Basic Constraints: critical
                CA:TRUE
Нажмите, чтобы развернуть и увидеть больше

Этой CA подписан серверный сертификат PostgreSQL в cluster-example-server:

BASH
kubectl get secret cluster-example-server \
  -o jsonpath="{.data['tls\.crt']}" | \
  base64 -d | \
  openssl x509 -text -noout
Нажмите, чтобы развернуть и увидеть больше

Особое внимание — на Subject и X509v3 Subject Alternative Name. В SAN перечислены все DNS-имена сервисов кластера: cluster-example-rw, cluster-example-r, cluster-example-ro и их FQDN-варианты в namespace.

Кроме сертификатов, секреты содержат приватные ключи — оператор использует их для самоподписи клиентских сертификатов (например, для streaming replication).

TLS-сертификат для streaming replication

cluster-example-replication хранит сертификат пользователя streaming_replica:

BASH
kubectl get secret cluster-example-replication \
  -o jsonpath="{.data['tls\.crt']}" | \
  base64 -d | \
  openssl x509 -text -noout
Нажмите, чтобы развернуть и увидеть больше

В Subject: CN=streaming_replica — имя пользователя PostgreSQL. По умолчанию CloudNativePG ротирует эти сертификаты каждые 90 дней.

Проверить, что primary_conninfo на реплике уже настроен на mTLS без пароля:

BASH
kubectl exec -ti -c postgres cluster-example-2 \
  -- psql -qAt -c 'SHOW primary_conninfo'
Нажмите, чтобы развернуть и увидеть больше

Вывод:

PLAINTEXT
host=cluster-example-rw
user=streaming_replica
port=5432
sslkey=/controller/certificates/streaming_replica.key
sslcert=/controller/certificates/streaming_replica.crt
sslrootcert=/controller/certificates/server-ca.crt
application_name=cluster-example-2
sslmode=verify-ca
Нажмите, чтобы развернуть и увидеть больше

Если самоподписанных сертификатов недостаточно — можно подключить cert-manager.

Глобальные объекты в PostgreSQL по умолчанию

CloudNativePG создаёт:

Список ролей:

BASH
kubectl exec -ti -c postgres cluster-example-1 -- psql -c '\du'
Нажмите, чтобы развернуть и увидеть больше
PLAINTEXT
                                 List of roles
     Role name     |                         Attributes
-------------------+------------------------------------------------------------
 app               |
 postgres          | Superuser, Create role, Create DB, Replication, Bypass RLS
 streaming_replica | Replication
Нажмите, чтобы развернуть и увидеть больше

Список БД:

BASH
kubectl exec -ti -c postgres cluster-example-1 -- psql -c '\l'
Нажмите, чтобы развернуть и увидеть больше

Помимо стандартных postgres, template0, template1, появилась app, владелец — app.

Вывод

Подход «один кластер = одна БД» — это и есть микросервисная БД: вместо того, чтобы держать пять БД в одном кластере, держим пять отдельных кластеров. Имя БД и владельца становятся менее важны — главным «адресом» становится пара namespace:name самого кластера, она уникальна на весь Kubernetes.

Начать поиск

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

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