- JavaScript 75.8%
- Python 14.1%
- Shell 4.4%
- HTML 2.5%
- Go 1.2%
- Other 2%
에이전트 툴의 로컬 상태 디렉터리라 추적 대상이 아니다. 기존에는 .claude/settings.local.json 한 파일만 막아 lock 파일 때문에 git status 에 미추적으로 계속 노출됐다. CLAUDE.md 는 루트에 있어 영향받지 않는다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| _reports | ||
| ai/llm-stack/menifests | ||
| app_works/pseudo | ||
| build | ||
| databases/postgresql-ha | ||
| deployments_inspector | ||
| development | ||
| integrated_checker | ||
| k8s_upgrade_checker | ||
| observability | ||
| productivity | ||
| sidecars | ||
| sql_engines | ||
| .gitattributes | ||
| .gitignore | ||
| CLAUDE.md | ||
| README.md | ||
cloud_native
사내 Kubernetes 클러스터(hd-cluster, k8s v1.35.x / Rocky Linux 9.7 / containerd 2.x / Calico / Rook-Ceph) 위에서 동작하는 Cloud-Native 워크로드 모음 저장소.
각 디렉터리는 하나의 운영 단위(StatefulSet/Deployment/Operator 등)를 담으며, 매니페스트·이미지 빌드 자산·운영 문서·운영 스크립트를 함께 둡니다.
Claude Code 로 작업할 때는 CLAUDE.md 를 함께 참고하세요 — 배포 스크립트 세대 차이, sed 구분자 함정 등 이 README 에 없는 함정이 정리되어 있습니다.
Repository Layout
cloud_native/
├── build/ # 원격 이미지 빌드 하네스 (이 저장소 공통)
├── databases/ # postgresql-ha
├── sql_engines/ # mpp/trino, proxy/shardingsphere
├── sidecars/ # healthz, collector
├── development/ # vscode, image_builder
├── productivity/ # guacamole, portainer, drawio, nextcloud, redmine
├── observability/ # kube-state-metrics, yarn-jmx-exporter
├── integrated_checker/ # 통합 점검 웹앱
├── k8s_upgrade_checker/ # 노드 업그레이드 점검 (CLI + 웹)
├── deployments_inspector/ # 매니페스트 검증기 (Go)
├── app_works/ # pseudo
└── ai/ # llm-stack
컴포넌트 디렉터리 구조 (신규 기준)
Dockerfile 은 컴포넌트당 하나입니다. online/closed 는 Dockerfile 을 나누지 않고 files/ 를
어떻게 채우느냐로만 구분합니다. 그래야 두 환경의 결과물이 규율이 아니라 구조적으로 같아집니다.
<group_or_kind>/<application>/
├── build/
│ ├── Dockerfile # 단 하나. 네트워크를 쓰지 않고 files/ 에서만 설치
│ ├── files/ # COPY 대상 = 착지점(landing zone)
│ │ ├── rpms/ # 바이너리·패키지 → gitignore (반입 또는 fetch.sh 가 채움)
│ │ ├── scripts/ # 추적됨 (소스)
│ │ └── conf/ # 추적됨 (소스)
│ ├── online/
│ │ └── fetch.sh # 네트워크로 files/ 를 채움
│ └── closed/
│ └── MANIFEST # 반입 목록 + sha256 체크섬
├── manifests/ # raw K8s 매니페스트 (__NAMESPACE__ 토큰, numbered prefix)
├── helm/ # Helm chart — manifests 와 동일 레벨
└── README.md # 컴포넌트별 운영 매뉴얼
빌드 흐름은 양쪽이 같고, files/ 를 채우는 앞단만 다릅니다.
# 온라인
bash build/online/fetch.sh && docker build -f build/Dockerfile build/
# 폐쇄망 (MANIFEST 대로 반입한 뒤)
sha256sum -c build/closed/MANIFEST && docker build -f build/Dockerfile build/
- Dockerfile 안에서 네트워크를 쓰지 않습니다.
dnf install <pkg>,curl,pip install <pkg>가 들어가는 순간 폐쇄망에서 깨지고 online 결과물과 갈립니다. 설치는 전부files/산출물로 합니다. closed/MANIFEST는 항상 만듭니다 (선택 아님). 반입 대상과 체크섬을 여기에 남기며,fetch.sh가 받는 대상과 일치해야 합니다.- 바이너리·패키지는 저장소에 넣지 않습니다.
.gitignore가 차단하며,files/아래라도scripts/·conf/텍스트 파일은 추적됩니다. 빈 디렉터리는.gitkeep으로 유지합니다. - compact / full 같은 변형은 디렉터리를 늘리지 말고
--build-arg나 멀티스테이지--target으로 처리합니다. Dockerfile 을 복제하는 순간 갈라집니다. - 결과물이 "동일"하다는 것은 내용·버전의 동일을 뜻합니다. 이미지 digest 까지 같아지지는 않습니다.
manifests/와helm/은 비어 있을 수 있습니다. 모든 컴포넌트가 K8s 에 배포되는 것은 아니지만 (CLI 도구, 단독 바이너리 등) 구조 일관성을 위해 디렉터리는 항상 생성합니다.- 기존 컴포넌트 다수는 컴포넌트 루트에
Dockerfile하나를 두는 옛 구조입니다. 임의로 마이그레이션하지 않습니다.
Components
범례 — 상태: 운영 운영 중 · 검증 운영 검증 중 · 도입 신규 도입 · scaffold 미완성 골격
databases/
| 컴포넌트 | 상태 | 버전 | 설명 |
|---|---|---|---|
| postgresql-ha | 검증 | PostgreSQL 16.13 | Lease 기반 Active-Standby StatefulSet (replicas=2), pg_rewind→pg_basebackup 폴백, 주간 논리 백업. raw + Helm 등가 제공. NodePort 30111/30112 |
sql_engines/
| 컴포넌트 | 상태 | 버전 | 설명 |
|---|---|---|---|
| mpp/trino | 운영 | Trino 479 | coordinator(Deployment, replicas=1) + worker(StatefulSet, replicas=3, HPA min=2/max=10), TLS + 파일 기반 password authenticator, NGINX HTTPS Ingress, PostgreSQL 카탈로그 2종. ns databases, NodePort 30143/30180 |
| proxy/shardingsphere | scaffold | 미지정 | 매니페스트 3개(namespace/configmap/secret)만 존재. 워크로드 리소스 미작성 |
sidecars/
| 컴포넌트 | 상태 | 설명 |
|---|---|---|
| healthz | 도입 | Python 3.13 / FastAPI 사이드카. uvicorn 2개 동시 구동 — 9001(self, liveness) / 9000(target, readiness). 메인 컨테이너의 process/TCP/HTTP 관측. Native sidecar 패턴(initContainer + restartPolicy: Always) + shareProcessNamespace: true 전제. scripts/validate.py 로 매니페스트 정합성 검증 |
| collector | 도입 | Rocky Linux 9 기반 단일 이미지에 exporter 19종 번들 — alloy, fluent_bit, node, mysqld, postgres, kafka, mongodb, redis, rabbitmq, oracledb, ceph, squid, blackbox, process, jmx, snmp, elasticsearch, nginx, sql. /opt/<name>/ 에 배치하고 Pod command 로 entrypoint 를 지정해 배포 시점에 선택. deploy.sh 는 ConfigMap 만 적용하며 사이드카는 30-sidecar-snippet.yaml 참고해 워크로드에 직접 부착 |
development/
| 컴포넌트 | 상태 | 버전 | 설명 |
|---|---|---|---|
| vscode | 도입 | code-server 4.103.0 | Debian 13(trixie) 기반 커스텀 이미지 — Python 3.13 / Node.js 22 / Temurin JDK 21 / Docker CLI / kubectl 1.35 / Helm v3 / yq, Claude Code · OpenAI Codex CLI 사전 설치, ko_KR.UTF-8 · Asia/Seoul, 비루트 coder(UID 1000) + sudo. ns development, NodePort 30880 (haedong 단일 사용자) |
| image_builder | 도입 | 0.1.0 | 이미지 빌드 + Deployment 롤아웃 웹앱 (Flask + gunicorn). Registry/Repository 등록, Dockerfile 편집→build→push, rollout restart/set image, 빌드 이력(SQLite). Docker socket 마운트 필요. ns development, NodePort 30088 |
productivity/
| 컴포넌트 | 상태 | 버전 | 설명 |
|---|---|---|---|
| guacamole | 도입 | Guacamole 1.6.0 / PostgreSQL 17 | 클라이언트리스 원격 데스크톱 게이트웨이. guacamole + guacd + postgres 3-Deployment 구성, raw + Helm 제공. ns guacamole, NodePort 30280 |
| portainer | 도입 | Portainer CE 2.27.3 | 컨테이너 관리 UI (Deployment replicas=1). ns portainer, NodePort 30290(HTTP) / 30291(Edge) |
| drawio | 도입 | drawio 24.7.17 | 다이어그램 편집기 (Deployment replicas=1, ClusterIP). ns 는 kustomization.yaml 의 namespace: 로 조절. 이미지는 kustomize images: 트랜스포머로 주입 |
| nextcloud | 도입 | Nextcloud 30 (apache) | 파일 공유·협업. nextcloud + mariadb 11.4 + redis 7.4-alpine. ns nextcloud 고정. 디렉터리명이 menifests 오타, deploy.sh 없음. Dockerfile 은 30-apache 인데 매니페스트는 stable-apache 참조 — 불일치 |
| redmine | 도입 | Redmine 6.0 / PostgreSQL 16 | 이슈 트래커. 플러그인 3종(redmine_drawio 1.5.4, redmine_mermaid 1.0.0, redmine_login_audit2 1.0.0) 내장. git_mirror(Rocky 9.7 기반 Git 미러링 데몬, 0.1.0)와 한 쌍으로 ns redmine 배포. 이미지는 __IMAGE__ 토큰(redmine) / kustomize images:(git_mirror). deploy.sh 없음 |
observability/
| 컴포넌트 | 상태 | 버전 | 설명 |
|---|---|---|---|
| kube-state-metrics | 도입 | KSM 2.15.0 | K8s 오브젝트(node/pod/deployment/PVC) 상태 메트릭을 Prometheus 로 노출. 상용 이미지 전용(Dockerfile 없음). ns monitoring, ClusterIP |
| yarn-jmx-exporter | 도입 | 0.1.0 (자체) | Hadoop YARN ResourceManager/NodeManager 의 /jmx 를 스크레이프해 Prometheus 메트릭으로 변환. ns monitoring, ClusterIP |
점검 도구 (checker/inspector)
| 컴포넌트 | 상태 | 설명 |
|---|---|---|
| integrated_checker | 도입 | 통합 점검 웹 대시보드 (Flask). K8s 클러스터 / Linux OS / HTTP 헬스 / YAML 스키마 / 이미지 빌드 5개 모듈을 탭으로 통합, 모듈별 의존성 없으면 "unavailable" 로 degrade. ns monitoring, NodePort 30090 |
| k8s_upgrade_checker | 도입 | 워커 노드 업그레이드 전후 상태 스냅샷/비교/복구. CLI(k8s-upgrade-check.py --snapshot|--compare|--restore) + Flask 웹 래퍼 한 쌍. 폐쇄망 대응으로 stdlib + kubectl/helm 서브프로세스만 사용 |
| deployments_inspector | 도입 | K8s 매니페스트 검증기 (Go, CGO_ENABLED=0 정적 링크). YAML 문법 + 들여쓰기/CRLF/BOM + 40여 필드 타입 검사. kubeconform 있으면 스키마 검증, 없으면 내장 규칙 폴백. CLI(standalone_inspector) + 웹(inspector_web) 한 쌍. 매니페스트·Dockerfile 없음 — 바이너리 배포 |
app_works/
| 컴포넌트 | 상태 | 설명 |
|---|---|---|
| pseudo | 도입 | FastAPI 백엔드 커넥션 풀 관리 API. YAML 설정 2개(common_config.yaml, resources_config.yaml) 기반, uvicorn 멀티워커 + graceful SIGTERM, cashews 캐시(디스크 폴백), request-id 미들웨어 |
ai/
| 컴포넌트 | 상태 | 설명 |
|---|---|---|
| llm-stack | scaffold | ollama 0.5.12 + open-webui v0.8.6 + litellm + PostgreSQL. 디렉터리명이 menifests 오타, deploy.sh·README 없음 |
범용성 요구사항
이 저장소의 산출물은 현재 운영 중인 hd-cluster 전용이 아닙니다. 이미지와 매니페스트는
전혀 다른 환경(다른 클러스터·스토리지·레지스트리)에서도 구동돼야 합니다. 폐쇄망 반입을
전제하는 프로젝트이므로 이식성이 곧 납품 가능성입니다.
환경 의존값은 하드코딩하지 않습니다.
| 항목 | 금지 | 대신 |
|---|---|---|
| 네임스페이스 | namespace: drawio |
__NAMESPACE__ 토큰 |
| 레지스트리 | 레지스트리 호스트 직접 기입 | __IMAGE__ 토큰 |
| StorageClass | block-sc-retain (Rook-Ceph 전용) |
미지정(기본 SC) 또는 주입 |
| IngressClass | nginx 고정 |
주입 가능하게 |
| NodePort | 고정 포트 | 기본 ClusterIP, NodePort 는 선택 |
| 토폴로지 | 노드 라벨·taint·affinity 가정 | 가정하지 않기 |
접근성 요구(RWX 필요 등)는 명시하되 구현(CephFS)에 묶지 않습니다.
아래 "사전 환경 요건"은 운영
hd-cluster기준 참고값입니다. 요구사항이 아니라 현재 검증된 환경의 서술로 읽으세요. 현황과 미준수 항목은 정리 대상 참조.
사전 환경 요건 (운영 hd-cluster 기준 참고값)
- Kubernetes 클러스터: v1.30+ 권장 (운영 hd-cluster 는 v1.35.x)
- StorageClass (Rook-Ceph 기준, 모두
allowVolumeExpansion: true):block-sc-delete— RBD, default, reclaimPolicy=Delete (임시/캐시)block-sc-retain— RBD, reclaimPolicy=Retain (영속 데이터, DB)filesystem-sc— CephFS, RWX, reclaimPolicy=Retain (공유/백업)
- IngressClass:
nginx(NodePort 30080/30443) — 외부는 Nginx Proxy Manager 가 TLS 종료 + 호스트 라우팅 - 사내 컨테이너 레지스트리: 같은 Harbor 의 두 이름 — 내부
harbor.nova.office(노드 pull) / 외부harbor.coxspace.biz(외부 push) kubectlv1.30+,helmv3 (Helm chart 사용 시)- 폐쇄망 또는 NetworkPolicy 통제 환경 (외부 노출 제한 필수)
이미지 빌드
빌드·배포·컴파일은 전부 외부 서버에서 수행합니다. 기본 대상은 haedong@192.168.2.1(build-97)이며,
개발 컨테이너(code-server)에서는 수행하지 않습니다 — docker 데몬도, 클러스터/내부 레지스트리 접근 경로도 없습니다.
cd build
./remote-build.sh --list # 등록된 빌드 대상
./remote-build.sh --dry-run vscode # 실행될 명령만 출력
./remote-build.sh --no-push drawio # 빌드만
./remote-build.sh vscode # 빌드 + push
- 대상 등록:
build/components.tsv에 한 줄 추가 - 태그:
harbor.coxspace.biz/<project>/<name>:YYYYMMDDHHmm+:latest(UTC)
자세한 내용은 build/README.md 참고.
배포
deploy.sh/build.sh는 참고용 레퍼런스입니다. 스크립트가 수행하는 절차를 문서화한 것이며, 실 운영 배포는 수동 커맨드로 처리합니다.
⚠️ deploy.sh 인터페이스가 3종으로 갈립니다
컴포넌트마다 호출 규약이 다르므로 참고할 때 해당 파일을 먼저 확인하세요.
Type A — 서브커맨드 + 영속 render (postgresql-ha, trino, collector)
./scripts/deploy.sh render <namespace> [output_dir]
./scripts/deploy.sh apply <namespace>
./scripts/deploy.sh delete <namespace>
Type B — ACTION 을 kubectl 에 그대로 전달 (image_builder, integrated_checker, pseudo)
./scripts/deploy.sh <apply|delete> [namespace]
render 를 넘기면 kubectl render 가 되어 실패합니다.
Type C — 환경변수 구동, 인자 없음, 즉시 apply (vscode, portainer, guacamole, yarn-jmx-exporter, kube-state-metrics)
NAMESPACE=development ./scripts/deploy.sh
IMAGE_TAG=0.1.0-20260508 NODEPORT=30290 ./scripts/deploy.sh
노출된 삭제 경로가 없습니다.
drawio, nextcloud, redmine, healthz, shardingsphere, llm-stack 은 deploy.sh 가 없어 kubectl apply -f 를 직접 씁니다.
Helm
cd <category>/<component>
helm install <release> ./helm -n <namespace> --create-namespace
helm upgrade <release> ./helm -n <namespace>
Chart 보유: databases/postgresql-ha, development/vscode, productivity/guacamole,
sidecars/collector/manifests/helm, sidecars/healthz/manifests/helm (뒤 둘은 manifests/ 아래).
두 방식의 결과 리소스명은 동일하게 설계되어 전환 시 충돌이 없습니다(Helm 메타데이터 라벨은 차이 있음). 다만 등가성을 검사하는 자동화 도구는 없으므로 한쪽을 고치면 반대쪽도 수동으로 맞춰야 합니다.
검증
저장소에 테스트 프레임워크나 린트 설정은 없습니다. 유일한 검증 도구는 매니페스트 정합성 검사기입니다.
cd sidecars/healthz && python3 scripts/validate.py [manifests_dir] # 기본: manifests/samples
# 종료코드: 0 정상 / 1 오류 / 2 매니페스트 없음
YAML 문법, ConfigMap 로더 왕복, volume↔volumeMount·targetPort↔containerPort·selector↔label 교차 참조, Pod 불변식을 검사합니다. PyYAML 외 의존성 없음.
NodePort 할당 현황
| 포트 | 컴포넌트 |
|---|---|
| 30071, 30077 | ai/llm-stack (pgsql, open-webui) |
| 30080, 30443 | ingress-nginx (클러스터 공용) |
| 30088 | image_builder |
| 30090 | integrated_checker |
| 30111, 30112 | postgresql-ha |
| 30143, 30180 | trino |
| 30280 | guacamole |
| 30880 | vscode (haedong) |
신규 컴포넌트는 30000번대에서 위와 충돌하지 않는 포트를 선택합니다.
컨벤션
- 이미지 태그:
harbor.coxspace.biz/library/<project>/<name>:<version>+:latest<project>세그먼트는 운영 네임스페이스/Harbor project 와 정렬하며 디렉터리 카테고리에서 유도하지 않습니다. 예:sql_engines/mpp/trino→library/databases/trino
- 매니페스트 토큰:
__NAMESPACE__(공통),__IMAGE__,__NODEPORT__,__<NAME>_PASSWORD__등을sed로 치환 (envsubst 미사용) - 파일명 번호: 두 규칙이 공존 —
NN_연속증가(구세대: postgresql-ha, trino, pseudo, image_builder) /NN-10단위(신세대: vscode, portainer, guacamole, drawio). 기존 컴포넌트는 그 디렉터리 방식을 따르고, 신규는NN-10단위 사용 - 네임스페이스: 컴포넌트별 분리 (
databases,development,monitoring,guacamole,portainer, …) - 라벨:
app=<component-name>, 역할 분리는role=<value> - 파일 인코딩: UTF-8 (BOM 없이) / 줄 끝: LF (
.gitattributes강제) - 커밋 메시지: Conventional Commits (
feat:/fix:/docs:/chore:/refactor:) + 한국어 본문 - 시크릿:
*.key,*.pem,*.p12,*.pfx,.env,secrets/,kubeconfig—.gitignore차단. 매니페스트의 비밀값은__PLACEHOLDER__토큰으로 두고 deploy.sh 가openssl로 생성 주입하거나 Sealed-Secrets / SOPS / External-Secrets-Operator 사용
정리 대상 (Known Issues)
레지스트리 혼재— 오해였음.harbor.nova.office(내부 직결)와harbor.coxspace.biz(프록시 바깥)는 같은 Harbor 의 안/밖 이름. 노드 pull 은 내부, 외부에서의 push 는 외부 이름을 쓴다 — 통일 대상이 아님범용성 위반 (하드코딩)— 정리 완료 (아래 "범용성 요구사항" 참조)- StorageClass 22곳 → 미지정(클러스터 기본 SC). RWX 볼륨은 경고 주석 명시
- IngressClass 7곳 →
__INGRESS_CLASS__토큰 (INGRESS_CLASS, 기본nginx) - 네임스페이스 → kustomize 계열은
kustomization.yaml의namespace:로, 나머지(ai/llm-stack,redmine)는__NAMESPACE__토큰으로 단일화
menifests오타 디렉터리 —productivity/nextcloud/menifests,ai/llm-stack/menifests- deploy.sh 인터페이스 3종 분기 — 하나로 통일 필요
- 미완성 —
sql_engines/proxy/shardingsphere(워크로드 없음),ai/llm-stack(README·deploy.sh 없음),deployments_inspector(Dockerfile·매니페스트 없음)
라이선스 / 책임
사내 운영 자산. 외부 공개 금지.
Sources
- 프로젝트 가이드라인: CLAUDE.md, build/README.md
- 컴포넌트 README: databases/postgresql-ha, sql_engines/mpp/trino, sidecars/healthz, sidecars/collector, development/vscode, development/image_builder, productivity/guacamole, productivity/portainer, observability/kube-state-metrics, observability/yarn-jmx-exporter, k8s_upgrade_checker
- 외부 참조:
- Kubernetes v1.35 docs: https://kubernetes.io/docs/home/
- Rook-Ceph: https://rook.io/docs/rook/latest/Getting-Started/intro/
- ingress-nginx: https://kubernetes.github.io/ingress-nginx/
- Trino docs: https://trino.io/docs/current/
- PostgreSQL 16: https://www.postgresql.org/docs/16/
- Helm chart template guide: https://helm.sh/docs/chart_template_guide/