Add platform infrastructure configuration
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
# pgAdmin
|
||||
|
||||
PostgreSQL 관리 화면을 platform-admin 네임스페이스에 배포합니다.
|
||||
|
||||
- 주소: db-admin.learn.hyeonworks.com
|
||||
- 실제 접근 범위: 호스트 Nginx에서 LAN·Tailscale만 허용
|
||||
- 차트: dpage/pgadmin4-helm:9.16.0
|
||||
- 이미지: dpage/pgadmin4:9.16의 amd64 digest 고정
|
||||
- 저장소: 2Gi SSD Local PV, Retain
|
||||
- 배포 전략: 단일 replica, Recreate
|
||||
|
||||
Keycloak 그룹 /platform-db-admins가 있는 사용자만 OIDC 로그인이
|
||||
가능합니다. 내부 관리자는 비상용으로 유지합니다. 공유 서버 정의에는
|
||||
비밀번호가 없으며, DB 비밀번호 저장도 비활성화합니다.
|
||||
|
||||
필요한 Secret은 다음 두 개뿐이며 Git에 저장하지 않습니다.
|
||||
|
||||
- pgadmin-keycloak-oidc: client-id, client-secret
|
||||
- pgadmin-bootstrap: password
|
||||
@@ -0,0 +1,42 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: pgadmin-config
|
||||
namespace: platform-admin
|
||||
labels:
|
||||
app.kubernetes.io/name: pgadmin4
|
||||
app.kubernetes.io/instance: pgadmin
|
||||
app.kubernetes.io/part-of: platform
|
||||
data:
|
||||
config_local.py: |
|
||||
import os
|
||||
|
||||
AUTHENTICATION_SOURCES = ['oauth2', 'internal']
|
||||
OAUTH2_AUTO_CREATE_USER = True
|
||||
OAUTH2_CONFIG = [{
|
||||
'OAUTH2_NAME': 'keycloak',
|
||||
'OAUTH2_DISPLAY_NAME': 'Hyeonworks ID',
|
||||
'OAUTH2_CLIENT_ID': os.environ['PGADMIN_OIDC_CLIENT_ID'],
|
||||
'OAUTH2_CLIENT_SECRET': os.environ['PGADMIN_OIDC_CLIENT_SECRET'],
|
||||
'OAUTH2_SERVER_METADATA_URL': (
|
||||
'https://id.learn.hyeonworks.com/realms/hyeonworks/'
|
||||
'.well-known/openid-configuration'
|
||||
),
|
||||
'OAUTH2_SCOPE': 'openid email profile',
|
||||
'OAUTH2_USERNAME_CLAIM': 'preferred_username',
|
||||
'OAUTH2_ADDITIONAL_CLAIMS': {
|
||||
'groups': ['/platform-db-admins'],
|
||||
},
|
||||
}]
|
||||
|
||||
ALLOW_SAVE_PASSWORD = False
|
||||
ENHANCED_COOKIE_PROTECTION = False
|
||||
SESSION_COOKIE_SECURE = True
|
||||
SESSION_COOKIE_HTTPONLY = True
|
||||
SESSION_COOKIE_SAMESITE = 'Lax'
|
||||
ALLOWED_HOSTS = ['db-admin.learn.hyeonworks.com']
|
||||
UPGRADE_CHECK_ENABLED = False
|
||||
SHOW_GRAVATAR_IMAGE = False
|
||||
LLM_ENABLED = False
|
||||
ENABLE_PSQL = False
|
||||
ENABLE_SERVER_PASS_EXEC_CMD = False
|
||||
@@ -0,0 +1,5 @@
|
||||
- op: remove
|
||||
path: /metadata/annotations/kubernetes.io~1ingress.class
|
||||
- op: add
|
||||
path: /spec/ingressClassName
|
||||
value: traefik
|
||||
@@ -0,0 +1,38 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
helmGlobals:
|
||||
chartHome: .helm/charts
|
||||
|
||||
helmCharts:
|
||||
- name: pgadmin4-helm
|
||||
repo: oci://docker.io/dpage
|
||||
version: 9.16.0
|
||||
releaseName: pgadmin
|
||||
namespace: platform-admin
|
||||
valuesFile: values/home.yaml
|
||||
includeCRDs: false
|
||||
skipTests: true
|
||||
|
||||
resources:
|
||||
- config.yaml
|
||||
- network-policies
|
||||
|
||||
patches:
|
||||
- patch: |-
|
||||
- op: add
|
||||
path: /metadata/namespace
|
||||
value: platform-admin
|
||||
target:
|
||||
labelSelector: app.kubernetes.io/instance=pgadmin
|
||||
- path: ingress-class-patch.yaml
|
||||
target:
|
||||
group: networking.k8s.io
|
||||
version: v1
|
||||
kind: Ingress
|
||||
name: pgadmin
|
||||
|
||||
images:
|
||||
- name: docker.io/dpage/pgadmin4
|
||||
newName: docker.io/dpage/pgadmin4
|
||||
digest: sha256:66a300a7ecdcc1f325af0c430315329bca46cd4a7067227d6899802238167c6e
|
||||
@@ -0,0 +1,6 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
resources:
|
||||
- pgadmin.yaml
|
||||
- platform-postgres.yaml
|
||||
@@ -0,0 +1,150 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: pgadmin-default-deny
|
||||
namespace: platform-admin
|
||||
labels:
|
||||
app.kubernetes.io/name: pgadmin4
|
||||
app.kubernetes.io/part-of: platform
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: pgadmin4
|
||||
app.kubernetes.io/instance: pgadmin
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: pgadmin-allow-traefik
|
||||
namespace: platform-admin
|
||||
labels:
|
||||
app.kubernetes.io/name: pgadmin4
|
||||
app.kubernetes.io/part-of: platform
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: pgadmin4
|
||||
app.kubernetes.io/instance: pgadmin
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: traefik
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 5050
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: pgadmin-allow-dns
|
||||
namespace: platform-admin
|
||||
labels:
|
||||
app.kubernetes.io/name: pgadmin4
|
||||
app.kubernetes.io/part-of: platform
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: pgadmin4
|
||||
app.kubernetes.io/instance: pgadmin
|
||||
policyTypes:
|
||||
- Egress
|
||||
egress:
|
||||
- to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
podSelector:
|
||||
matchLabels:
|
||||
k8s-app: kube-dns
|
||||
ports:
|
||||
- protocol: UDP
|
||||
port: 53
|
||||
- protocol: TCP
|
||||
port: 53
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: pgadmin-allow-keycloak
|
||||
namespace: platform-admin
|
||||
labels:
|
||||
app.kubernetes.io/name: pgadmin4
|
||||
app.kubernetes.io/part-of: platform
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: pgadmin4
|
||||
app.kubernetes.io/instance: pgadmin
|
||||
policyTypes:
|
||||
- Egress
|
||||
egress:
|
||||
- to:
|
||||
- ipBlock:
|
||||
cidr: 192.168.0.107/32
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 443
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: pgadmin-allow-platform-postgres
|
||||
namespace: platform-admin
|
||||
labels:
|
||||
app.kubernetes.io/name: pgadmin4
|
||||
app.kubernetes.io/part-of: platform
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: pgadmin4
|
||||
app.kubernetes.io/instance: pgadmin
|
||||
policyTypes:
|
||||
- Egress
|
||||
egress:
|
||||
- to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: platform-data
|
||||
podSelector:
|
||||
matchLabels:
|
||||
cnpg.io/cluster: platform-postgres
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 5432
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: pgadmin-allow-blackbox-health
|
||||
namespace: platform-admin
|
||||
labels:
|
||||
app.kubernetes.io/name: pgadmin4
|
||||
app.kubernetes.io/part-of: platform
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: pgadmin4
|
||||
app.kubernetes.io/instance: pgadmin
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: observability
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: prometheus-blackbox-exporter
|
||||
app.kubernetes.io/instance: blackbox-exporter
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 5050
|
||||
@@ -0,0 +1,27 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: platform-postgres-allow-pgadmin
|
||||
namespace: platform-data
|
||||
labels:
|
||||
app.kubernetes.io/name: platform-postgres
|
||||
app.kubernetes.io/component: database-network-policy
|
||||
app.kubernetes.io/part-of: platform
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
cnpg.io/cluster: platform-postgres
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: platform-admin
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: pgadmin4
|
||||
app.kubernetes.io/instance: pgadmin
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 5432
|
||||
@@ -0,0 +1,175 @@
|
||||
fullname: pgadmin
|
||||
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: dpage/pgadmin4
|
||||
tag: "9.16"
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
commonLabels:
|
||||
app: pgadmin4
|
||||
app.kubernetes.io/name: pgadmin4
|
||||
app.kubernetes.io/instance: pgadmin
|
||||
app.kubernetes.io/component: database-admin
|
||||
app.kubernetes.io/part-of: platform
|
||||
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
|
||||
containerPort: 5050
|
||||
disablePostfix: true
|
||||
enableServiceLinks: false
|
||||
|
||||
auth:
|
||||
email: platform-admin@hyeonworks.com
|
||||
existingSecret: pgadmin-bootstrap
|
||||
passwordKey: password
|
||||
|
||||
extraEnvVars:
|
||||
- name: PGADMIN_OIDC_CLIENT_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: pgadmin-keycloak-oidc
|
||||
key: client-id
|
||||
- name: PGADMIN_OIDC_CLIENT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: pgadmin-keycloak-oidc
|
||||
key: client-secret
|
||||
- name: PGADMIN_REPLACE_SERVERS_ON_STARTUP
|
||||
value: "True"
|
||||
|
||||
config_local:
|
||||
enabled: false
|
||||
|
||||
extraVolumes:
|
||||
- name: config-local
|
||||
configMap:
|
||||
name: pgadmin-config
|
||||
defaultMode: 292
|
||||
items:
|
||||
- key: config_local.py
|
||||
path: config_local.py
|
||||
|
||||
extraVolumeMounts:
|
||||
- name: config-local
|
||||
mountPath: /pgadmin4/config_local.py
|
||||
subPath: config_local.py
|
||||
readOnly: true
|
||||
|
||||
serverDefinitions:
|
||||
enabled: true
|
||||
data:
|
||||
"1":
|
||||
Name: Hyeonworks Gitea
|
||||
Group: Platform
|
||||
Host: platform-postgres-rw.platform-data.svc.cluster.local
|
||||
Port: 5432
|
||||
MaintenanceDB: gitea
|
||||
Username: gitea
|
||||
Shared: true
|
||||
SharedUsername: gitea
|
||||
ConnectionParameters:
|
||||
sslmode: require
|
||||
connect_timeout: 10
|
||||
"2":
|
||||
Name: Hyeonworks Keycloak
|
||||
Group: Platform
|
||||
Host: platform-postgres-rw.platform-data.svc.cluster.local
|
||||
Port: 5432
|
||||
MaintenanceDB: keycloak
|
||||
Username: keycloak
|
||||
Shared: true
|
||||
SharedUsername: keycloak
|
||||
ConnectionParameters:
|
||||
sslmode: require
|
||||
connect_timeout: 10
|
||||
|
||||
resources:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
limits:
|
||||
cpu: "1"
|
||||
memory: 1Gi
|
||||
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 2Gi
|
||||
storageClass: ssd-local-pgadmin-retain
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
|
||||
serviceAccount:
|
||||
create: true
|
||||
automountServiceAccountToken: false
|
||||
|
||||
ingress:
|
||||
enabled: true
|
||||
hostname: db-admin.learn.hyeonworks.com
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: traefik
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: web
|
||||
tlsSecret: ""
|
||||
|
||||
startupProbe:
|
||||
enabled: true
|
||||
httpGet:
|
||||
path: /misc/ping
|
||||
port: http
|
||||
httpHeaders:
|
||||
- name: Host
|
||||
value: db-admin.learn.hyeonworks.com
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 30
|
||||
|
||||
readinessProbe:
|
||||
enabled: true
|
||||
httpGet:
|
||||
path: /misc/ping
|
||||
port: http
|
||||
httpHeaders:
|
||||
- name: Host
|
||||
value: db-admin.learn.hyeonworks.com
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 6
|
||||
|
||||
livenessProbe:
|
||||
enabled: true
|
||||
httpGet:
|
||||
path: /misc/ping
|
||||
port: http
|
||||
httpHeaders:
|
||||
- name: Host
|
||||
value: db-admin.learn.hyeonworks.com
|
||||
periodSeconds: 20
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 6
|
||||
|
||||
podSecurityContext:
|
||||
enabled: true
|
||||
fsGroupChangePolicy: OnRootMismatch
|
||||
fsGroup: 1001
|
||||
|
||||
containerSecurityContext:
|
||||
enabled: true
|
||||
runAsUser: 1001
|
||||
runAsGroup: 1001
|
||||
runAsNonRoot: true
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
appArmorProfile:
|
||||
type: RuntimeDefault
|
||||
Reference in New Issue
Block a user