Отже, Друід ми запустили – див. Apache Druid: огляд, запуск в Kubernetes та моніторинг з Prometheus. Поки що в дефолтному вигляді, тобто в ролі сторейджа для метаданих використовується локальна база Apache Derby.
Далі будемо переключати Друід на PostgreSQL, ще згодом – прибирати звідти ZooKeeper.
Ну а для початку – запустимо кластер PostgreSQL в Kubernetes, додамо PostgreSQL Exporter для Promethues, та налаштємо збір метрік.
Запускати знову будемо в Minikube, для PostgreSQL використаємо Zalando Operator, а Експортер будемо запускати у вигляді sidecar container.
Глибоко копати в Оператор поки що не будемо, хоча він дуже цікавий, тож якось з ним побавимося. Наразі, нам треба лише його моніторинг.
Документація – Administrator Guide.
Зміст
Запуск PostgreSQL оператора
Створюємо неймспейс:
[simterm]
$ kubectl create ns postgres-operator namespace/postgres-operator created
[/simterm]
Додаємо Хельм-репозіторій:
[simterm]
$ helm repo add postgres-operator-charts https://opensource.zalando.com/postgres-operator/charts/postgres-operator
[/simterm]
Встановлюємо сам оператор:
[simterm]
$ helm -n postgres-operator install postgres-operator postgres-operator-charts/postgres-operator
[/simterm]
За бажанням додаємо WebUI для оператора:
[simterm]
$ helm repo add postgres-operator-ui-charts https://opensource.zalando.com/postgres-operator/charts/postgres-operator-ui $ helm -n postgres-operator install postgres-operator-ui postgres-operator-ui-charts/postgres-operator-ui
[/simterm]
Перевіряємо поди:
[simterm]
$ kubectl -n postgres-operator get pods NAME READY STATUS RESTARTS AGE postgres-operator-649799f4bd-dz5bl 1/1 Running 0 82s postgres-operator-ui-5cfff55c65-v4bjj 1/1 Running 0 22s
[/simterm]
Вікриваємо собі доступ до Сервісу веб-морди Оператора:
[simterm]
$ kubectl port-forward svc/postgres-operator-ui 8081:80 Forwarding from 127.0.0.1:8081 -> 8081 Forwarding from [::1]:8081 -> 8081
[/simterm]
Перевіряємо:
Тут ми нічого робити не будемо – візьмемо готові приклади конфігу кластера.
Запуск PostgreSQL кластеру
Клонуємо репозіторій:
[simterm]
$ https://github.com/zalando/postgres-operator.git $ cd postgres-operator/
[/simterm]
В каталозі manifests
є декілька прикладів, візьмемо собі manifests/minimal-master-replica-svcmonitor.yaml
– він описує неймспейс, кластер-юзерів-бази, два Service та два ServiceMonitors + Sidecars с Prometheus Exporter.
Застосовуємо його:
[simterm]
$ kubectl apply -f manifests/minimal-master-replica-svcmonitor.yaml namespace/test-pg created postgresql.acid.zalan.do/acid-minimal-cluster created service/acid-minimal-cluster-svc-metrics-master created service/acid-minimal-cluster-svc-metrics-replica created servicemonitor.monitoring.coreos.com/acid-minimal-cluster-svcm-master created servicemonitor.monitoring.coreos.com/acid-minimal-cluster-svcm-replica created
[/simterm]
Перевіряєм кластер:
[simterm]
$ kk -n test-pg get postgresql NAME TEAM VERSION PODS VOLUME CPU-REQUEST MEMORY-REQUEST AGE STATUS acid-minimal-cluster acid 13 2 1Gi 2m21s Running
[/simterm]
Та його поди:
[simterm]
$ kk -n test-pg get po NAME READY STATUS RESTARTS AGE acid-minimal-cluster-0 2/2 Running 0 37s acid-minimal-cluster-1 1/2 Running 0 24s
[/simterm]
У кожного є своя роль, яка задається в лейблах – spilo-role=master
або spilo-role=replica
.
PostgreSQL users
Юзери описуються в блоці – сюрпрайз – users
:
[simterm]
$ kubectl -n test-pg get postgresql -o yaml ... users: foo_user: [] zalando: - superuser - createdb ...
[/simterm]
І для кожного з них створюється окремий Kubernetes Secret:
[simterm]
$ kk -n test-pg get secret NAME TYPE DATA AGE foo-user.acid-minimal-cluster.credentials.postgresql.acid.zalan.do Opaque 2 38m postgres.acid-minimal-cluster.credentials.postgresql.acid.zalan.do Opaque 2 38m standby.acid-minimal-cluster.credentials.postgresql.acid.zalan.do Opaque 2 38m zalando.acid-minimal-cluster.credentials.postgresql.acid.zalan.do Opaque 2 38m
[/simterm]
Які потім мапляться в поди через змінні:
[simterm]
$ kubectl -n test-pg get statefulsets acid-minimal-cluster -o yaml ... - env: - name: POD_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace - name: POSTGRES_USER value: postgres - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: key: password name: postgres.acid-minimal-cluster.credentials.postgresql.acid.zalan.do ...
[/simterm]
Ну і перевіримо.
Отримаємо пароль:
[simterm]
$ kubectl -n test-pg get secret postgres.acid-minimal-cluster.credentials.postgresql.acid.zalan.do -o 'jsonpath={.data.password}' | base64 -d CcWdAaqvPA8acxwIpVyM8UHkds2QG3opC3KD7rO1TxITQ1q31cwYLTswzfBeTVsN
[/simterm]
Відкриваємо порт:
[simterm]
$ kubectl -n test-pg port-forward acid-minimal-cluster-0 6432:5432
[/simterm]
Логінимося, та перевіряємо бази:
[simterm]
$ psql -U postgres -h localhost -p 6432 Password for user postgres: psql (14.5, server 13.7 (Ubuntu 13.7-1.pgdg18.04+1)) SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off) Type "help" for help. postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+-----------+----------+-------------+-------------+----------------------- bar | bar_owner | UTF8 | en_US.utf-8 | en_US.utf-8 | foo | zalando | UTF8 | en_US.utf-8 | en_US.utf-8 | postgres | postgres | UTF8 | en_US.utf-8 | en_US.utf-8 | template0 | postgres | UTF8 | en_US.utf-8 | en_US.utf-8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.utf-8 | en_US.utf-8 | =c/postgres + | | | | | postgres=CTc/postgres (5 rows) postgres=#
[/simterm]
PostgreSQL Prometheus Exporter
Див. Sidecar definitions.
Сайдкар ми вже маємо – доданий із маніфесту, і в кожному поді наразі маємо два контейнери – самого PostgreSQL, та його Експортера:
[simterm]
$ kk -n test-pg get po acid-minimal-cluster-0 -o jsonpath='{.spec.containers[*].name}' postgres exporter
[/simterm]
Глянемо чи є там метріки – відкриваємо порт:
[simterm]
$ kubectl -n test-pg port-forward svc/acid-minimal-cluster-svc-metrics-master 9187:9187 Forwarding from 127.0.0.1:9187 -> 9187 Forwarding from [::1]:9187 -> 9187
[/simterm]
І бачимо, що нічого не бачимо, а кластер взагалі “мертвий” – pg_up == 0
:
[simterm]
$ curl -s localhost:9187/metrics | grep pg_ | grep -v '#' pg_exporter_last_scrape_duration_seconds 1.00031302 pg_exporter_last_scrape_error 1 pg_exporter_scrapes_total 9 pg_up 0
[/simterm]
Чому – тому що експортер має мати дані доступу, тобто логін-пароль.
В конфізі сайдкару додаємо нові змінні, див. Environment Variables:
... env: - name: "DATA_SOURCE_URI" value: "$(POD_NAME)/postgres?sslmode=require" - name: "DATA_SOURCE_USER" value: "$(POSTGRES_USER)" - name: "DATA_SOURCE_PASS" value: "$(POSTGRES_PASSWORD)" - name: "PG_EXPORTER_AUTO_DISCOVER_DATABASES" value: "true" ...
Тобто, Оператор створює StatefulSet, в якому задає змінні POSTGRES_USER
та POSTGRES_PASSWORD
, які ми використовуємо для сайдкару, щоб задати його власні змінні.
Зберігаємо, оновлюємо:
[simterm]
$ kubectl apply -f manifests/minimal-master-replica-svcmonitor.yaml
[/simterm]
Перевіряємо змінні в самому поді:
[simterm]
$ kubectl -n test-pg get po acid-minimal-cluster-0 -o yaml ... - env: - name: POD_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace - name: POSTGRES_USER value: postgres - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: key: password name: postgres.acid-minimal-cluster.credentials.postgresql.acid.zalan.do - name: DATA_SOURCE_URI value: $(POD_NAME)/postgres?sslmode=require - name: DATA_SOURCE_USER value: $(POSTGRES_USER) - name: DATA_SOURCE_PASS value: $(POSTGRES_PASSWORD) - name: PG_EXPORTER_AUTO_DISCOVER_DATABASES value: "true" ...
[/simterm]
Та знову перевіряємо мектріки в експортері:
[simterm]
$ curl -s localhost:9187/metrics | grep pg_ | grep -v '#' | tail -5 pg_stat_replication_pg_current_wal_lsn_bytes{application_name="acid-minimal-cluster-0",client_addr="172.17.0.17",server="acid-minimal-cluster-1:5432",slot_name="182",state="streaming"} 1.52655344e+08 pg_stat_replication_pg_wal_lsn_diff{application_name="acid-minimal-cluster-0",client_addr="172.17.0.17",server="acid-minimal-cluster-1:5432",slot_name="182",state="streaming"} 0 pg_stat_replication_reply_time{application_name="acid-minimal-cluster-0",client_addr="172.17.0.17",server="acid-minimal-cluster-1:5432",slot_name="182",state="streaming"} 1.663625745e+09 pg_static{server="acid-minimal-cluster-1:5432",short_version="13.7.0",version="PostgreSQL 13.7 (Ubuntu 13.7-1.pgdg18.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0, 64-bit"} 1 pg_up 1
[/simterm]
pg_up == 1
– йай! Іт воркс!
Prometehus ServiceMonitors
Відкриваємо порт для доступу до самого Prometheus:
[simterm]
$ kubectl -n monitoring port-forward svc/kube-prometheus-stack-prometheus 9090:9090 Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090
[/simterm]
Перевіряємо Status > Service Discovery – PostgreSQL тут не бачимо:
СервісМонітори також були створені із маніфесту:
[simterm]
$ kubectl -n test-pg get servicemonitor NAME AGE acid-minimal-cluster-svcm-master 65m acid-minimal-cluster-svcm-replica 65m
[/simterm]
Повторюємо “грязний хак”, як робили для Друіда – додаємо в них label "release": "kube-prometheus-stack"
, чекаємо хвилину-дві, и перевіряємо ще раз:
Та маємо метріки в графіках:
Готово.