기록 84편을 계약 에이전트로 다시 썼다. 기존 71편(kss 25 · virt 46)과, 계약에만 있고 안 쓰여 있던 새 글감 13편이다. 원장 84개를 열어 단계마다 스킬 영수증과 관문 종료 코드를 적었고 verify-pipeline-run.py 가 error 0 으로 닫는다. SSOT 결함 둘을 고쳤다. - kss 의 `약 58일` 이 반입 중 `약 59일` 로 바뀌어 있었다. 원 증거 파일이 「남은 일수: 88일 … 실제 갱신까지 약 58일」로 산수를 직접 적는다. D-4a 쪽 `약 59일` 은 강제 갱신 뒤(`VALID: 89 days`)라 맞는 값이라 그대로 뒀다. - virt §198 의 `11.6GB` 는 §178 의 원 측정 `Mem: 11648`(MiB)과 어긋나는데 원 가이드의 표기 그대로라 고치지 않고 쓰이는 자리에 대조를 적었다. 기록의 수치 오류 셋을 고쳤다 — CASE 요약의 「게스트 셋에 8240MB」(5120+3120 은 둘이다), k3s 편이 같은 것을 여섯·일곱·여덟로 세던 것, no-docker 편의 「셋을 더 든다」(§281 의 표는 네 행이고 디스크 행이 빠져 있었다). 계약을 셋 고쳤다. - kss 의 sourceRepository 리비전이 cdac9b8 이었는데 그 커밋에는 docs/guides/** 28개가 아예 없다. 9465582b 로 바꾸고, 반입한 바이트가 어느 커밋과도 같지 않다는 것을 측정값과 함께 적었다 — 반입은 커밋이 아니라 그 시점의 작업 트리에서 떠 온 것이다(kss 297/306 · virt 12/14 가 작업 트리와 같고, 200 커밋을 거슬러 전수 대조했을 때 가장 가까운 커밋도 28개가 어긋났다). - virt 계약이 「2026-09-11 재배분」이라고 적는데 SSOT 는 재배분 날짜를 적지 않고 재배분 뒤 값은 이미 2026-09-10 측정에 찍혀 있다. - kss 후보 대장이 지나친 절 아홉에 처분을 적었다(warn 9 → 0). 새 글감은 0건이고 넷은 앵커가 h3 슬러그의 접두가 아니라 중간 토막이라 검사기가 못 본 것이었다. style_profile.mjs 의 결함 둘을 고쳤다 — frontmatter 가 문장으로 세어져 (실측 398자짜리 「문장」 하나) 평균 길이를 기준 안으로 밀어 올리고 있었고, engPerSent 의 분자는 목록을 포함한 글에서, 분모는 목록을 걷어낸 글에서 세고 있었다(Question 기록에서 11.94 → 3.86). verify-pipeline.py 전 항목 PASS · error 0 · unittest 334건 OK. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
실습 가이드 — 직접 쳐보면서 만드는 실험대
이 문서 묶음은 읽는 문서가 아니라 따라 치는 문서다. 기존
experiment-*.md 가 「무엇을 발견했나」를 적었다면, 여기는
「그 발견을 재현하려면 무엇을 어떤 순서로 치는가」를 적는다.
두 종류의 명령을 구별해 적는다
실무자가 터미널에서 치는 명령과, 근거를 남기려고 재는 명령은 길이도 목적도 다르다. 이 가이드는 둘을 섞지 않는다.
| 표시 | 무엇인가 |
|---|---|
| 하기 · 확인 | 실무자가 실제로 치는 형태. 짧고, 한 번에 하나씩 |
| 근거를 재려면 | 이 실험대가 문서에 남기려고 쓴 긴 형태. 평소에는 필요 없다 |
예를 들어 nginx 에러 로그가 잘렸을 때, 실무자는 잘린 걸 보고 access 로그로 넘어간다. 길이를 재서 2048인지 확인하는 것은 몰라서 재는 것이고, 알면 재지 않는다.
같은 이유로 curl 도 두 형태가 있다.
curl -I https://auth.hyeonworks.com/realms/master # 한 번 볼 때
curl -s -o /dev/null -w '%{http_code}\n' <url> # 여러 번 재서 비교할 때
이 가이드의 확인은 값을 대조해야 해서 두 번째 형태를 자주 쓴다. 실제로 터미널에서 눈으로 볼 때는 첫 번째로 충분하다.
자리표시자를 두지 않는다
<토큰> 처럼 적어 두면 그 값을 어디서 가져오는지가 문서 밖으로 나간다.
이 가이드는 값을 찾는 명령을 함께 적는다.
TOKEN=$(ssh kc-lab-1 'sudo cat /var/lib/rancher/k3s/server/node-token')
echo "${#TOKEN} 자" # 값이 아니라 길이만 확인한다
비밀은 길이나 존재 여부만 확인하고 값을 찍지 않는다. 터미널 스크롤백과 화면 공유에 남기 때문이다.
어느 기계에서 치는가
이 실험대에는 셸이 네 개 있고, 같은 명령이 어디서 도느냐에 따라 결과가 달라진다. 그래서 모든 코드 블록 앞에 어디서 치는지를 붙인다.
| 표시 | 어느 기계 | 어떻게 들어가나 |
|---|---|---|
[워크스테이션] |
평소 쓰는 개발 머신 | — |
[lab host] |
test-server. virsh 가 도는 곳 |
ssh test-server |
[kc-lab-edge] |
엣지 게스트 — nginx · certbot | ssh kc-lab-edge (lab host 에서만) |
[kc-lab-1] |
k3s server 게스트 | ssh kc-lab-1 (lab host 에서만) |
[kc-lab-2] |
k3s agent 게스트 | ssh kc-lab-2 (lab host 에서만) |
기본은 [lab host] 다. 게스트는 libvirt NAT(192.168.122.0/24) 안에
있어서 워크스테이션에서 직접 닿지 않는다. ssh kc-lab-1 이라는 별칭도
lab host 의 ~/.ssh/config 에만 있다.
[워크스테이션] $ ping -c1 192.168.122.11
1 packets transmitted, 0 received, 100% packet loss # 경로가 없다
게스트 안에 들어가서 다음 단계를 치지 않는다. 게스트에는 lab host 의
개인키도 ~/.ssh/config 도 없으므로, 게스트 안에서 ssh kc-lab-1 을 치면
이렇게 끝난다.
[kc-lab-1] $ ssh kc-lab-1 'sudo cat /var/lib/rancher/k3s/server/node-token'
Host key verification failed.
이 실패가 조용한 이유 — 위 명령을 TOKEN=$(...) 로 감싸면 오류는
stderr 로 흘러가고 TOKEN 에는 빈 문자열이 담긴다. 셸은 아무 불평도
하지 않는다. 그래서 게스트에 로그인한 채 다음 단계를 치면 몇 단계 뒤에
가서야 증상이 나타난다.
그래서 이 가이드는 게스트에 로그인하지 않고 lab host 에서
ssh kc-lab-1 '...' 형태로 원격 실행한다. 셸이 하나뿐이면 「지금 어디
있더라」가 생기지 않는다.
순서
앞 단계가 끝나야 다음이 된다. 각 단계 첫머리에 「이 단계가 끝나면」이 있고, 그 상태를 확인하는 명령이 있다. 그것이 통과해야 다음으로 넘어간다.
| 단계 | 무엇을 세우나 | 끝나면 확인되는 것 |
|---|---|---|
| 00 | lab host 가상화 준비 | virsh list 가 돈다 |
| 01 | VM 세 대 (엣지 + k3s 2노드) | 세 게스트에 SSH 가 붙는다 |
| 02 | k3s server + agent | kubectl get nodes 에 둘 다 Ready |
| 03 | 엣지 nginx 라우팅 + 호스트 DNAT | 밖에서 요청이 파드까지 닿는다 |
| 04 | Let's Encrypt | https:// 가 열리고 체인이 4단계 |
| 05 | Keycloak 2노드 + PostgreSQL | 관리 콘솔 로그인이 된다 |
| 06 | Prometheus · Grafana | vendor_cluster_size 가 2 |
| experiments | 실험 26건 | 각 실험의 판정 기준 |
이 가이드가 검증된 방식
읽기 전용 확인은 돌아가는 실험대에서 실제로 실행해 출력을 그대로 실었다. 버전·IP·메모리 같은 값은 지어내지 않았다.
만드는 명령은 다르다. VM 을 다시 만들거나 k3s 를 다시 깔면 지금 돌고 있는 실험대가 없어지므로, 그 명령들은 실제로 구축할 때 쓴 것을 그대로 옮겼고 결과 상태를 확인하는 것으로 대신했다. 어느 쪽인지 각 단계에 표시한다.
막혔을 때
각 단계 끝에 「막히면」 표가 있다. 거기 적힌 증상은 전부 이 실험대가
실제로 겪은 것이고, 원문은 ../evidence/ 에 있다.
지어낸 실패 사례는 없다.