# Chart 개발 및 빌드 가이드 이 문서는 JupyterLab Helm chart의 구조와 템플릿 개발, 검증 방법을 설명합니다. ## 디렉토리 구조 ``` jupyterlab/ ├── Chart.yaml # 차트 메타데이터 ├── values.yaml # 기본값 정의 ├── custom-values.yaml # 환경별 override 예시 ├── README.md # 사용자 가이드 ├── CUSTOM-README.md # custom-values 작성 가이드 ├── BUILD-README.md # 이 파일 (개발/빌드 가이드) └── templates/ ├── _helpers.tpl # 재사용 헬퍼 함수 정의 ├── deployment.yaml # Deployment 리소스 ├── service.yaml # Service 리소스 ├── ingress.yaml # Ingress 리소스 ├── pvc.yaml # PersistentVolumeClaim 리소스 └── configmap.yaml # ConfigMap (startup-script.sh) ``` ## 템플릿 구조 설명 ### `_helpers.tpl` — 헬퍼 함수 | 함수 | 반환값 예시 | 설명 | |------|------------|------| | `jupyterlab.name` | `my-jupyter` | 릴리즈 이름 그대로 사용 | | `jupyterlab.configMapName` | `my-jupyter-scripts` | ConfigMap 이름 | | `jupyterlab.homePvcName` | `pvc-my-jupyter-home` | 홈 PVC 이름 | | `jupyterlab.dataPvcName` | `pvc-my-jupyter-data` | 데이터 PVC 이름 | | `jupyterlab.homeDir` | `/home/jovyan` | `homeVolume.mountPath` 또는 기본값 | | `jupyterlab.dataDir` | `/home/jovyan/data` | `/` | | `jupyterlab.labels` | (라벨 맵) | 공통 라벨 세트 | | `jupyterlab.image` | `quay.io/jupyter/scipy-notebook:latest` | 전체 이미지 참조. `repository`에 `:`가 있으면 `tag` 무시 | | `jupyterlab.command` | (bash 커맨드 배열) | JupyterLab 시작 커맨드 | ### `deployment.yaml` - `replicas`: `values.replicas` - 보안 컨텍스트: Pod 레벨 `runAsUser: 1000 / fsGroup: 100`, Container 레벨 `runAsUser: 0` - readinessProbe: `tcpSocket:8888`, 초기 30초 대기, 10초 주기, 27회 실패 허용 (총 ~5분) - 볼륨: `localtime`, `startup-script`, `dshm` (항상), `home-volume`, `data-volume`, `groupVolumes` (조건부) - `dshm`: RAM 기반 tmpfs를 `/dev/shm`에 마운트. PyTorch/NumPy 멀티프로세싱 시 기본 64MB 제한 해제 ### `configmap.yaml` startup-script.sh 내용: ```bash #!/bin/bash apt-get update -y python -m pip install --upgrade pip ``` 이 스크립트는 `/usr/local/bin/start-notebook.d/` 에 마운트되어 JupyterLab 시작 전 자동 실행됩니다. 추가 패키지 설치가 필요하면 이 파일을 수정하세요. ### `pvc.yaml` - `homeVolume.enabled: true` 일 때만 `pvc--home` 생성 - `dataVolume.enabled: true` 일 때만 `pvc--data` 생성 - `storageClassName`이 비어 있으면 클러스터 기본 StorageClass 사용 - PVC 보존 필요 시 주석 해제: `helm.sh/resource-policy: keep` ### `ingress.yaml` - `ingress.enabled: false` 이면 리소스 생성 안 함 - annotations는 `range`로 동적 주입 (Kong, cert-manager 설정 포함) - pathType은 `Prefix`로 고정 ## 개발 시 자주 쓰는 명령어 ### 렌더링 검증 ```bash # 전체 렌더링 출력 helm template my-jupyter . -f custom-values.yaml # 특정 리소스만 확인 helm template my-jupyter . -f custom-values.yaml | \ kubectl neat | grep -A50 "kind: Deployment" # values 병합 결과 확인 helm template my-jupyter . -f custom-values.yaml --debug 2>&1 | head -50 ``` ### Lint ```bash helm lint . -f custom-values.yaml ``` ### values 스키마 검증 (schema 파일 추가 시) ```bash helm template my-jupyter . -f custom-values.yaml --validate ``` ### 실 클러스터 dry-run ```bash helm install my-jupyter . \ --namespace jupyter \ --create-namespace \ -f custom-values.yaml \ --dry-run ``` ## 새 기능 추가 시 체크리스트 - [ ] `values.yaml`에 새 키와 기본값 추가 - [ ] `_helpers.tpl`에 필요한 헬퍼 함수 추가 - [ ] 해당 템플릿 파일에 조건부 블록으로 구현 (`{{- if .Values.xxx }}`) - [ ] `custom-values.yaml`에 예시값 반영 - [ ] `helm lint` 통과 확인 - [ ] `helm template` 렌더링 결과 확인 - [ ] `README.md` Values 테이블 업데이트 ## 자주 발생하는 오류 ### Error: YAML parse error `values.yaml`이나 `custom-values.yaml`의 들여쓰기 오류. `helm lint` 로 위치 확인. ### Error: template: jupyterlab/templates/xxx.yaml: ... nil pointer evaluating `values.yaml`에 존재하지 않는 키를 템플릿에서 참조할 때 발생. `_helpers.tpl`에서 `default` 함수 사용: ``` {{ .Values.some.key | default "fallback" }} ``` ### PVC Pending 상태 `storageClassName`이 클러스터에 없는 경우. `kubectl get storageclass` 로 사용 가능한 클래스 확인 후 설정. ### Pod CrashLoopBackOff startup-script.sh 오류 가능성 높음. `kubectl logs -n ` 로 스크립트 실행 로그 확인. ## Chart 버전 관리 `Chart.yaml`의 `version` 필드는 **SemVer** 규칙을 따릅니다. | 변경 유형 | 버전 업 | 예시 | |----------|---------|------| | 하위 호환 버그 픽스 | patch | `1.0.0` → `1.0.1` | | 새 기능 추가 (하위 호환) | minor | `1.0.0` → `1.1.0` | | 하위 비호환 변경 | major | `1.0.0` → `2.0.0` | `appVersion`은 JupyterLab 애플리케이션 버전을 나타내며, chart version과 별도로 관리합니다.