No description
  • JavaScript 75.8%
  • Python 14.1%
  • Shell 4.4%
  • HTML 2.5%
  • Go 1.2%
  • Other 2%
Find a file
newshure a59cb18295 chore: .claude/ .moai/ 를 gitignore 에 추가
에이전트 툴의 로컬 상태 디렉터리라 추적 대상이 아니다.
기존에는 .claude/settings.local.json 한 파일만 막아 lock 파일 때문에
git status 에 미추적으로 계속 노출됐다.

CLAUDE.md 는 루트에 있어 영향받지 않는다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-15 15:51:23 +09:00
_reports docs: add pseudo API operation manual 2026-05-20 14:20:21 +09:00
ai/llm-stack/menifests refactor(portability): 레지스트리 하드코딩 제거 2026-09-15 08:49:48 +09:00
app_works/pseudo refactor(portability): 레지스트리 하드코딩 제거 2026-09-15 08:49:48 +09:00
build fix(build): remote-build.sh 가 빌드 실패를 성공으로 보고하던 문제 2026-09-15 09:08:19 +09:00
databases/postgresql-ha refactor(portability): 레지스트리 하드코딩 제거 2026-09-15 08:49:48 +09:00
deployments_inspector feat: add deployments_inspector (K8s manifest YAML inspector) 2026-06-01 15:41:05 +09:00
development fix(vscode): seed 가 확장 버전을 비교해 이미지 쪽이 높으면 교체하도록 수정 2026-09-15 13:48:14 +09:00
integrated_checker refactor(portability): 레지스트리 하드코딩 제거 2026-09-15 08:49:48 +09:00
k8s_upgrade_checker docs: K8s Upgrade Checker README 추가 2026-06-10 10:52:00 +09:00
observability docs: 저장소 가이드라인·원격 빌드 하네스 추가 및 README 현행화 2026-09-15 08:03:19 +09:00
productivity docs: 워크스페이스 경로를 /home/coder → /home/haedong 으로 정정 2026-09-15 13:43:15 +09:00
sidecars refactor(portability): 레지스트리 하드코딩 제거 2026-09-15 08:49:48 +09:00
sql_engines refactor(portability): 레지스트리 하드코딩 제거 2026-09-15 08:49:48 +09:00
.gitattributes Initial commit: cloud_native monorepo bootstrap with postgresql-ha 2026-05-08 09:01:38 +09:00
.gitignore chore: .claude/ .moai/ 를 gitignore 에 추가 2026-09-15 15:51:23 +09:00
CLAUDE.md docs: 워크스페이스 경로를 /home/coder → /home/haedong 으로 정정 2026-09-15 13:43:15 +09:00
README.md docs: 빌드·배포·컴파일은 전부 외부 서버에서 수행함을 명시 2026-09-15 09:09:51 +09:00

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)
  • kubectl v1.30+, helm v3 (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