init: 폴더구조 설계 및 인프라 설계
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
# k8s/base/managing AGENTS
|
||||
|
||||
Role:
|
||||
- own management and operational Kubernetes base units
|
||||
- model bootstrap, migration, backup, restore, maintenance, and admin workloads as declarative Kustomize bases
|
||||
- keep operational workloads separate from long-running application serving workloads
|
||||
|
||||
Allowed:
|
||||
- Job / CronJob base resources for operational tasks
|
||||
- maintenance ServiceAccount / RBAC / ConfigMap / Secret reference wiring
|
||||
- backup / restore / migration helper workload shapes
|
||||
- admin-only service shapes when explicitly justified
|
||||
|
||||
Forbidden:
|
||||
- long-running product application workloads
|
||||
- environment-specific values that belong in `k8s/overlays/<env>`
|
||||
- scripts becoming the primary source of YAML truth
|
||||
- large heredoc-generated manifests as the default path
|
||||
- embedding production secret values
|
||||
- hiding environment differences in shell conditionals instead of overlays
|
||||
- giant all-in-one jobs that mix unrelated concerns
|
||||
|
||||
Read first:
|
||||
- `/docs/standards/infra/workload-selection.md`
|
||||
- `/docs/standards/infra/db-and-migration.md`
|
||||
- `/docs/standards/infra/flyway.md`
|
||||
- `/docs/standards/infra/backup-restore.md`
|
||||
- `/docs/standards/infra/operations-runbook-upgrade-rollback.md`
|
||||
- `/docs/standards/infra/config-and-secrets.md`
|
||||
- `/docs/standards/infra/security-hardening.md`
|
||||
- `/docs/standards/infra/kustomize.md`
|
||||
|
||||
Examples:
|
||||
- `/docs/examples/infra/flyway.md`
|
||||
- `/docs/examples/infra/backup-restore.md`
|
||||
- `/docs/examples/infra/operations-runbook-upgrade-rollback.md`
|
||||
- `/docs/examples/infra/db-and-migration.md`
|
||||
- `/docs/examples/infra/kustomize.md`
|
||||
- `/docs/examples/infra/scripts.md`
|
||||
|
||||
Rules:
|
||||
- management jobs are explicit operational units, not hidden app startup hooks
|
||||
- migrations must stay separate from app startup
|
||||
- backup and restore paths must be documented before risky stateful changes
|
||||
- destructive operations require explicit opt-in and runbook backing
|
||||
- operational workloads must still follow security, resource, secret, and namespace standards
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
resources:
|
||||
- namespace
|
||||
@@ -0,0 +1,80 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: migration-flyway-sql
|
||||
labels:
|
||||
app.kubernetes.io/name: migration-flyway
|
||||
app.kubernetes.io/instance: migration-flyway
|
||||
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');
|
||||
@@ -0,0 +1,119 @@
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: migration-flyway
|
||||
labels:
|
||||
app.kubernetes.io/name: migration-flyway
|
||||
app.kubernetes.io/instance: migration-flyway
|
||||
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: migration-flyway
|
||||
app.kubernetes.io/instance: migration-flyway
|
||||
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: migration-flyway-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: migration-flyway-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: migration-flyway
|
||||
app.kubernetes.io/instance: migration-flyway
|
||||
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: migration-flyway-sa
|
||||
labels:
|
||||
app.kubernetes.io/name: migration-flyway
|
||||
app.kubernetes.io/instance: migration-flyway
|
||||
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,5 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
resources:
|
||||
- namespace.yaml
|
||||
@@ -0,0 +1,16 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: mnt
|
||||
labels:
|
||||
app.kubernetes.io/name: mnt
|
||||
app.kubernetes.io/instance: mnt
|
||||
app.kubernetes.io/component: namespace
|
||||
app.kubernetes.io/part-of: infra-platform
|
||||
app.kubernetes.io/managed-by: kustomize
|
||||
pod-security.kubernetes.io/enforce: restricted
|
||||
pod-security.kubernetes.io/enforce-version: latest
|
||||
pod-security.kubernetes.io/audit: restricted
|
||||
pod-security.kubernetes.io/audit-version: latest
|
||||
pod-security.kubernetes.io/warn: restricted
|
||||
pod-security.kubernetes.io/warn-version: latest
|
||||
Reference in New Issue
Block a user