From e6050a14c43e6a0b7e492d41cd93a722e13105cb Mon Sep 17 00:00:00 2001 From: migatu Date: Fri, 7 Aug 2026 15:16:44 +0200 Subject: [PATCH] feat(astrololo): Postgres jako lustro baz w SQL + runbook (DAN-28) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Manifest, wpięcie w kustomization i runbook krok po kroku. DECYZJE ZAPISANE W MANIFEŚCIE, ŻEBY NIE TRZEBA ICH BYŁO ODTWARZAĆ Z GŁOWY: local-path, NIE NFS. Postgres zakłada semantykę blokad i fsync, której NFS nie gwarantuje — to klasyczne źródło uszkodzenia bazy przy nagłym restarcie. Ceną jest przywiązanie do węzła; przy luście odtwarzalnym z Excela to akceptowalne. strategy: Recreate. Wolumen jest ReadWriteOnce, a dwa procesy Postgresa na jednym katalogu danych to uszkodzona baza — rolling próbowałby wstać z nowym podem, zanim stary zejdzie. PGDATA w PODKATALOGU wolumenu: katalog główny potrafi zawierać wpisy systemu plików, a initdb odmawia pracy w niepustym katalogu. Wersja PRZYPIĘTA i poza image-updaterem: podbicie majora wymaga migracji katalogu danych, więc nie może się zdarzyć samo, w nocy, przy okazji builda aplikacji. C.UTF-8 zamiast pl_PL.UTF-8: dopasowanie tekstu robimy przez unaccent i pg_trgm, nie przez collation, a pl_PL wymagałby obrazu z wygenerowanymi lokalizacjami. DATA_PROVIDER zostaje na `excel`. Postgres można wdrożyć i obejrzeć BEZ ryzyka dla działającego wyszukiwania; przełączenie to osobna, późniejsza decyzja. SPRAWDZONE PRZED ODDANIEM: `kubectl kustomize astrololo` składa komplet 21 zasobów bez błędu, YAML parsuje się poprawnie, audyt odwołań potwierdza, że jedynym brakującym sekretem jest astrololo-postgres (oba klucze), a DSN postgresql+psycopg:// jest rozpoznawany przez SQLAlchemy z psycopg 3. NIE SPRAWDZONE: skrypt inicjalizujący nie biegł przeciwko prawdziwemu Postgresowi — na maszynie, na której to powstawało, nie ma Dockera. Zapisane wprost w runbooku; krok 4 jest tam prawdziwym testem. Co-Authored-By: Claude Opus 5 --- astrololo/README-postgres.md | 284 +++++++++++++++++++++++++++++++++++ astrololo/README.md | 9 ++ astrololo/data.yaml | 10 ++ astrololo/kustomization.yaml | 1 + astrololo/postgres.yaml | 150 ++++++++++++++++++ 5 files changed, 454 insertions(+) create mode 100644 astrololo/README-postgres.md create mode 100644 astrololo/postgres.yaml diff --git a/astrololo/README-postgres.md b/astrololo/README-postgres.md new file mode 100644 index 0000000..2259457 --- /dev/null +++ b/astrololo/README-postgres.md @@ -0,0 +1,284 @@ +# Postgres — lustro baz w SQL (DAN-28) + +Runbook krok po kroku. Zakłada, że nie pamiętasz nic z rozmowy, w której to +powstało. + +--- + +## Co to jest — i czego to NIE jest + +Postgres trzyma **lustro** plików Excela, żeby wyszukiwanie było szybsze i mądrzejsze. + +> **ŹRÓDŁEM PRAWDY SĄ PLIKI EXCELA NA NFS.** Utrata tej bazy **nie jest utratą +> danych** — odbudowuje się z plików. Dlatego kopie zapasowe Postgresa są tu +> **opcjonalne**, a wolumen stoi na `local-path` zamiast na NFS. + +Po co w ogóle Postgres, skoro danych jest mało (~54 tys. wierszy)? Nie dla skali — +przy takim rozmiarze SQLite bywa szybszy. Dla **wyszukiwania w polskim, +nieznormalizowanym tekście**: `pg_trgm` (dopasowanie mimo literówek) i `unaccent` +(ogonki) nie mają w SQLite taniego zamiennika. + +--- + +## Część 1 — co zrobiłem za Ciebie (w repo) + +Nic z tego nie wymaga Twojej ręki, ale wiedz, co jest gdzie: + +| plik | co w nim jest | +|---|---| +| `astrololo/postgres.yaml` | PVC (5 Gi, `local-path`), ConfigMap z SQL-em inicjalizującym, Deployment (`Recreate`), Service `ClusterIP` | +| `astrololo/kustomization.yaml` | `postgres.yaml` dopisany **przed** `data.yaml` | +| `astrololo/data.yaml` | `SQL_URL` z sekretu; `DATA_PROVIDER` **zostaje `excel`** | +| repo aplikacji: `services/data/requirements.txt` | sterownik `psycopg[binary]` | + +Decyzje, które w tych plikach zapadły — żeby nie trzeba było ich odtwarzać z głowy: + +* **`local-path`, nie NFS.** Postgres zakłada semantykę blokad i `fsync`, której NFS + nie gwarantuje — to klasyczne źródło uszkodzenia bazy przy nagłym restarcie. + Ceną jest przywiązanie do węzła; przy luście odtwarzalnym z Excela to nie boli. +* **`strategy: Recreate`.** Wolumen jest `ReadWriteOnce`, a dwa procesy Postgresa + na jednym katalogu danych to uszkodzona baza. Rolling próbowałby wstać z nowym + podem, zanim stary zejdzie. +* **`PGDATA` w podkatalogu** (`…/data/pgdata`). Katalog główny wolumenu potrafi + zawierać wpisy systemu plików, a `initdb` odmawia pracy w niepustym katalogu. +* **Wersja przypięta (`postgres:17`) i POZA image-updaterem.** Podbicie majora + wymaga migracji katalogu danych — nie może się zdarzyć samo, w nocy, przy okazji + builda aplikacji. +* **`DATA_PROVIDER` zostaje na `excel`.** Postgres można wdrożyć i obejrzeć **bez + żadnego ryzyka** dla działającego wyszukiwania. Przełączenie na `sql` to osobna, + późniejsza decyzja — po wdrożeniu lustra. + +--- + +## Część 2 — co musisz zrobić Ty + +### Krok 0. Sprawdź, że klaster ma `local-path` + +```bash +kubectl get storageclass +``` + +Oczekiwany wynik: linia z `local-path` i dopiskiem `(default)`. W k3s jest +domyślnie. **Jeśli jej nie ma — zatrzymaj się tutaj** i daj znać; bez niej PVC +zawiśnie w `Pending`. + +### Krok 1. Utwórz sekret `astrololo-postgres` + +Ta sama konwencja co `astrololo-auth`: **sekretu nie ma w repo**, bo to repo +GitOps i cokolwiek by tu wpadło, zostałoby w historii gita na zawsze. + +```bash +PGPASS="$(openssl rand -base64 24 | tr -d '/+=' | head -c 32)" + +kubectl -n astrololo create secret generic astrololo-postgres \ + --from-literal=POSTGRES_PASSWORD="$PGPASS" \ + --from-literal=SQL_URL="postgresql+psycopg://astrololo:${PGPASS}@postgres:5432/astrololo" + +unset PGPASS +``` + +Hasła **nie musisz nigdzie zapisywać ani nigdy oglądać** — używają go tylko usługi +między sobą. Gdybyś kiedyś go potrzebował: + +```bash +kubectl -n astrololo get secret astrololo-postgres \ + -o jsonpath='{.data.POSTGRES_PASSWORD}' | base64 -d; echo +``` + +> **Dlaczego dwa klucze, skoro hasło jest w obu?** `POSTGRES_PASSWORD` czyta sam +> Postgres przy inicjalizacji, `SQL_URL` czyta warstwa danych. Rozdzielone, bo to +> dwa różne formaty i dwóch różnych odbiorców — sklejanie DSN-a w manifeście +> wymagałoby wstawienia tam hasła. + +### Krok 2. Wdróż + +Jeśli ArgoCD pilnuje katalogu `astrololo`, wystarczy **zmergować PR** — reszta +zrobi się sama. Ręcznie: + +```bash +kubectl apply -k astrololo +``` + +### Krok 3. Sprawdź, że wstało + +```bash +kubectl -n astrololo rollout status deploy/postgres +kubectl -n astrololo get pvc postgres-data +``` + +Oczekiwane: `deployment "postgres" successfully rolled out` i PVC w stanie `Bound`. + +### Krok 4. Sprawdź, że rozszerzenia się założyły + +To jest **najważniejszy sprawdzian tego wdrożenia** — bez tych rozszerzeń cały +sens stawiania Postgresa znika. + +```bash +kubectl -n astrololo exec deploy/postgres -- \ + psql -U astrololo -d astrololo -c "\dx" +``` + +Na liście muszą być **`pg_trgm`** i **`unaccent`**. Sprawdź też, że działają: + +```bash +kubectl -n astrololo exec deploy/postgres -- psql -U astrololo -d astrololo -c \ + "SELECT unaccent('różdżka') AS bez_ogonkow, + similarity(unaccent('różdżka'), 'rozdzka') AS po_zdjeciu_ogonkow, + similarity('kowalski', 'kowlaski') > 0.3 AS literowka_lapana;" +``` + +Oczekiwane **dokładnie**: + +``` + bez_ogonkow | po_zdjeciu_ogonkow | literowka_lapana +-------------+--------------------+------------------ + rozdzka | 1 | t +``` + +Pierwsza kolumna pokazuje, że `unaccent` zna polskie znaki; druga, że po zdjęciu +ogonków słowa są **identyczne** (stąd równo `1`); trzecia, że `pg_trgm` łapie +przestawione litery. Jeśli druga kolumna nie jest równa `1`, rozszerzenia są, ale +reguły `unaccent` nie obsługują polskich znaków — daj znać, bo to zmienia sposób +budowania indeksów. + +### Krok 5. Sprawdź, że warstwa danych ma połączenie + +```bash +kubectl -n astrololo rollout restart deploy/data +kubectl -n astrololo rollout status deploy/data +kubectl -n astrololo logs deploy/data --tail=30 | grep -i -E "sql|postgres|error" || echo "brak wzmianek — OK" +``` + +Na tym etapie warstwa danych **nadal czyta Excela** (`DATA_PROVIDER=excel`). +Postgres tylko stoi i czeka. Aplikacja ma działać dokładnie jak przedtem — +i to jest oczekiwany wynik tego wdrożenia. + +--- + +## Część 3 — obsługa na co dzień + +### Zajrzeć do bazy + +```bash +kubectl -n astrololo exec -it deploy/postgres -- psql -U astrololo -d astrololo +``` + +Przydatne w środku: `\dt mirror.*` (tabele lustra), `\dx` (rozszerzenia), +`\l` (bazy), `\q` (wyjście). + +### Podłączyć narzędzie graficzne z laptopa + +Baza **celowo nie jest wystawiona poza klaster**. Na czas jednej sesji: + +```bash +kubectl -n astrololo port-forward deploy/postgres 5432:5432 +``` + +i łączysz się na `localhost:5432`, użytkownik `astrololo`, baza `astrololo`, +hasło jak w kroku 1. Po zamknięciu terminala tunel znika. + +### Dodanie rozszerzenia do ISTNIEJĄCEJ bazy + +> ⚠️ **Pułapka.** Skrypty z `/docker-entrypoint-initdb.d/` uruchamiają się +> **wyłącznie przy pierwszej inicjalizacji**, na pustym katalogu danych. Dopisanie +> rozszerzenia do ConfigMapy **nie zrobi nic**, jeśli baza już istnieje. + +```bash +kubectl -n astrololo exec deploy/postgres -- \ + psql -U astrololo -d astrololo -c "CREATE EXTENSION IF NOT EXISTS nazwa;" +``` + +### Kopia zapasowa (opcjonalna — patrz nagłówek) + +```bash +kubectl -n astrololo exec deploy/postgres -- \ + pg_dump -U astrololo -d astrololo -Fc > astrololo-$(date +%F).dump +``` + +Odtworzenie: + +```bash +kubectl -n astrololo exec -i deploy/postgres -- \ + pg_restore -U astrololo -d astrololo --clean --if-exists < astrololo-2026-08-06.dump +``` + +### Wyczyścić lustro i wczytać od nowa + +```bash +kubectl -n astrololo exec deploy/postgres -- psql -U astrololo -d astrololo -c \ + "DROP SCHEMA mirror CASCADE; CREATE SCHEMA mirror;" +``` + +Po tym warstwa danych odbuduje lustro z plików Excela (gdy lustro będzie już +zaimplementowane — dziś ta komenda tylko czyści pusty schemat). + +### Podbicie wersji Postgresa + +**Nie robi się tego przez zmianę tagu w manifeście.** Major wymaga migracji +katalogu danych. Ponieważ to lustro: + +1. `kubectl -n astrololo scale deploy/data --replicas=0` +2. skasuj Deployment i **PVC** (`kubectl -n astrololo delete deploy/postgres pvc/postgres-data`) +3. zmień tag obrazu w `postgres.yaml`, wdróż ponownie +4. `kubectl -n astrololo scale deploy/data --replicas=1` — lustro odbuduje się z Excela + +To jest właśnie ta sytuacja, w której „lustro, nie źródło prawdy" oszczędza dzień +pracy. + +--- + +## Co zostało sprawdzone przed oddaniem, a co nie + +**Sprawdzone:** `kubectl kustomize astrololo` składa komplet 21 zasobów bez błędu; +YAML wszystkich manifestów parsuje się poprawnie; audyt odwołań do sekretów +potwierdza, że jedyne brakujące to `astrololo-postgres` (oba klucze); DSN +`postgresql+psycopg://…` jest poprawnie rozpoznawany przez SQLAlchemy 2.0 +z zainstalowanym `psycopg` 3. + +**NIE sprawdzone, bo nie było na czym:** skrypt inicjalizujący nie został +uruchomiony przeciwko prawdziwemu Postgresowi (na maszynie, na której to +powstawało, nie ma Dockera). Składnia jest prosta i przejrzana, ale **krok 4 jest +tu prawdziwym testem** — jeśli coś ma nie zadziałać, to właśnie tam. + +--- + +## Część 4 — typowe problemy + +| objaw | przyczyna | co zrobić | +|---|---|---| +| PVC wisi w `Pending` | brak `local-path` albo brak miejsca na węźle | `kubectl get storageclass`, `kubectl describe pvc postgres-data` | +| pod w `CrashLoopBackOff`, w logach `directory not empty` | `PGDATA` wskazuje katalog główny wolumenu | sprawdź, czy `PGDATA` to `…/data/pgdata` (jest w manifeście) | +| pod nie startuje, `secret not found` | nie wykonany krok 1 | utwórz sekret i `kubectl -n astrololo rollout restart deploy/postgres` | +| `\dx` nie pokazuje `pg_trgm` | baza założona przed dodaniem ConfigMapy | patrz „Dodanie rozszerzenia do istniejącej bazy" | +| warstwa danych: `ModuleNotFoundError: psycopg` | obraz zbudowany przed dodaniem sterownika | poczekaj na build z CI albo `kubectl -n astrololo rollout restart deploy/data` po nowym obrazie | +| `password authentication failed` | `SQL_URL` w sekrecie nie zgadza się z `POSTGRES_PASSWORD` | odtwórz sekret krokiem 1 (oba klucze naraz) i zrestartuj **oba** deploymenty | + +Gdy nic nie pasuje — pierwsze dwie komendy do wklejenia: + +```bash +kubectl -n astrololo describe pod -l app=postgres | tail -30 +kubectl -n astrololo logs deploy/postgres --tail=50 +``` + +--- + +## Część 5 — pełne odtworzenie ręczne, bez ArgoCD i bez repo + +Gdyby trzeba było postawić to od zera na czystym klastrze: + +```bash +kubectl create namespace astrololo + +PGPASS="$(openssl rand -base64 24 | tr -d '/+=' | head -c 32)" +kubectl -n astrololo create secret generic astrololo-postgres \ + --from-literal=POSTGRES_PASSWORD="$PGPASS" \ + --from-literal=SQL_URL="postgresql+psycopg://astrololo:${PGPASS}@postgres:5432/astrololo" +unset PGPASS + +kubectl apply -f astrololo/postgres.yaml +kubectl -n astrololo rollout status deploy/postgres +kubectl -n astrololo exec deploy/postgres -- psql -U astrololo -d astrololo -c "\dx" +``` + +Reszta aplikacji wymaga jeszcze sekretów `astrololo-auth` i `astrololo-link` — +patrz [README.md](README.md). diff --git a/astrololo/README.md b/astrololo/README.md index 2d2ca2d..85a5236 100644 --- a/astrololo/README.md +++ b/astrololo/README.md @@ -23,6 +23,15 @@ Ten plik **celowo nie jest w `kustomization.yaml`**: resource stoi w ns `argocd` (poza namespace docelowym aplikacji), a to konfiguracja kontrolera, który wdraża tę aplikację — nakładamy go ręcznie, w repo trzymamy dla odtwarzalności i historii. +## Postgres — lustro baz w SQL (DAN-28) + +Osobny runbook: **[README-postgres.md](README-postgres.md)** — co zrobiono w repo, +co musisz zrobić ręcznie (sekret `astrololo-postgres`), jak sprawdzić rozszerzenia +`pg_trgm`/`unaccent` i jak odtworzyć całość bez ArgoCD. + +Postgres trzyma LUSTRO plików Excela, nie źródło prawdy — jego utrata nie jest +utratą danych, więc kopie zapasowe są opcjonalne. + ## ⚠️ Sekret `astrololo-auth` — utwórz PRZED wdrożeniem Aplikacja wystawia treść **oryginalnych baz interpretacyjnych**, dlatego wymaga diff --git a/astrololo/data.yaml b/astrololo/data.yaml index f6556a5..8e133a1 100644 --- a/astrololo/data.yaml +++ b/astrololo/data.yaml @@ -44,6 +44,16 @@ spec: # zdążyłby wypuścić zapytanie jawnym tekstem, zanim dostanie odmowę. - name: LINK_ENCRYPTION_REQUIRED value: "true" + # Lustro baz w SQL (DAN-28). DSN w SEKRECIE, bo niesie hasło — + # w manifeście zostałoby w historii gita na zawsze. + # + # Sam adres nie przełącza jeszcze warstwy na SQL: o tym decyduje + # DATA_PROVIDER, które celowo zostaje na `excel`, dopóki lustro nie + # jest zaimplementowane i sprawdzone. Dzięki temu Postgres można + # wdrożyć i obejrzeć BEZ ryzyka dla działającego wyszukiwania. + - name: SQL_URL + valueFrom: + secretKeyRef: { name: astrololo-postgres, key: SQL_URL } volumeMounts: - name: cache mountPath: /app/.cache diff --git a/astrololo/kustomization.yaml b/astrololo/kustomization.yaml index 33a62c5..ada68a1 100644 --- a/astrololo/kustomization.yaml +++ b/astrololo/kustomization.yaml @@ -2,6 +2,7 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - namespace.yaml + - postgres.yaml # lustro baz Excela w SQL (DAN-28) — sekret astrololo-postgres POZA repo - data.yaml - logic.yaml - presentation.yaml diff --git a/astrololo/postgres.yaml b/astrololo/postgres.yaml new file mode 100644 index 0000000..1b9b84d --- /dev/null +++ b/astrololo/postgres.yaml @@ -0,0 +1,150 @@ +# Postgres — lustro baz Excela w SQL (DAN-28). +# +# DLACZEGO POSTGRES, A NIE SQLITE. Nie ze względu na skalę: dzisiejszy zbiór to +# ~54 tys. wierszy, przy których SQLite bywa szybszy. Powodem jest WYSZUKIWANIE +# w nieznormalizowanym, polskim tekście — `pg_trgm` (dopasowanie rozmyte, literówki) +# i `unaccent` (ogonki) nie mają w SQLite taniego zamiennika, a to jest główna +# funkcja programu, nie dodatek. Drugi powód: `pg_advisory_lock` sprawia, że model +# sesji z atomowym commitem przestaje zakładać „jedna replika na zawsze". +# +# TO LUSTRO, NIE ŹRÓDŁO PRAWDY. Źródłem są pliki Excela na NFS. Utrata tej bazy +# NIE JEST utratą danych — odbudowuje się z plików. Dlatego kopie zapasowe są tu +# OPCJONALNE, a wolumen może stać na local-path. +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: postgres-data + namespace: astrololo +spec: + accessModes: [ReadWriteOnce] + # local-path (domyślny provisioner k3s), NIE NFS. Postgres zakłada semantykę + # blokad i fsync, której NFS nie gwarantuje — to klasyczne źródło uszkodzenia + # bazy przy nagłym restarcie. Ceną jest przywiązanie do węzła; przy luście + # odtwarzalnym z Excela to akceptowalne. + storageClassName: local-path + resources: + requests: + storage: 5Gi +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: postgres-init + namespace: astrololo +data: + # UWAGA: skrypty z /docker-entrypoint-initdb.d/ uruchamiają się WYŁĄCZNIE przy + # pierwszej inicjalizacji, na pustym katalogu danych. Dopisanie tu rozszerzenia + # PO utworzeniu bazy nic nie zrobi — trzeba je wtedy założyć ręcznie (patrz + # README-postgres.md, sekcja „Dodanie rozszerzenia do istniejącej bazy"). + 01-extensions.sql: | + -- Dopasowanie rozmyte: similarity(), operator %, indeksy GIN po trigramach. + -- To jest powód, dla którego stoi tu Postgres, a nie SQLite. + CREATE EXTENSION IF NOT EXISTS pg_trgm; + -- Zdejmowanie ogonków: „różdżka" ma się znaleźć na „rozdzka". + CREATE EXTENSION IF NOT EXISTS unaccent; + + -- Schemat na lustro. Osobny, żeby purge i odbudowa nie musiały ruszać + -- niczego w `public` i żeby `DROP SCHEMA mirror CASCADE` był bezpiecznym + -- „wyczyść wszystko i wczytaj od nowa". + CREATE SCHEMA IF NOT EXISTS mirror; + + -- Rejestr luster: co, z jakiego pliku, o jakim skrócie i kiedy wczytane. + -- Zgodność pliku z tabelą poznajemy po sha256 — nazwa pliku nie wystarcza, + -- bo treść potrafi się zmienić bez zmiany nazwy. + CREATE TABLE IF NOT EXISTS mirror.registry ( + table_name text PRIMARY KEY, + source_path text NOT NULL UNIQUE, + sha256 text NOT NULL, + row_count integer NOT NULL DEFAULT 0, + loaded_at timestamptz NOT NULL DEFAULT now(), + active boolean NOT NULL DEFAULT false + ); + CREATE INDEX IF NOT EXISTS registry_active_idx ON mirror.registry (active); +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: postgres + namespace: astrololo +spec: + replicas: 1 + # Recreate, NIE RollingUpdate: wolumen jest ReadWriteOnce, a dwa procesy + # Postgresa na jednym katalogu danych to uszkodzona baza. Rolling próbowałby + # wstać z nowym podem, zanim stary zejdzie. + strategy: + type: Recreate + selector: + matchLabels: { app: postgres } + template: + metadata: + labels: { app: postgres } + spec: + containers: + - name: postgres + # Wersja PRZYPIĘTA i celowo poza image-updaterem: podbicie majora + # Postgresa wymaga migracji katalogu danych, więc nie może się zdarzyć + # samo, w nocy, przy okazji builda aplikacji. + image: postgres:17 + ports: [{ containerPort: 5432, name: postgres }] + env: + - name: POSTGRES_DB + value: astrololo + - name: POSTGRES_USER + value: astrololo + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: { name: astrololo-postgres, key: POSTGRES_PASSWORD } + # PGDATA w PODKATALOGU montowanego wolumenu. Katalog główny wolumenu + # potrafi zawierać wpisy systemu plików (np. lost+found), a initdb + # odmawia inicjalizacji w niepustym katalogu. + - name: PGDATA + value: /var/lib/postgresql/data/pgdata + # C.UTF-8 zamiast pl_PL.UTF-8: dopasowanie tekstu robimy przez + # unaccent i pg_trgm, nie przez collation, a locale pl_PL wymagałoby + # obrazu z wygenerowanymi lokalizacjami. Gdyby kiedyś potrzebne było + # polskie SORTOWANIE, dokłada się collation ICU na konkretnej kolumnie. + - name: POSTGRES_INITDB_ARGS + value: "--encoding=UTF8 --locale=C.UTF-8" + volumeMounts: + - name: data + mountPath: /var/lib/postgresql/data + - name: init + mountPath: /docker-entrypoint-initdb.d + readOnly: true + # pg_isready, nie zwykły TCP: gniazdo słucha, zanim baza przyjmuje + # zapytania, więc sonda po porcie przepuściłaby ruch za wcześnie. + readinessProbe: + exec: + command: ["pg_isready", "-U", "astrololo", "-d", "astrololo", "-q"] + initialDelaySeconds: 5 + periodSeconds: 5 + livenessProbe: + exec: + command: ["pg_isready", "-U", "astrololo", "-d", "astrololo", "-q"] + initialDelaySeconds: 30 + periodSeconds: 20 + failureThreshold: 6 + resources: + requests: { cpu: "100m", memory: "256Mi" } + limits: { cpu: "1000m", memory: "1Gi" } + volumes: + - name: data + persistentVolumeClaim: + claimName: postgres-data + - name: init + configMap: + name: postgres-init +--- +apiVersion: v1 +kind: Service +metadata: + name: postgres + namespace: astrololo +spec: + # ClusterIP i tylko ClusterIP. Baza nie ma żadnego powodu być widoczna poza + # klastrem; dostęp z zewnątrz robi się przez `kubectl port-forward` na czas + # jednej sesji (patrz README-postgres.md). + type: ClusterIP + selector: { app: postgres } + ports: [{ port: 5432, targetPort: 5432 }]