Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,23 @@ Argo CD는 클러스터에 별도 설치해야 합니다. 이 저장소는 Argo

Deployment는 이에 맞춰 `runAsNonRoot`, `seccompProfile: RuntimeDefault`, `allowPrivilegeEscalation: false`, `capabilities.drop: [ALL]`, `startupProbe`, `livenessProbe`, `readinessProbe`를 포함합니다.

## Platform services for dev

auth-server가 실제로 기동되려면 `Postgres`, `Keycloak`, `Vault`가 먼저 필요합니다. dev 기준 공용 platform 서비스 manifest는 아래 경로로 관리합니다.

- Kustomize: [k8s/platform-dev/kustomization.yaml](/home/donghyeon/dev/Project-Auth-Server/k8s/platform-dev/kustomization.yaml)
- Argo CD Application: [argocd/dev-platform-application.yaml](/home/donghyeon/dev/Project-Auth-Server/argocd/dev-platform-application.yaml)

`platform-dev`는 별도 `AppProject`를 두지 않고 기존 [argocd/auth-dev-project.yaml](/home/donghyeon/dev/Project-Auth-Server/argocd/auth-dev-project.yaml)을 함께 사용합니다. 현재 단계에서는 같은 저장소/같은 dev 환경에서 auth-server와 공용 platform 서비스를 같이 관리하는 편이 단순하고 충분합니다.

현재 platform manifest는 아래 서비스 이름을 기준으로 앱과 연결됩니다.

- `postgres.platform.svc.cluster.local`
- `keycloak.platform.svc.cluster.local:8081`
- `vault.platform.svc.cluster.local`

민감값은 [k8s/platform-dev/secret.yaml](/home/donghyeon/dev/Project-Auth-Server/k8s/platform-dev/secret.yaml)에 placeholder만 두고, 실제 값으로 채운 뒤 namespace에 수동 적용하는 방식을 기준으로 합니다.

## Flyway 운영 기준

Flyway는 스키마 변경을 추적하기 위해 이번 브랜치에서 적용했습니다. 다만 운영 환경에서 애플리케이션 Pod가 스케일 아웃될 때마다 마이그레이션을 시도하게 두는 구조는 지양합니다.
Expand Down
4 changes: 4 additions & 0 deletions argocd/auth-dev-project.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ spec:
destinations:
- namespace: auth-dev
server: https://kubernetes.default.svc
- namespace: platform
server: https://kubernetes.default.svc

clusterResourceWhitelist:
- group: ""
Expand All @@ -29,6 +31,8 @@ spec:
kind: Service
- group: ""
kind: ServiceAccount
- group: ""
kind: PersistentVolumeClaim
- group: "apps"
kind: Deployment
- group: "apps"
Expand Down
32 changes: 32 additions & 0 deletions argocd/dev-platform-application.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: platform-dev
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: auth-dev
source:
repoURL: https://github.com/DongHyeonka/Project-Auth-Server.git
targetRevision: develop
path: k8s/platform-dev
destination:
server: https://kubernetes.default.svc
namespace: platform
syncPolicy:
automated:
enabled: true
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- PruneLast=true
- ApplyOutOfSyncOnly=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
revisionHistoryLimit: 5
2 changes: 1 addition & 1 deletion k8s/dev/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ data:
APP_DOCS_VERSION: v1
APP_DATASOURCE_URL: jdbc:postgresql://postgres.platform.svc.cluster.local:5432/project_auth
APP_PERSISTENCE_MIGRATION_RUN_ON_STARTUP: "false"
APP_SECURITY_OAUTH2_KEYCLOAK_ISSUER_URI: http://keycloak.platform.svc.cluster.local:8080/realms/project-auth
APP_SECURITY_OAUTH2_KEYCLOAK_ISSUER_URI: http://keycloak.platform.svc.cluster.local:8081/realms/project-auth
APP_SECURITY_OAUTH2_KEYCLOAK_CLIENT_ID: project-auth-server
APP_SECURITY_OAUTH2_GOOGLE_REGISTRATION_ID: keycloak-google
APP_SECURITY_OAUTH2_GOOGLE_IDP_HINT: google
Expand Down
15 changes: 15 additions & 0 deletions k8s/platform-dev/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: platform-config
data:
POSTGRES_SUPERUSER: postgres
POSTGRES_DEFAULT_DB: postgres
AUTH_DB_NAME: project_auth
AUTH_DB_USER: project_auth
KEYCLOAK_DB_NAME: keycloak
KEYCLOAK_DB_USER: keycloak
KEYCLOAK_BOOTSTRAP_ADMIN_USERNAME: admin
KEYCLOAK_CLIENT_ID: project-auth-server
AUTH_SERVER_BASE_URL: http://auth-server.auth-dev.svc.cluster.local:8080
VAULT_TRANSIT_KEY_NAME: project-auth-jwt
22 changes: 22 additions & 0 deletions k8s/platform-dev/files/keycloak/project-auth-realm.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"realm": "project-auth",
"enabled": true,
"displayName": "Project Auth",
"sslRequired": "NONE",
"registrationAllowed": false,
"loginWithEmailAllowed": true,
"duplicateEmailsAllowed": false,
"resetPasswordAllowed": true,
"clients": [
{
"clientId": "project-auth-server",
"name": "project-auth-server",
"enabled": true,
"protocol": "openid-connect",
"publicClient": false,
"standardFlowEnabled": true,
"directAccessGrantsEnabled": false,
"serviceAccountsEnabled": false
}
]
}
10 changes: 10 additions & 0 deletions k8s/platform-dev/files/postgres/01-init-project-auth-databases.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh
set -eu

psql -v ON_ERROR_STOP=1 --username "${POSTGRES_USER}" --dbname "${POSTGRES_DB}" <<-EOSQL
CREATE USER ${AUTH_DB_USER} WITH PASSWORD '${AUTH_DB_PASSWORD}';
CREATE DATABASE ${AUTH_DB_NAME} OWNER ${AUTH_DB_USER};

CREATE USER ${KEYCLOAK_DB_USER} WITH PASSWORD '${KEYCLOAK_DB_PASSWORD}';
CREATE DATABASE ${KEYCLOAK_DB_NAME} OWNER ${KEYCLOAK_DB_USER};
EOSQL
11 changes: 11 additions & 0 deletions k8s/platform-dev/files/vault/01-init-transit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/sh

set -eu

until vault status -address="${VAULT_ADDR}" >/dev/null 2>&1; do
sleep 2
done

vault secrets enable transit || true
vault write "transit/keys/${VAULT_TRANSIT_KEY_NAME}" type="rsa-2048" || true
vault read "transit/keys/${VAULT_TRANSIT_KEY_NAME}"
67 changes: 67 additions & 0 deletions k8s/platform-dev/keycloak-client-sync-job.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
apiVersion: batch/v1
kind: Job
metadata:
name: keycloak-client-sync
spec:
backoffLimit: 5
template:
metadata:
labels:
app: keycloak-client-sync
spec:
restartPolicy: OnFailure
containers:
- name: keycloak-client-sync
image: quay.io/keycloak/keycloak:26.5.5
command:
- /bin/sh
- -c
- |
set -eu

until /opt/keycloak/bin/kcadm.sh config credentials \
--server http://keycloak.platform.svc.cluster.local:8081 \
--realm master \
--user "$KC_BOOTSTRAP_ADMIN_USERNAME" \
--password "$KC_BOOTSTRAP_ADMIN_PASSWORD" >/dev/null 2>&1; do
sleep 5
done

CLIENT_UUID=$(/opt/keycloak/bin/kcadm.sh get clients \
-r project-auth \
-q clientId="$KEYCLOAK_CLIENT_ID" | sed -n 's/.*"id" : "\([^"]*\)".*/\1/p' | head -n 1)

test -n "$CLIENT_UUID"

/opt/keycloak/bin/kcadm.sh update "clients/${CLIENT_UUID}" \
-r project-auth \
-s "secret=$KEYCLOAK_CLIENT_SECRET" \
-s "baseUrl=$AUTH_SERVER_BASE_URL" \
-s 'redirectUris=["'"$AUTH_SERVER_BASE_URL"'/login/oauth2/code/keycloak-google","'"$AUTH_SERVER_BASE_URL"'/login/oauth2/code/keycloak-github"]' \
-s 'webOrigins=["'"$AUTH_SERVER_BASE_URL"'"]'
env:
- name: KC_BOOTSTRAP_ADMIN_USERNAME
valueFrom:
configMapKeyRef:
name: platform-config
key: KEYCLOAK_BOOTSTRAP_ADMIN_USERNAME
- name: KC_BOOTSTRAP_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: platform-secret
key: KEYCLOAK_BOOTSTRAP_ADMIN_PASSWORD
- name: KEYCLOAK_CLIENT_ID
valueFrom:
configMapKeyRef:
name: platform-config
key: KEYCLOAK_CLIENT_ID
- name: KEYCLOAK_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: platform-secret
key: KEYCLOAK_CLIENT_SECRET
- name: AUTH_SERVER_BASE_URL
valueFrom:
configMapKeyRef:
name: platform-config
key: AUTH_SERVER_BASE_URL
84 changes: 84 additions & 0 deletions k8s/platform-dev/keycloak-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: keycloak
spec:
replicas: 1
selector:
matchLabels:
app: keycloak
template:
metadata:
labels:
app: keycloak
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: keycloak
image: quay.io/keycloak/keycloak:26.5.5
args:
- start-dev
- --import-realm
- --http-port=8080
ports:
- containerPort: 8080
name: http
env:
- name: KC_DB
value: postgres
- name: KC_DB_URL
value: jdbc:postgresql://postgres.platform.svc.cluster.local:5432/keycloak
- name: KC_DB_USERNAME
valueFrom:
configMapKeyRef:
name: platform-config
key: KEYCLOAK_DB_USER
- name: KC_DB_PASSWORD
valueFrom:
secretKeyRef:
name: platform-secret
key: KEYCLOAK_DB_PASSWORD
- name: KC_HEALTH_ENABLED
value: "true"
- name: KC_BOOTSTRAP_ADMIN_USERNAME
valueFrom:
configMapKeyRef:
name: platform-config
key: KEYCLOAK_BOOTSTRAP_ADMIN_USERNAME
- name: KC_BOOTSTRAP_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: platform-secret
key: KEYCLOAK_BOOTSTRAP_ADMIN_PASSWORD
volumeMounts:
- name: keycloak-realm-import
mountPath: /opt/keycloak/data/import/project-auth-realm.json
subPath: project-auth-realm.json
readinessProbe:
httpGet:
path: /health/ready
port: http
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 3
livenessProbe:
httpGet:
path: /health/live
port: http
initialDelaySeconds: 40
periodSeconds: 15
timeoutSeconds: 3
resources:
requests:
cpu: 250m
memory: 768Mi
limits:
cpu: 1000m
memory: 1536Mi
volumes:
- name: keycloak-realm-import
configMap:
name: keycloak-realm-import
12 changes: 12 additions & 0 deletions k8s/platform-dev/keycloak-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: keycloak
spec:
selector:
app: keycloak
ports:
- name: http
port: 8081
targetPort: 8080
type: ClusterIP
30 changes: 30 additions & 0 deletions k8s/platform-dev/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: platform

resources:
- namespace.yaml
- configmap.yaml
- postgres-service.yaml
- postgres-statefulset.yaml
- keycloak-service.yaml
- keycloak-deployment.yaml
- keycloak-client-sync-job.yaml
- vault-service.yaml
- vault-deployment.yaml
- vault-init-job.yaml

generatorOptions:
disableNameSuffixHash: true

configMapGenerator:
- name: postgres-init-script
files:
- files/postgres/01-init-project-auth-databases.sh
- name: keycloak-realm-import
files:
- files/keycloak/project-auth-realm.json
- name: vault-init-script
files:
- files/vault/01-init-transit.sh
11 changes: 11 additions & 0 deletions k8s/platform-dev/namespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: v1
kind: Namespace
metadata:
name: platform
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/enforce-version: latest
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/warn-version: latest
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/audit-version: latest
13 changes: 13 additions & 0 deletions k8s/platform-dev/postgres-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: postgres
spec:
clusterIP: None
selector:
app: postgres
ports:
- name: postgres
port: 5432
targetPort: 5432
type: ClusterIP
Loading