refactor: 폴더 구조 변경

This commit is contained in:
donghyeon-ka
2026-08-02 00:22:19 +09:00
parent f9c463f87a
commit be2f8e4863
1869 changed files with 4565 additions and 295591 deletions
+6
View File
@@ -0,0 +1,6 @@
# gitops/apps AGENTS
Application-owned workloads, stateful dependencies, and independently runnable
operations live here. Keep environment-neutral manifests in each unit's `base`.
Ingress hosts, image rollout references, environment labels, storage classes,
retention, and Secret delivery differences belong in `overlays/<env>`.
+18
View File
@@ -0,0 +1,18 @@
# Application Deployment Catalog
애플리케이션의 source code가 아니라 Kubernetes 배포 정의를 둡니다. app 팀이
별도 source/deploy 저장소를 소유하면 이곳에는 immutable artifact를 참조하는
GitOps 리소스만 둘 수 있습니다.
```text
apps/
└── example-api/
├── base/
└── overlays/
├── dev/
└── prod/
```
base는 환경을 모르고, overlay에는 replica/resource/config처럼 필요한 차이만
둡니다. image는 mutable tag 대신 조직 정책에 따른 고정 tag 또는 digest를
사용합니다.
+22
View File
@@ -0,0 +1,22 @@
# __REPLACE_ME_APPLICATION_NAME__
## 소유자
Team: __REPLACE_ME_OWNER__
repository와 on-call 정보를 적습니다.
## 배포 계약
- Namespace:
- Image/artifact source:
- Ports/protocol:
- Dependency:
- SLO/alerts:
## 구성
- `base`: 공통 Kubernetes 배포 정의
- `overlays`: 환경별 replica, resource, config 차이
비밀은 ExternalSecret 같은 참조 또는 승인된 암호화 형식으로만 추가합니다.
+4
View File
@@ -0,0 +1,4 @@
# Base
환경을 모르는 application의 공통 manifest를 둡니다. namespace 자체의 소유권이
tenant catalog에 있다면 이곳에서 중복 생성하지 않습니다.
@@ -0,0 +1,4 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources: []
+6
View File
@@ -0,0 +1,6 @@
# Overlays
필요한 환경에만 overlay를 추가합니다. 각 overlay는 `../../base`를 참조하고
환경별 patch만 포함합니다.
비밀값, 임시 debug 설정과 수동 hotfix 결과를 overlay에 커밋하지 않습니다.
+5
View File
@@ -0,0 +1,5 @@
# gitops/apps/auth-migration AGENTS
Jobs and CronJobs live here. Operations are versioned, independently runnable
units and must not be hidden inside an application base. Define completion,
retry, timeout, rollback, and rerun semantics before changing them.
@@ -0,0 +1,80 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: auth-server-migrate-sql
labels:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server-migrate-0-1-0
app.kubernetes.io/version: "0.1.0"
app.kubernetes.io/component: migration
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
data:
V1__create_users_table.sql: |
create schema if not exists auth;
create or replace function auth.set_updated_at()
returns trigger as $$
begin
new.updated_at := current_timestamp;
return new;
end;
$$ language plpgsql;
create table auth.users (
id uuid not null,
email text not null,
encoded_password text not null,
name text not null,
provider text not null,
created_at timestamp with time zone not null default current_timestamp,
updated_at timestamp with time zone not null default current_timestamp,
constraint pk_users primary key (id),
constraint uq_users__email unique (email),
constraint ck_users__provider check (provider in ('LOCAL', 'GOOGLE', 'GITHUB'))
);
create index ix_users__created_at on auth.users (created_at);
create trigger trg_users__set_updated_at
before update on auth.users
for each row
when (old.* is distinct from new.*)
execute function auth.set_updated_at();
V2__add_oauth_login_columns.sql: |
alter table auth.users alter column encoded_password drop not null;
alter table auth.users add column provider_subject text;
alter table auth.users
add constraint uq_users__provider_provider_subject unique (provider, provider_subject);
V3__add_user_provider_field_constraints.sql: |
alter table auth.users
add constraint ck_users__local_password_required
check (
(provider = 'LOCAL' and encoded_password is not null and provider_subject is null)
or (provider <> 'LOCAL')
);
alter table auth.users
add constraint ck_users__social_subject_required
check (
(provider <> 'LOCAL' and provider_subject is not null and encoded_password is null)
or (provider = 'LOCAL')
);
V4__add_keycloak_provider.sql: |
alter table auth.users drop constraint ck_users__provider;
alter table auth.users
add constraint ck_users__provider check (provider in ('LOCAL', 'KEYCLOAK', 'GOOGLE', 'GITHUB'));
V5__keycloak_only_provider.sql: |
alter table auth.users drop constraint if exists ck_users__local_password_required;
alter table auth.users drop constraint if exists ck_users__social_subject_required;
alter table auth.users drop constraint if exists ck_users__provider;
alter table auth.users drop column if exists encoded_password;
alter table auth.users alter column provider_subject set not null;
alter table auth.users
add constraint ck_users__provider check (provider = 'KEYCLOAK');
+119
View File
@@ -0,0 +1,119 @@
apiVersion: batch/v1
kind: Job
metadata:
name: auth-server-migrate-0-1-0
labels:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server-migrate-0-1-0
app.kubernetes.io/version: "0.1.0"
app.kubernetes.io/component: migration
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
spec:
parallelism: 1
completions: 1
backoffLimit: 0
activeDeadlineSeconds: 1800
ttlSecondsAfterFinished: 86400
template:
metadata:
labels:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server-migrate-0-1-0
app.kubernetes.io/version: "0.1.0"
app.kubernetes.io/component: migration
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
spec:
serviceAccountName: auth-server-migrate-sa
automountServiceAccountToken: false
restartPolicy: Never
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
fsGroupChangePolicy: OnRootMismatch
seccompProfile:
type: RuntimeDefault
initContainers:
- name: flyway-info
image: flyway/flyway:10.20.1
imagePullPolicy: IfNotPresent
command: ["/bin/sh", "-c"]
args: ["FLYWAY_USER=\"$(cat /run/secrets/db/SPRING_DATASOURCE_USERNAME)\" FLYWAY_PASSWORD=\"$(cat /run/secrets/db/SPRING_DATASOURCE_PASSWORD)\" exec /flyway/flyway info"]
env: &flywayEnv
- name: FLYWAY_URL
value: jdbc:postgresql://identity-postgres:5432/auth_server
- name: FLYWAY_LOCATIONS
value: filesystem:/flyway/sql
- name: FLYWAY_SCHEMAS
value: auth
- name: FLYWAY_DEFAULT_SCHEMA
value: auth
- name: FLYWAY_TABLE
value: flyway_schema_history
- name: FLYWAY_VALIDATE_ON_MIGRATE
value: "true"
- name: FLYWAY_BASELINE_ON_MIGRATE
value: "false"
- name: FLYWAY_OUT_OF_ORDER
value: "false"
- name: FLYWAY_MIXED
value: "false"
- name: FLYWAY_CLEAN_DISABLED
value: "true"
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 256Mi
securityContext: &flywaySC
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
allowPrivilegeEscalation: false
privileged: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault
volumeMounts: &flywayVM
- name: sql
mountPath: /flyway/sql
readOnly: true
- name: db-secret
mountPath: /run/secrets/db
readOnly: true
- name: tmp
mountPath: /tmp
containers:
- name: flyway-migrate
image: flyway/flyway:10.20.1
imagePullPolicy: IfNotPresent
command: ["/bin/sh", "-c"]
args: ["FLYWAY_USER=\"$(cat /run/secrets/db/SPRING_DATASOURCE_USERNAME)\" FLYWAY_PASSWORD=\"$(cat /run/secrets/db/SPRING_DATASOURCE_PASSWORD)\" exec /flyway/flyway migrate"]
env: *flywayEnv
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
memory: 512Mi
securityContext: *flywaySC
volumeMounts: *flywayVM
volumes:
- name: sql
configMap:
name: auth-server-migrate-sql
- name: db-secret
secret:
secretName: auth-server-db
defaultMode: 0400
- name: tmp
emptyDir:
medium: Memory
sizeLimit: 128Mi
@@ -0,0 +1,16 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- serviceaccount.yaml
- configmap-sql.yaml
- job.yaml
labels:
- pairs:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server-migrate-0-1-0
app.kubernetes.io/version: "0.1.0"
app.kubernetes.io/component: migration
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
includeSelectors: false
includeTemplates: true
@@ -0,0 +1,12 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: auth-server-migrate-sa
labels:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server-migrate-0-1-0
app.kubernetes.io/version: "0.1.0"
app.kubernetes.io/component: migration
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
automountServiceAccountToken: false
@@ -0,0 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: mnt
resources:
- ../../base
- networkpolicy.yaml
@@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: auth-server-migrate-egress-postgres
labels:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server-migrate-0-1-0
app.kubernetes.io/component: migration
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server-migrate-0-1-0
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app.kubernetes.io/name: identity-postgres
app.kubernetes.io/instance: identity-postgres
ports:
- protocol: TCP
port: 5432
@@ -0,0 +1,19 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: auth-server-config
labels:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server
app.kubernetes.io/version: "0.1.0"
app.kubernetes.io/component: api
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
data:
SPRING_PROFILES_ACTIVE: dev
SPRING_DATASOURCE_URL: jdbc:postgresql://identity-postgres:5432/auth_server
APP_DATASOURCE_URL: jdbc:postgresql://identity-postgres:5432/auth_server
MANAGEMENT_SERVER_ADDRESS: 0.0.0.0
MANAGEMENT_SERVER_PORT: "8081"
MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: health,prometheus
SERVER_PORT: "8080"
@@ -0,0 +1,128 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: auth-server
labels:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server
app.kubernetes.io/version: "0.1.0"
app.kubernetes.io/component: api
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
spec:
replicas: 1
revisionHistoryLimit: 5
progressDeadlineSeconds: 600
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 0
selector:
matchLabels:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server
template:
metadata:
labels:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server
app.kubernetes.io/version: "0.1.0"
app.kubernetes.io/component: api
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
spec:
serviceAccountName: auth-server-sa
automountServiceAccountToken: false
terminationGracePeriodSeconds: 45
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server
securityContext:
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
fsGroup: 10001
fsGroupChangePolicy: OnRootMismatch
seccompProfile:
type: RuntimeDefault
containers:
- name: auth-server
image: registry.example.com/auth-platform/auth-server:0.1.0
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 8080
protocol: TCP
- name: metrics
containerPort: 8081
protocol: TCP
envFrom:
- configMapRef:
name: auth-server-config
- secretRef:
name: auth-server-db
env:
- name: JAVA_TOOL_OPTIONS
value: "-XX:MaxRAMPercentage=75 -XX:+ExitOnOutOfMemoryError"
- name: SPRING_CONFIG_IMPORT
value: "optional:configtree:/etc/secrets/"
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
memory: 768Mi
startupProbe:
httpGet:
path: /actuator/health/liveness
port: metrics
periodSeconds: 5
failureThreshold: 24
timeoutSeconds: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: metrics
periodSeconds: 5
failureThreshold: 3
timeoutSeconds: 2
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: metrics
periodSeconds: 15
failureThreshold: 3
timeoutSeconds: 3
securityContext:
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
allowPrivilegeEscalation: false
privileged: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault
volumeMounts:
- name: db-creds
mountPath: /etc/secrets
readOnly: true
- name: tmp
mountPath: /tmp
volumes:
- name: db-creds
secret:
secretName: auth-server-db
defaultMode: 0400
- name: tmp
emptyDir:
medium: Memory
sizeLimit: 128Mi
@@ -0,0 +1,17 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- serviceaccount.yaml
- configmap.yaml
- deployment.yaml
- service.yaml
labels:
- pairs:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server
app.kubernetes.io/version: "0.1.0"
app.kubernetes.io/component: api
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
includeSelectors: false
includeTemplates: true
+27
View File
@@ -0,0 +1,27 @@
apiVersion: v1
kind: Service
metadata:
name: auth-server
labels:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server
app.kubernetes.io/version: "0.1.0"
app.kubernetes.io/component: api
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server
ports:
- name: http
port: 80
targetPort: http
protocol: TCP
appProtocol: http
- name: metrics
port: 8081
targetPort: metrics
protocol: TCP
appProtocol: http
@@ -0,0 +1,12 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: auth-server-sa
labels:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server
app.kubernetes.io/version: "0.1.0"
app.kubernetes.io/component: api
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
automountServiceAccountToken: false
@@ -0,0 +1,27 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: auth-server
labels:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server
app.kubernetes.io/version: "0.1.0"
app.kubernetes.io/component: api
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
traefik.ingress.kubernetes.io/router.middlewares: kube-system-security-headers@kubernetescrd
spec:
ingressClassName: traefik
rules:
- host: auth.local.test
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: auth-server
port:
name: http
@@ -0,0 +1,40 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: mnt
resources:
- ../../base
- ingress.yaml
- networkpolicy.yaml
images:
- name: registry.example.com/auth-platform/auth-server
newName: registry.project.com/auth-platform/auth-server
newTag: manual-20260512071751
patches:
- target:
kind: ConfigMap
name: auth-server-config
patch: |-
- op: add
path: /data/APP_SECURITY_KEYCLOAK_ISSUER_URI
value: http://keycloak.local.test/realms/platform
- op: add
path: /data/SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI
value: http://keycloak.local.test/realms/platform
- op: add
path: /data/SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI
value: http://keycloak/realms/platform/protocol/openid-connect/certs
- op: add
path: /data/SERVER_MAX_HTTP_REQUEST_HEADER_SIZE
value: 64KB
- target:
kind: ServiceAccount
name: auth-server-sa
patch: |-
- op: add
path: /imagePullSecrets
value:
- name: docker-registry-pull-credentials
@@ -0,0 +1,63 @@
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: auth-server-ingress-traefik
labels:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server
app.kubernetes.io/component: api
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
app.kubernetes.io/name: traefik
ports:
- protocol: TCP
port: 8080
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: auth-server-egress
labels:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server
app.kubernetes.io/component: api
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app.kubernetes.io/name: identity-postgres
app.kubernetes.io/instance: identity-postgres
ports:
- protocol: TCP
port: 5432
- to:
- podSelector:
matchLabels:
app.kubernetes.io/instance: keycloak
app.kubernetes.io/managed-by: keycloak-operator
ports:
- protocol: TCP
port: 8080
+5
View File
@@ -0,0 +1,5 @@
# gitops/apps/identity-postgres AGENTS
Stateful data services live here. Read the storage, backup, security, and
component standard before changing a StatefulSet, Tenant, PVC, or retention
policy. Environment storage classes and deletion behavior belong in overlays.
@@ -0,0 +1,30 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: identity-postgres-initdb
labels:
app.kubernetes.io/name: identity-postgres
app.kubernetes.io/instance: identity-postgres
app.kubernetes.io/version: "16.4"
app.kubernetes.io/component: database
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
data:
01-create-databases.sh: |
#!/usr/bin/env bash
set -euo pipefail
KEYCLOAK_DB_PASSWORD="$(cat /run/secrets/keycloak-db/password)"
AUTH_SERVER_DB_PASSWORD="$(cat /run/secrets/auth-server-db/SPRING_DATASOURCE_PASSWORD)"
psql --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-'SQL'
CREATE ROLE keycloak LOGIN;
CREATE DATABASE keycloak OWNER keycloak;
CREATE ROLE auth_server LOGIN;
CREATE DATABASE auth_server OWNER auth_server;
SQL
psql --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" \
-c "ALTER ROLE keycloak PASSWORD '$(printf '%s' "$KEYCLOAK_DB_PASSWORD" | sed "s/'/''/g")';"
psql --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" \
-c "ALTER ROLE auth_server PASSWORD '$(printf '%s' "$AUTH_SERVER_DB_PASSWORD" | sed "s/'/''/g")';"
@@ -0,0 +1,18 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- serviceaccount.yaml
- configmap-initdb.yaml
- service-headless.yaml
- service.yaml
- statefulset.yaml
labels:
- pairs:
app.kubernetes.io/name: identity-postgres
app.kubernetes.io/instance: identity-postgres
app.kubernetes.io/version: "16.4"
app.kubernetes.io/component: database
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
includeSelectors: false
includeTemplates: true
@@ -0,0 +1,22 @@
apiVersion: v1
kind: Service
metadata:
name: identity-postgres-headless
labels:
app.kubernetes.io/name: identity-postgres
app.kubernetes.io/instance: identity-postgres
app.kubernetes.io/version: "16.4"
app.kubernetes.io/component: database
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
spec:
clusterIP: None
selector:
app.kubernetes.io/name: identity-postgres
app.kubernetes.io/instance: identity-postgres
ports:
- name: postgres
port: 5432
targetPort: postgres
protocol: TCP
appProtocol: postgresql
@@ -0,0 +1,22 @@
apiVersion: v1
kind: Service
metadata:
name: identity-postgres
labels:
app.kubernetes.io/name: identity-postgres
app.kubernetes.io/instance: identity-postgres
app.kubernetes.io/version: "16.4"
app.kubernetes.io/component: database
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: identity-postgres
app.kubernetes.io/instance: identity-postgres
ports:
- name: postgres
port: 5432
targetPort: postgres
protocol: TCP
appProtocol: postgresql
@@ -0,0 +1,12 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: identity-postgres-sa
labels:
app.kubernetes.io/name: identity-postgres
app.kubernetes.io/instance: identity-postgres
app.kubernetes.io/version: "16.4"
app.kubernetes.io/component: database
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
automountServiceAccountToken: false
@@ -0,0 +1,174 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: identity-postgres
labels:
app.kubernetes.io/name: identity-postgres
app.kubernetes.io/instance: identity-postgres
app.kubernetes.io/version: "16.4"
app.kubernetes.io/component: database
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
spec:
replicas: 1
serviceName: identity-postgres-headless
podManagementPolicy: OrderedReady
updateStrategy:
type: RollingUpdate
persistentVolumeClaimRetentionPolicy:
whenDeleted: Retain
whenScaled: Retain
selector:
matchLabels:
app.kubernetes.io/name: identity-postgres
app.kubernetes.io/instance: identity-postgres
template:
metadata:
labels:
app.kubernetes.io/name: identity-postgres
app.kubernetes.io/instance: identity-postgres
app.kubernetes.io/version: "16.4"
app.kubernetes.io/component: database
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
spec:
serviceAccountName: identity-postgres-sa
automountServiceAccountToken: false
terminationGracePeriodSeconds: 60
securityContext:
runAsNonRoot: true
runAsUser: 999
runAsGroup: 999
fsGroup: 999
fsGroupChangePolicy: OnRootMismatch
seccompProfile:
type: RuntimeDefault
containers:
- name: postgres
image: postgres:16.4
imagePullPolicy: IfNotPresent
ports:
- name: postgres
containerPort: 5432
protocol: TCP
env:
- name: POSTGRES_DB
value: postgres
- name: POSTGRES_USER_FILE
value: /run/secrets/superuser/username
- name: POSTGRES_PASSWORD_FILE
value: /run/secrets/superuser/password
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
- name: KEYCLOAK_DB_PASSWORD_FILE
value: /run/secrets/keycloak-db/password
- name: AUTH_SERVER_DB_PASSWORD_FILE
value: /run/secrets/auth-server-db/SPRING_DATASOURCE_PASSWORD
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: "1"
memory: 1Gi
startupProbe:
exec:
command:
- sh
- -c
- pg_isready -U "$(cat "$POSTGRES_USER_FILE")"
periodSeconds: 5
failureThreshold: 60
timeoutSeconds: 3
readinessProbe:
exec:
command:
- sh
- -c
- pg_isready -U "$(cat "$POSTGRES_USER_FILE")"
periodSeconds: 10
failureThreshold: 3
timeoutSeconds: 3
livenessProbe:
exec:
command:
- sh
- -c
- pg_isready -U "$(cat "$POSTGRES_USER_FILE")"
periodSeconds: 30
failureThreshold: 3
timeoutSeconds: 3
securityContext:
runAsNonRoot: true
runAsUser: 999
runAsGroup: 999
allowPrivilegeEscalation: false
privileged: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
- name: initdb
mountPath: /docker-entrypoint-initdb.d
readOnly: true
- name: superuser
mountPath: /run/secrets/superuser
readOnly: true
- name: keycloak-db
mountPath: /run/secrets/keycloak-db
readOnly: true
- name: auth-server-db
mountPath: /run/secrets/auth-server-db
readOnly: true
- name: tmp
mountPath: /tmp
- name: run
mountPath: /var/run/postgresql
volumes:
- name: initdb
configMap:
name: identity-postgres-initdb
defaultMode: 0755
- name: superuser
secret:
secretName: identity-postgres-superuser
defaultMode: 0400
- name: keycloak-db
secret:
secretName: keycloak-db
defaultMode: 0400
- name: auth-server-db
secret:
secretName: auth-server-db
defaultMode: 0400
- name: tmp
emptyDir:
medium: Memory
sizeLimit: 128Mi
- name: run
emptyDir:
medium: Memory
sizeLimit: 64Mi
volumeClaimTemplates:
- metadata:
name: data
labels:
app.kubernetes.io/name: identity-postgres
app.kubernetes.io/instance: identity-postgres
app.kubernetes.io/version: "16.4"
app.kubernetes.io/component: database
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
spec:
accessModes:
- ReadWriteOnce
storageClassName: replace-in-overlay
volumeMode: Filesystem
resources:
requests:
storage: 5Gi
@@ -0,0 +1,23 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: mnt
resources:
- ../../base
- networkpolicy.yaml
patches:
- target:
kind: StatefulSet
name: identity-postgres
patch: |-
- op: replace
path: /spec/persistentVolumeClaimRetentionPolicy/whenDeleted
value: Delete
- op: replace
path: /spec/persistentVolumeClaimRetentionPolicy/whenScaled
value: Delete
- op: replace
path: /spec/volumeClaimTemplates/0/spec/storageClassName
value: local-path
@@ -0,0 +1,34 @@
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: identity-postgres-ingress-clients
labels:
app.kubernetes.io/name: identity-postgres
app.kubernetes.io/instance: identity-postgres
app.kubernetes.io/component: database
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: identity-postgres
app.kubernetes.io/instance: identity-postgres
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app.kubernetes.io/instance: keycloak
app.kubernetes.io/managed-by: keycloak-operator
- podSelector:
matchLabels:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server
- podSelector:
matchLabels:
app.kubernetes.io/name: auth-server
app.kubernetes.io/instance: auth-server-migrate-0-1-0
ports:
- protocol: TCP
port: 5432
@@ -0,0 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: mnt
resources:
- platform-realm-import.yaml
@@ -0,0 +1,62 @@
apiVersion: k8s.keycloak.org/v2beta1
kind: KeycloakRealmImport
metadata:
name: platform-realm-v1
labels:
app.kubernetes.io/name: keycloak
app.kubernetes.io/instance: keycloak
app.kubernetes.io/version: "26.6.1"
app.kubernetes.io/component: identity-provider
app.kubernetes.io/part-of: auth-platform
app.kubernetes.io/managed-by: kustomize
spec:
keycloakCRName: keycloak
placeholders:
AUTH_SERVER_INGRESS_CLIENT_SECRET:
secret:
name: keycloak-client-auth-server-ingress
key: client-secret
realm:
realm: platform
enabled: true
sslRequired: external
registrationAllowed: true
loginWithEmailAllowed: true
accessTokenLifespan: 300
defaultRoles:
- user
roles:
realm:
- name: user
clients:
- clientId: auth-server-ingress
name: auth-server-ingress
protocol: openid-connect
publicClient: false
clientAuthenticatorType: client-secret
secret: ${AUTH_SERVER_INGRESS_CLIENT_SECRET}
standardFlowEnabled: true
directAccessGrantsEnabled: false
serviceAccountsEnabled: false
defaultClientScopes:
- profile
- email
- roles
protocolMappers:
- name: realm roles in id token
protocol: openid-connect
protocolMapper: oidc-usermodel-realm-role-mapper
config:
user.attribute: foo
claim.name: realm_access.roles
jsonType.label: String
multivalued: "true"
access.token.claim: "true"
id.token.claim: "true"
introspection.token.claim: "true"
redirectUris:
- http://auth.local.test/oauth2/callback
webOrigins:
- http://auth.local.test
rootUrl: http://auth.local.test
baseUrl: http://auth.local.test