refactor: 폴더 구조 변경
This commit is contained in:
+76
-130
@@ -1,147 +1,93 @@
|
||||
# Architecture 상세
|
||||
# Architecture
|
||||
|
||||
README 의 Architecture / Key Components 를 보충하는 문서. 폴더 구조 전체와 워크로드, 이미지 정책을 모은다.
|
||||
## Ownership model
|
||||
|
||||
## 폴더 구조
|
||||
Catalog는 환경이 아니라 workload ownership으로 나눕니다.
|
||||
|
||||
```
|
||||
Project-Infra/
|
||||
├── .gitignore # vault-init-keys.json 제외
|
||||
├── .kube-linter.yaml # kube-linter 규칙 (컨텍스트 오탐 4종 제외)
|
||||
├── README.md # 본 프로젝트 진입 문서
|
||||
├── guide.md # 운영 절차서
|
||||
├── docs/ # README 보조 분할 문서
|
||||
│
|
||||
├── k8s/
|
||||
│ ├── base/
|
||||
│ │ ├── managing/
|
||||
│ │ │ ├── namespace/ # mnt namespace + PSS restricted 라벨
|
||||
│ │ │ └── migration-flyway/ # Flyway Job (공식 이미지)
|
||||
│ │ │
|
||||
│ │ ├── app/ # 애플리케이션 워크로드 (소유권 = 개발팀)
|
||||
│ │ │ ├── identity/auth/
|
||||
│ │ │ │ ├── stateful/identity-postgres/
|
||||
│ │ │ │ └── stateless/auth-server/
|
||||
│ │ │ ├── storage/minio/stateful/minio/
|
||||
│ │ │ └── test/stateless/test-server-{1,2,3}/
|
||||
│ │ │
|
||||
│ │ └── plugins/ # 플랫폼 플러그인 (다른 워크로드가 의존)
|
||||
│ │ ├── vault/ # Vault StatefulSet (공식 이미지)
|
||||
│ │ ├── docker-registry/ # Registry Deployment (공식 이미지)
|
||||
│ │ ├── oauth2-proxy/ # ForwardAuth 용 auth proxy
|
||||
│ │ └── vso/ # VSO CRD 리소스 (VaultConnection / VaultAuth / VaultStaticSecret)
|
||||
│ │
|
||||
│ ├── components/
|
||||
│ │ └── forward-auth/ # oauth2-proxy + Traefik ForwardAuth 재사용 component
|
||||
│ │
|
||||
│ ├── overlays/
|
||||
│ │ ├── dev/
|
||||
│ │ │ ├── kustomization.yaml # dev 전체 집계 (namespace: mnt)
|
||||
│ │ │ ├── networkpolicy-baseline.yaml # default-deny + DNS egress
|
||||
│ │ │ ├── platform/
|
||||
│ │ │ │ ├── traefik/ # HelmChartConfig + Middleware + TLSOption
|
||||
│ │ │ │ ├── cert-manager/ # cert-manager v1.20.2
|
||||
│ │ │ │ ├── cert-manager-issuers/ # letsencrypt-staging/prod ClusterIssuer
|
||||
│ │ │ │ └── keycloak-operator/ # Keycloak Operator 26.6.1
|
||||
│ │ │ ├── tls/ # cert-manager 적용 후 Certificate
|
||||
│ │ │ ├── vault/ # Vault overlay + NetworkPolicy + storage patch
|
||||
│ │ │ ├── registry/ # Registry overlay + NetworkPolicy + storage patch
|
||||
│ │ │ ├── vso/ # VSO CRDs (Helm 설치 후 별도 apply)
|
||||
│ │ │ ├── database/ # identity-postgres + VaultStaticSecret
|
||||
│ │ │ ├── auth/ # auth-server + Ingress(project.com) + flyway
|
||||
│ │ │ ├── keycloak/ # Keycloak CR + public Ingress
|
||||
│ │ │ ├── keycloak-realm/ # KeycloakRealmImport (Git-managed realm/client)
|
||||
│ │ │ ├── storage/ # minio + VaultStaticSecret + certConfig FQDN patch
|
||||
│ │ │ └── test/ # test-server 1/2/3
|
||||
│ │ ├── components/forward-auth/ # dev overlay 에 포함되는 ForwardAuth component
|
||||
│ │ ├── staging/ # 의도적으로 비어둠
|
||||
│ │ └── prod/ # 의도적으로 비어둠
|
||||
│ │
|
||||
│ └── scripts/
|
||||
│ ├── bin/ # 사용자 진입점 (bootstrap.sh / teardown.sh)
|
||||
│ ├── ci/validate.sh # kustomize + kubeconform + kube-linter
|
||||
│ ├── lib/ # 공통 라이브러리 (common.sh / vault.sh)
|
||||
│ └── tasks/ # 재사용 작업 (vault-init / vault-seed-apps / vso-install)
|
||||
│
|
||||
└── terraform/ # contracts 만 존재, 추후 구현
|
||||
| Area | Owned resources |
|
||||
| --- | --- |
|
||||
| `gitops/apps/auth-server` | auth-server |
|
||||
| `gitops/apps/identity-postgres` | identity-postgres |
|
||||
| `gitops/apps/auth-migration` | versioned Flyway Job |
|
||||
| `gitops/platform` | Vault, Keycloak, MinIO, registry와 operator |
|
||||
| `gitops/platform/forward-auth` | oauth2-proxy와 Traefik ForwardAuth integration |
|
||||
|
||||
환경별 차이는 각 catalog의 `overlays/<env>`에 두고, rollout ownership은
|
||||
`gitops/clusters/<env>/<cluster>/stages`가 가집니다. 따라서 경로만 보고
|
||||
리소스 소유자와 실제 적용 단계를 구분할 수 있습니다.
|
||||
|
||||
## Deployment graph
|
||||
|
||||
```text
|
||||
namespaces
|
||||
|
|
||||
00-platform ---- cert-manager / Keycloak Operator / Traefik policy
|
||||
|
|
||||
+---- Helm: MinIO Operator / Vault Secrets Operator
|
||||
|
|
||||
10-vault ---- Vault Running -> init/unseal/policies/roles -> KV seed
|
||||
|
|
||||
20-secrets ---- VaultConnection / VaultAuth / pre-data VaultStaticSecret
|
||||
|
|
||||
30-data ---- PostgreSQL / MinIO / Keycloak
|
||||
|
|
||||
+---- MinIO registry bucket/access-key provisioning -> Vault
|
||||
|
|
||||
35-registry ---- registry VaultStaticSecret / docker-registry
|
||||
|
|
||||
40-operations ---- auth-server-migrate-0-1-0 / platform-realm-v1
|
||||
|
|
||||
50-apps ---- auth-server / oauth2-proxy / ingress
|
||||
```
|
||||
|
||||
## 네임스페이스 전략
|
||||
`all/`은 이 그래프를 하나로 렌더하지만 실행 순서를 보장하지 않습니다.
|
||||
따라서 validation 전용입니다.
|
||||
|
||||
`mnt` 단일 namespace. 학습 단계의 단순성 우선. 실무에서는 역할별 namespace(`auth`, `storage`, `security`, `registry`) 분리가 원칙이며, base 는 환경 중립이라 overlay 재구성으로 분리 가능하다.
|
||||
## Runtime boundaries
|
||||
|
||||
- Pod Security Standards: `pod-security.kubernetes.io/enforce=restricted` (audit + warn 동시).
|
||||
- 모든 리소스는 overlay 의 `namespace: mnt` 로 일괄 주입.
|
||||
| Workload | Kind | Namespace | Base |
|
||||
| --- | --- | --- | --- |
|
||||
| Vault | StatefulSet | `mnt` | `gitops/platform/vault` |
|
||||
| identity-postgres | StatefulSet | `mnt` | `gitops/apps/identity-postgres` |
|
||||
| MinIO | Tenant CR | `mnt` | `gitops/platform/minio` |
|
||||
| Keycloak | Keycloak CR | `mnt` | `gitops/platform/keycloak` |
|
||||
| docker-registry | Deployment | `mnt` | `gitops/platform/registry` |
|
||||
| auth-server | Deployment | `mnt` | `gitops/apps/auth-server` |
|
||||
| oauth2-proxy | Deployment | `mnt` | `gitops/platform/forward-auth` |
|
||||
| DB migration | Job | `mnt` | `gitops/apps/auth-migration` |
|
||||
| realm import | KeycloakRealmImport | `mnt` | `gitops/apps/keycloak-realm-import` |
|
||||
|
||||
## 워크로드 목록
|
||||
## One-shot operation contract
|
||||
|
||||
| 워크로드 | 종류 | 위치 | 참조 Secret |
|
||||
|---|---|---|---|
|
||||
| `identity-postgres` | StatefulSet | `base/app/identity/auth/stateful/` | `identity-postgres-superuser`, `keycloak-db`, `auth-server-db` |
|
||||
| [`auth-server`](https://github.com/donghyeon-ka/project-auth-server/tree/develop) | Deployment | `base/app/identity/auth/stateless/` | `auth-server-db` |
|
||||
| `keycloak` | Keycloak CR (Operator 생성 StatefulSet) | `overlays/dev/keycloak/` | `keycloak-db-operator`, `keycloak-bootstrap-admin-operator` |
|
||||
| `minio` | Tenant CRD | `base/app/storage/minio/stateful/` | `minio-tenant-env` |
|
||||
| `test-server-1/2/3` | Deployment | `base/app/test/stateless/` | — |
|
||||
| `migration-flyway` | Job (PreSync / sync-wave=-1) | `base/managing/migration-flyway/` | `auth-server-db` |
|
||||
| `vault` | StatefulSet | `base/plugins/vault/` | — |
|
||||
| `docker-registry` | Deployment | `base/plugins/docker-registry/` | `docker-registry-basic-auth`, `docker-registry-pull-credentials` |
|
||||
Flyway Job 이름은 migration release를 포함합니다:
|
||||
`auth-server-migrate-0-1-0`. SQL을 변경해 새 migration release를 만들 때는
|
||||
Job instance/name도 함께 올립니다. 같은 이름의 완료된 Job을 지웠다가
|
||||
묵시적으로 재실행하지 않습니다.
|
||||
|
||||
auth-server / keycloak 모두 `jdbc:postgresql://identity-postgres:5432/<db>` 로 short name 접속 (같은 namespace).
|
||||
KeycloakRealmImport도 `platform-realm-v1`처럼 versioned name을 씁니다.
|
||||
Operator는 기존 import CR의 spec 변경을 일반 workload rollout처럼
|
||||
재실행하지 않으므로, realm 변경은 새 version의 명시적 operation으로 냅니다.
|
||||
|
||||
### Flyway 실행 순서
|
||||
## Namespace decision
|
||||
|
||||
dev overlay 가 migration-flyway Job 에 ArgoCD annotation 을 patch:
|
||||
현재 lab은 `mnt` 단일 namespace입니다. 이는 운영 권장 구조가 아니라 기존
|
||||
runtime을 깨지 않고 먼저 deployment lifecycle을 분리하기 위한 전환 단계입니다.
|
||||
|
||||
```
|
||||
argocd.argoproj.io/sync-wave: "-1"
|
||||
argocd.argoproj.io/hook: PreSync
|
||||
```
|
||||
역할별 namespace 분리는 다음을 원자적으로 바꿔야 합니다.
|
||||
|
||||
ArgoCD 배포 시 Job 이 앱보다 먼저 돌고 스키마 마이그레이션을 마친 뒤 `auth-server` 가 뜬다.
|
||||
- Service DNS와 issuer/JWK/DB endpoint
|
||||
- Vault Kubernetes auth의 bound ServiceAccount/namespace
|
||||
- VSO destination Secret 위치
|
||||
- cross-namespace NetworkPolicy
|
||||
- Flyway와 DB init credential ownership
|
||||
- operator watch namespace와 RBAC
|
||||
|
||||
### Keycloak hostname patch
|
||||
따라서 단순 폴더 이동과 함께 수행하지 않습니다.
|
||||
|
||||
dev overlay JSON patch 가 Keycloak ConfigMap 에 다음을 주입:
|
||||
## Environment meaning
|
||||
|
||||
- `KC_HOSTNAME=https://keycloak.dev.example.com`
|
||||
- `KC_HOSTNAME_ADMIN=https://keycloak-admin.dev.example.com`
|
||||
|
||||
staging / prod 는 자체 hostname 을 overlay 에서 주입.
|
||||
|
||||
### MinIO certConfig.dnsNames
|
||||
|
||||
base 는 short name(`minio`, `minio-hl`) 만 둔다. dev overlay 에서 `minio.mnt.svc.cluster.local`, `*.minio-hl.mnt.svc.cluster.local` 을 patch — base 환경 중립성 원칙.
|
||||
|
||||
## 이미지 정책
|
||||
|
||||
| 구분 | 이미지 | 근거 |
|
||||
|---|---|---|
|
||||
| 공식 upstream | `hashicorp/vault:1.17.2` | HashiCorp 공식 |
|
||||
| | `registry:2.8.3` | Docker library 공식 |
|
||||
| | `postgres:16.4` | PostgreSQL 공식 |
|
||||
| | `quay.io/keycloak/keycloak:26.6.1` | Keycloak Operator 26.6.1 관리 |
|
||||
| | `minio/minio:RELEASE.2025-01-20T14-49-07Z` | MinIO 공식 |
|
||||
| | `flyway/flyway:10.20.1` | Flyway 공식 |
|
||||
| 사용자 개발 | `registry.example.com/auth-platform/auth-server:0.1.0` | 조직 개발 서비스 |
|
||||
| | `registry.example.com/test-platform/test-server-{1,2,3}:0.1.0` | 조직 개발 서비스 |
|
||||
|
||||
prod 승격 시 공식 이미지도 digest pin(`@sha256:…`)으로 전환.
|
||||
|
||||
## Docker Registry
|
||||
|
||||
| 항목 | 값 |
|
||||
|---|---|
|
||||
| 이미지 | `registry:2.8.3` |
|
||||
| 내부 서비스 | `docker-registry.mnt.svc.cluster.local:5000` |
|
||||
| 외부 Ingress | `registry.project.com` (`/v2` only) |
|
||||
| 인증 | 내부 Service 무인증, 외부 Ingress + kubelet pull 만 credential 사용 |
|
||||
| 저장 | MinIO S3 bucket `docker-registry` |
|
||||
|
||||
### 인증 경계
|
||||
|
||||
Registry 자체 auth 는 켜지 않는다. 인증 경계는 두 곳:
|
||||
|
||||
- 외부 Ingress: Traefik `Middleware/docker-registry-basic-auth` 가 VSO 로 생성된 `docker-registry-basic-auth` Secret 의 htpasswd 를 검증
|
||||
- 내부 pull: 앱 ServiceAccount 에 `docker-registry-pull-credentials` imagePullSecret
|
||||
|
||||
따라서 `docker-registry-ingress-traefik` NetworkPolicy + BasicAuth Secret + imagePullSecret 이 함께 있어야 push/pull 양쪽이 안전하다.
|
||||
- `lab`: 폐기 가능한 K3s 검증 환경. stateful overlay의 local-path, HTTP
|
||||
ingress, 단일 replica 허용.
|
||||
- `staging`: production과 같은 보안·TLS·backup path의 승격 검증 환경.
|
||||
- `prod`: HA, digest pin, backup/restore evidence, TLS, disruption budget가
|
||||
준비되지 않으면 생성하지 않습니다.
|
||||
|
||||
Reference in New Issue
Block a user