Add platform infrastructure configuration

This commit is contained in:
donghyeon-ka
2026-08-28 17:35:41 +09:00
parent fa76531e5b
commit 16c337bcc9
302 changed files with 83259 additions and 1 deletions
+73
View File
@@ -0,0 +1,73 @@
# 플랫폼 PostgreSQL — Phase 1 빌드 루트
이 Kustomization은 `platform-data` namespace에 Phase 1 CloudNativePG 기반 구성을
선언한다.
- `platform-postgres`라는 `Cluster` 하나
- Gitea용 `DatabaseRole``Database`
- CloudNativePG, 동일 Cluster 트래픽 및 Gitea만 허용하는 기본 ingress
NetworkPolicy
PostgreSQL 17.9 인스턴스 하나로 시작하며 20 GiB Claim을 홈 서버의 정적
`ssd-local-postgres-retain` StorageClass에 바인딩한다. CloudNativePG에서는 필수
read/write Service만 유지한다.
```text
platform-postgres-rw.platform-data.svc.cluster.local:5432
```
이미지 `ghcr.io/cloudnative-pg/postgresql:17.9-standard-trixie`는 공식 PostgreSQL
17 멀티 아키텍처 이미지로 고정되어 있다. 백업 및 복원 시험 후 의도적으로 태그를
업그레이드한다.
Cluster의 사용자 정의 `pg_hba` 규칙은 `gitea``gitea` Database에만,
`keycloak``keycloak` Database에만 인증하도록 허용한 뒤 각 Role의 다른 모든
Database 접근을 거부한다. 이 규칙들은 CloudNativePG의 기본 fallback 인증 규칙보다
앞에 배치된다.
## Phase 1 Secret 계약
Cluster를 생성하기 전에 `platform-data``gitea-db-credentials`를 생성한다.
- 유형: `kubernetes.io/basic-auth`
- label: `cnpg.io/reload: "true"`
- `username`: 정확히 `gitea`
- `password`: Git 외부에서 제공하는 생성된 비밀번호
동일한 credential 값을 `gitea` namespace에 복사한다. `initdb` bootstrap은 최초
소유자와 Database를 만들 때 이 Secret을 사용하고 data checksum을 활성화한다.
Gitea Role과 Database는 모두 `retain` 조정 정책을 사용한다.
Keycloak `DatabaseRole`, `Database`, Secret 참조 및 namespace 전용 ingress 허용은
이 Phase 1 빌드 루트에 의도적으로 포함하지 않았다. 공통 Cluster의 Keycloak HBA
허용·거부 규칙 쌍은 이곳에 유지하고, 독립적인 형제 빌드 루트
`services/platform-postgres-keycloak`이 Keycloak login Role, Database 및
namespace 전용 ingress를 추가한다. 2026-07-23 기준 이 Keycloak 확장은 실제
클러스터에 적용됐다. 두 빌드 루트가 분리돼 있으므로
`platform-data/keycloak-db-credentials`가 없어도 신규 Phase 1 baseline만은
배포할 수 있다.
## 의존성과 렌더링
1. Phase 1 namespace를 생성한다.
2. PostgreSQL SSD Local PV 기반 구성을 준비하고 적용한다.
3. CloudNativePG Operator를 설치하고 준비될 때까지 기다린다.
4. Gitea credential Secret 계약을 생성한다.
5. 이 디렉터리를 렌더링하고 적용한다.
```sh
kubectl kustomize services/platform-postgres
```
렌더링 결과에는 Cluster 하나와 Gitea의 DatabaseRole 및 Database만 있어야 한다.
Keycloak DatabaseRole, Database, Secret 참조 또는 Keycloak namespace ingress
허용은 없어야 하며, Keycloak용 HBA 정책만 존재해야 한다.
## 공식 참고 문서
- <https://cloudnative-pg.io/docs/1.30/bootstrap/>
- <https://cloudnative-pg.io/docs/1.30/declarative_role_management/>
- <https://cloudnative-pg.io/docs/1.30/declarative_database_management/>
- <https://cloudnative-pg.io/docs/1.30/postgresql_conf/>
- <https://cloudnative-pg.io/docs/1.30/service_management/>
- <https://cloudnative-pg.io/docs/1.30/networking/>
@@ -0,0 +1,46 @@
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: platform-postgres
labels:
app.kubernetes.io/name: platform-postgres
app.kubernetes.io/component: database
spec:
description: Shared platform PostgreSQL instance initialized for Gitea
instances: 1
imageName: ghcr.io/cloudnative-pg/postgresql:17.9-standard-trixie
bootstrap:
initdb:
dataChecksums: true
database: gitea
owner: gitea
secret:
name: gitea-db-credentials
postgresql:
pg_hba:
- host gitea gitea all scram-sha-256
- host all gitea all reject
- host keycloak keycloak all scram-sha-256
- host all keycloak all reject
storage:
size: 20Gi
managed:
services:
disabledDefaultServices:
- ro
- r
affinity:
enablePodAntiAffinity: false
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: "2"
memory: 4Gi
@@ -0,0 +1,22 @@
apiVersion: postgresql.cnpg.io/v1
kind: DatabaseRole
metadata:
name: platform-postgres-gitea
labels:
app.kubernetes.io/name: gitea
app.kubernetes.io/component: database-role
spec:
cluster:
name: platform-postgres
name: gitea
comment: Gitea application database owner
login: true
superuser: false
createdb: false
createrole: false
replication: false
bypassrls: false
connectionLimit: 50
passwordSecret:
name: gitea-db-credentials
databaseRoleReclaimPolicy: retain
@@ -0,0 +1,14 @@
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
name: platform-postgres-gitea
labels:
app.kubernetes.io/name: gitea
app.kubernetes.io/component: database
spec:
cluster:
name: platform-postgres
name: gitea
owner: gitea
ensure: present
databaseReclaimPolicy: retain
@@ -0,0 +1,16 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: platform-data
resources:
- cluster.yaml
- gitea-database-role.yaml
- gitea-database.yaml
- platform-postgres-network-policy.yaml
labels:
- pairs:
app.kubernetes.io/part-of: platform
app.kubernetes.io/managed-by: kustomize
includeSelectors: false
@@ -0,0 +1,53 @@
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: platform-postgres-ingress
labels:
app.kubernetes.io/name: platform-postgres
app.kubernetes.io/component: database-network-policy
spec:
podSelector:
matchLabels:
cnpg.io/cluster: platform-postgres
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: cnpg-system
podSelector:
matchLabels:
app.kubernetes.io/name: cloudnative-pg
ports:
- protocol: TCP
port: 8000
- protocol: TCP
port: 5432
- from:
- podSelector:
matchLabels:
cnpg.io/cluster: platform-postgres
ports:
- protocol: TCP
port: 8000
- protocol: TCP
port: 5432
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: gitea
ports:
- protocol: TCP
port: 5432
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: observability
podSelector:
matchLabels:
app.kubernetes.io/name: prometheus
app.kubernetes.io/instance: observability-core-kube-pr-prometheus
ports:
- protocol: TCP
port: 9187
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- overlays/home
@@ -0,0 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
- path: platform-postgres-storage-patch.yaml
@@ -0,0 +1,8 @@
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: platform-postgres
spec:
storage:
storageClass: ssd-local-postgres-retain
size: 20Gi