--- title: daily-task / infra / {{slug}} source_type: daily-task track: infra status: raw status_label: not-started difficulty: intermediate duration_estimate: 120 prerequisites: [] parent_project: ca-skeleton-operational-contract parent_branch: target_date: YYYY-MM-DD created: YYYY-MM-DD tags: [daily-task, infra] # 트랙 구분은 폴더 경로 + frontmatter `track:` 가 SSOT. # `infra` 는 L3 Domain 태그 (운영/인프라 영역 검색용). 추가 tag 는 도메인별 (예: `observability`, `kubernetes`) 0~2개. --- # daily-task / infra / {{slug}} > Layer: `raw/daily-tasks/infra/` — **인프라 / 운영 트랙 일일 실습 과제**. 사수가 신입에게 주는 형식의 자율 운영 과제. 매일 아침 1개 수행. > `status_label`: `not-started` | `in-progress` | `done` | `abandoned` > `difficulty`: `starter` (도구 처음) | `intermediate` (기본 흐름 익숙) | `advanced` (장애 / 트레이드오프 / SLO 탐구) > `duration_estimate`: 분 단위. 기본 120분. develop 트랙과 달리 *대기 시간 (apply / probe / metric 수렴)* 이 포함됨에 유의. > > **체계 근거**: 본 template 구조는 두 raw 자료로 정당화된다 — 9-section anchor 는 vendor-normative 가이드 (`[[raw/company-tech-blogs/skillable-hands-on-lab-structure]]`), 단계 분할·자기평가·회고 원리는 deliberate-practice 개인 블로그 (`[[raw/company-tech-blogs/deliberate-practice-software-developers-redgreencode]]`) 기반. 두 자료 모두 *공식 best practice 가 아니다*. > > **develop 트랙과의 차이**: §3 환경은 *작업 host + target cluster + kubeconfig context*, §5 단계는 *manifest 작성 → apply → 관측 → 롤백 drill* 흐름, §6 검증은 *kubectl / promql / log query / smoke test*, §7 결과물은 *applied manifest + dashboard URL + alert rule + runbook stub*, §11 운영 회복력 anchor 추가. ## 부모 (필수) - **Parent project**: `[[raw/project-notes/ca-skeleton-operational-contract]]` (또는 해당하는 다른 project-note — 예: 사용자 인프라 개요) - **연관 branch** (선택, 있을 때만): `[[raw/branch-notes/{{branch-slug}}]]` > 본 과제가 어느 작업 묶음에 속하는지 명시. parent 없는 과제는 금지. ## 1. 학습 목표 > 3-5개 측정 가능 목표. "이 과제 끝났을 때 다음을 *할 수 있어야* 한다" 형식. 인프라 트랙은 *관측 / 진단 / 롤백* 동사를 의식적으로 섞을 것. > 근거: `[[raw/company-tech-blogs/skillable-hands-on-lab-structure]]#SKILL-LAB-C1`. - [ ] L1: <동사로 시작 (예: "Spring Boot actuator `/actuator/health/readiness` 를 k8s readinessProbe 로 연결하고 의도적 DB 단절 시 not-ready 가 30초 안에 노출됨을 prometheus 로 확인할 수 있다")> - [ ] L2: <...> - [ ] L3: <...> ## 2. 스토리라인 > *왜* 이 인프라 작업이 필요한가. 실무 운영 시나리오 1-2 문단. SLO / 장애 / 비용 anchor 가 자연스럽다. > 근거: `[[raw/company-tech-blogs/skillable-hands-on-lab-structure]]#SKILL-LAB-C2` (storyline 없으면 "clicking things"). (예시: "현재 ca-tmpl staging cluster 의 readiness probe 는 항상 200 을 반환하는 `/health` 를 본다. 즉 DB unavailable 이어도 pod 가 ready 로 표시돼 트래픽이 흘러 5xx 가 양산된다. 오늘은 readiness 를 `health/readiness` 로 분리하고 DB connection failure 시 *unhealthy* 가 30초 내에 표면화되는지, kube-state-metrics + prometheus 로 확인한다.") ## 3. 환경 > 작업 호스트 · 대상 시스템 · 도구 버전 · context. > 근거: `[[raw/company-tech-blogs/skillable-hands-on-lab-structure]]#SKILL-LAB-C1` (Prospective environment + Technologies used). **작업 호스트**: - 로컬 macOS / Linux / WSL2 — <명시> **대상 환경**: - Cluster: - Namespace: - Kubeconfig context: <명시> **도구 버전**: - `kubectl`: - `helm`: <3.15> - `docker` / `podman`: <24.x> - (Optional) `terraform`, `kustomize`, `k9s`, `stern`, `kubectx`: <버전> - 관측: Prometheus , Grafana <11.x>, Loki / OpenTelemetry collector <버전> **사전 셋업**: ```bash # context 전환 확인 kubectl config current-context kubectl get ns # 작업 디렉토리 cd ~/workspace/ca-tmpl-infra git checkout -b daily-task/infra/{{slug}} # 현재 상태 스냅샷 (롤백 reference) kubectl get all -n -o yaml > /tmp/snapshot-pre-{{slug}}.yaml ``` **변경 예정 리소스**: - `` — <어떤 변경> ## 4. 사전 지식 > 알아야 할 개념·결정·운영 규약. - `[[wiki/concepts/]]` — <왜 필요한지> - `[[raw/project-notes/ca-skeleton-operational-contract]]` — <§N (e.g., §15 runtime/lifecycle) 인용> - `[[raw/official-docs/]]` — <인용할 claim> ## 5. 단계별 과제 > *Manifest 작성 → apply → 관측 → 롤백 drill* 의 자연스러운 흐름. 각 단계 25분 ± 대기시간. infra 는 *apply 후 metric 수렴* 같은 비-CPU 대기가 있으니 시간 추정에 포함. > 근거: `[[raw/company-tech-blogs/deliberate-practice-software-developers-redgreencode]]#DP-RGC-C2` (slightly higher than current), `#DP-RGC-C5` (25-min Pomodoro 권고 시작점). ### 베이스라인 측정 (~20min) - **What**: 변경 전 상태를 *수치* 로 기록. metric / log / probe 응답. - **How (hint)**: `kubectl get` / `kubectl describe` / promql query / log grep - **Done when**: 베이스라인 수치 3개 이상이 본 노트 §7 에 기록됨 ### 설정 작성 (~30min) - **What**: <변경할 manifest / Dockerfile / helm values / actuator config> - **How (hint)**: 어떤 field 가 핵심인가, 어떤 default 를 override 해야 하는가 - **Done when**: 로컬 lint 통과 (`kubectl apply --dry-run=server -f ...`), diff 검토 완료 ### Step 3: Apply + 관측 (~25min, 대기 포함) - **What**: 실제 apply 후 *수렴 시간* 측정 + 의도된 동작 확인 - **How (hint)**: `kubectl rollout status`, prometheus `up{job=...}`, alert 발화 여부, `kubectl logs --previous` - **Done when**: 의도된 metric / probe 변화가 promQL 로 확인 가능 ### 롤백 drill (~25min) - **What**: 본 변경의 *실패 모드* 를 의도적으로 발생 → 자동 복구 또는 수동 롤백 검증 - **How (hint)**: chaos (e.g., DB 단절, pod kill, network delay), 또는 rollback 명령 직접 실행 - **Done when**: 시스템이 알려진 상태로 복귀 + 사후 metric / log 정상 ### 대시보드 작성 (~20min) - **What**: 본 변경을 관측하는 alert rule + grafana panel - **How (hint)**: PromQL recording rule, alert threshold, runbook link - **Done when**: alert rule lint 통과, dashboard JSON commit > *단계 갯수 권고*: starter=3, intermediate=4-5, advanced=5+chaos. 총 시간은 frontmatter `duration_estimate` 와 일치. ## 6. 검증 > 인프라 검증 = *명령 + metric + log + probe* 4가지 채널 중 ≥2개 교차 확인. 단일 채널만 의존 금지. > 근거: `[[raw/company-tech-blogs/skillable-hands-on-lab-structure]]#SKILL-LAB-C4` (immediate feedback), `[[raw/company-tech-blogs/deliberate-practice-software-developers-redgreencode]]#DP-RGC-C3` (objective standard). **자동 검증** (각 명령 + 합격 기준): ```bash # 1) Probe / health curl -fsS http://:/actuator/health/readiness # 합격 기준: HTTP 200 + status: UP # 2) k8s 리소스 상태 kubectl rollout status deployment/ -n --timeout=60s # 합격 기준: deployment 가 successfully rolled out # 3) PromQL — 의도된 metric 수렴 # 예: 1분 평균 readiness probe success rate # promql: avg_over_time(probe_success{job="kubernetes-pods"}[1m]) # 합격 기준: 변화 시점이 기대 시간 ± 10초 내 # 4) Log 검증 kubectl logs deployment/ -n --tail=200 | grep -E '' # 합격 기준: 의도된 log entry 발견 (또는 *없어야 할* line 부재) # 5) Smoke test (해당 시) ./scripts/smoke-test.sh # 합격 기준: exit code 0 ``` **수동 self-check**: - [ ] 위 4-5개 명령 중 ≥2 채널이 교차 확인됨 - [ ] 의도적 실패 시 정확히 의도된 alert 가 발화 (Step 4 결과) - [ ] 롤백 명령으로 *완전히* 베이스라인으로 복귀 가능 (Step 1 수치와 일치) - [ ] L1~L3 학습 목표가 실제로 수행 가능한 상태 - [ ] manifest commit 메시지가 "왜" 를 답함 ## 7. 결과물 > 인프라 트랙 산출물 = *applied manifest + 측정값 + dashboard / alert + runbook stub*. > 근거: `[[raw/company-tech-blogs/skillable-hands-on-lab-structure]]#SKILL-LAB-C1`. - **commit / PR**: - 브랜치: `daily-task/infra/{{slug}}` - commits: <해시 + 1줄> - PR URL (있다면): - **변경된 manifest / 설정**: - `` — <역할 한 줄> - **측정값** (§5 Step 1 베이스라인 vs Step 3 적용 후): - : before=<값> → after=<값> - **Dashboard / Alert**: - Grafana panel URL: <또는 JSON path> - Alert rule: - **Runbook stub** (이 변경으로 새 alert 가 생겼다면): - 알람 발생 시 1차 확인: <명령 1-2줄> - 즉시 fail-fast / degrade 가능 분류: <명시> - **학습한 개념** (wiki/concepts 로 ingest 후보): - **다음 과제 thread**: ## 8. 회고 > 빈 회고 = 학습 손실. 인프라 트랙은 *측정값 vs 예상* 의 괴리를 특히 기록. > 근거: `[[raw/company-tech-blogs/deliberate-practice-software-developers-redgreencode]]#DP-RGC-C4`. - **막혔던 곳** (몇 분 / 어디서 — apply 대기 / probe timing / metric label mismatch 등): - **예상과 다른 점** (가정이 깨진 부분 — 수렴 시간 / probe 동작 / cluster 자동 동작): - **다음 반복에서 개선할 점**: - **부수 효과로 발견한 것** (의도 외 metric / log / 이벤트): - **이 과제의 난이도가 적정했는가** (frontmatter `difficulty` 조정 신호): ## 9. 출처 | Source | 정당화 영역 | |---|---| | `[[raw/company-tech-blogs/skillable-hands-on-lab-structure]]` | template 9-section 구조 자체 | | `[[raw/company-tech-blogs/deliberate-practice-software-developers-redgreencode]]` | §5 단계 분할 + §6 objective 평가 + §8 reflection | | `[[raw/official-docs/<...>]]` | 도메인 근거 (Spring actuator / k8s probe / Prometheus / Grafana 등) | | `[[raw/project-notes/ca-skeleton-operational-contract]]` | 본 과제가 검증하려는 운영 계약 §N | ## 10. 완료 후 정리 - **최종 status_label**: `done` | `abandoned` - **소요 시간 실측**: <분> (vs frontmatter `duration_estimate`) — 차이는 §8 회고에 - **promotable 후보**: - `actually-implemented` → 어느 운영 계약 §N 과 연결되는지 - `locally-verified` → 어떤 명령으로 검증됐는지 - `prod-verified` → (해당 시) 운영 환경 검증 시점 + 로그/측정값 reference - **추출하지 않을 항목** (단순 학습 / 실험 / 폐기): ## 11. 운영 회복력 > develop 트랙에 *없는* infra 트랙 전용 anchor. 본 과제가 시스템 회복력에 어떤 영향을 주는지 명시. - **본 변경이 도입하는 새 실패 모드**: - **새 실패 모드의 fail-fast vs degrade 분류**: - **모니터링 누락 위험** (이 변경 후 *못 보게 되는* metric/log): - **롤백 트리거 조건** (어떤 측정값이 어떤 임계치 초과 시 롤백): - **연관 alert / runbook** (`[[raw/project-notes/ca-skeleton-operational-contract]]#28` Operational Runbook 와의 정합):