fix(setup): Studio 편집기가 다시 쓰는 공백을 저장소에서 미리 맞춘다

Studio 의 블록 편집기는 본문을 화면에 풀 때 공백을 정규화한다. 이어진 빈 줄
둘을 하나로 줄이고, 닫는 코드펜스 뒤에 빈 줄이 없으면 하나를 넣는다. 저장된
값은 저장소와 바이트가 같지만, 사람이 편집 화면을 열고 저장을 누르는 순간
그 공백이 저장소와 갈린다 — 내용은 그대로인데 SHA 만 달라져서 어느 쪽이
정본인지 알 수 없게 된다.

setup 35편을 훑어 9편 11곳을 찾아 저장소 쪽을 편집기와 같은 모양으로 맞췄다.
빈 줄만 움직였고 내용 줄은 하나도 바꾸지 않았다(추가 2 · 삭제 9).

- 이어진 빈 줄 둘 → 하나: d4 · d4a(3곳) · a7 · b7a · c2 · b0 · tear-down
- 닫는 펜스 뒤 빈 줄 추가: c1 · create-three-guests

코드블록 안의 빈 줄과 frontmatter 는 건드리지 않았다.

관문: check_body PASS · check_prose error 0 · check_evidence 두 프로젝트 문제 없음 ·
verify-tech-log-tree error 0 · verify-project-layout error 0

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
DongHyeonka
2026-09-17 20:03:53 +09:00
co-authored by Claude Opus 5
parent da774648dc
commit bbd87dc9ab
9 changed files with 2 additions and 9 deletions
@@ -721,7 +721,6 @@ sudo certbot renew --force-renewal
결과는 `Congratulations, all renewals succeeded:` 였고 `certbot exit=0` 이었다. 배포 훅이 돌아 서빙하는 인증서까지 바뀌었는데, 그 대조는 D-4a 의 「엣지에서 다시 치고」 절에 있다 — 일련번호가 `06F3E0EF4D1BB03DE58130EAAD1176101373` 에서 `065547991777D11A408CEA90D945DDA03DF1` 로, `notAfter` 가 `Dec 3` 에서 `Dec 16` 으로 바뀜다.
## 주입 검증
「갱신 실패」와 「갱신은 됐는데 안 집었다」를 가르는 절이다. 이 실험은 처음에 이 둘을 구별하지 못해 두 갈래로 적어 뒀었다.
@@ -470,7 +470,6 @@ certbot exit=1
기본값 30초가 이 도메인에서는 아슬아슬하다. **한 번 실패했다고 설정이 틀린 것이 아니다** — 다시 쳐 보고, 계속 실패하면 `--dns-cloudflare-propagation-seconds` 를 올린다. 이 판의 종료 코드는 `1` 이었다 — 앞에서 본 대로 종료 코드는 사유마다 다르다.
**★ 더 나쁜 것은, 종료 코드가 실패를 일관되게 알려 주지 않는다는 점이다**(2026-09-17, observed). 같은 「전부 실패」 본문을 두 번 받았는데 한 번은 `0`, 한 번은 `1` 로 끝났다.
```bash label="[kc-lab-edge] 종료 코드를 따로 잡아서 본다"
@@ -616,10 +615,8 @@ app1 200 verify=0
app2 302 verify=0
```
**그리고 이것이 종료 코드 이야기를 닫는다.** 성공도 `0` 이고 앞의 첫 번째 실패도 `0` 이었다. 같은 명령이 돼을 때와 안 돼을 때 같은 값을 내므로, `$?` 로는 둔 경우를 가를 수 없다. 본문을 읽는 수밖에 없다.
## 관찰
### 9. 강제 갱신을 친다
@@ -1008,7 +1008,6 @@ postgres-7b474b88c8-t6rrf 1/1 Running 0 2m8s
**★ 마지막 줄의 `200` 은 이 실험대에서 안 나온다**(2026-09-17, observed). `auth.hyeonworks.com` 이 lab host 에서 `100.83.212.4` 로 풀리고 그 주소의 443 이 닫혀 있어 `000` 이 나온다. 엣지 주소를 짚으면 `200` 이고, 까닭은 A-6 의 같은 줄에 적었다. 나머지 여덟 줄은 이 실험대에서 그대로 통과했다 — args `["start"]`, `git diff` 출력 없음, 파드 둘 다 `1/1 Running`, postgres `1/1 Running`, 로그인 뒤 세션 행 `1`, 두 노드 `raw PREROUTING` 비어 있음, `vendor_cluster_size` 양쪽 `2`, 탐침 `NotFound`.
```bash label="[lab host] ⑧ 탐침 파드를 지운다"
kubectl -n keycloak-lab delete pod a7-probe --ignore-not-found
```
@@ -173,7 +173,6 @@ kubectl -n keycloak-lab exec deploy/redis -- redis-cli dbsize
`dbsize` 가 `0` 이고 스캔이 비었다는 것은 **Redis 는 멀쩡한데 엣지 세션이 하나도 없다**는 뜻이다. `oauth2-proxy` 가 안 떠 있으면 늘 이 모양이므로, 이 값을 보고 「Redis 가 안 붙었다」로 읽지 않는다.
**어디를 보나** — 실측은 이렇다(observed, `01-orphan-lifecycle.txt`).
```text
@@ -272,6 +272,7 @@ kubectl -n keycloak-lab rollout status statefulset/keycloak --timeout=300s
```text
No server specified. Use --server, or 'kcadm.sh config credentials'.
```
그러니 롤아웃이 끝나는 대로 주입 전 2 절의 `config credentials` 를 다시 친다. 건너뛰면 뒤에 나오는 `kcadm` 이 전부 `401` 을 내는데, 그 사실은 관찰 1 절에 가서야 보인다.
```bash label="[lab host] ④ 두 저장소를 다시 센다"
@@ -576,7 +576,6 @@ curl -s -o /dev/null -w 'app1 %{http_code}\n' https://app1.hyeonworks.com/
| `HTTP 200` | 실제로 닿는다 |
| `HTTP 000` | curl 이 연결조차 못 했다 = 네트워크가 원인 |
**★ 지금 배치에서는 주소가 다르고, 닿는 까닭도 다르다**(2026-09-17, observed). 판정(`200`)은 같은데 `nslookup` 이 내놓는 주소가 `100.83.212.4` 가 아니라 엣지 게스트의 `192.168.122.10` 이다.
```text label="탐침 파드에서 받은 그대로"
@@ -857,7 +857,6 @@ exit=0
**앞서 적어 둔 「남은 것은 인증서 하나」는 해결됐다**(2026-09-17, observed). 호스트에 있던 인증서를 엣지 게스트로 옮기고 강제 갱신까지 치면서 `https://auth.hyeonworks.com` 은 선다. 지금 남은 걸림돌은 소스 쪽 하나다.
## 무엇이 관측이고 무엇이 아닌가
이 절차의 숫자는 `2026-09-04 13:3913:46 KST` 에 돈 한 번의 실행에서 나왔다(observed).
@@ -596,6 +596,7 @@ sudo grep -n "packages" /var/lib/cloud/instance/user-data.txt
```text label="그 출력"
19:packages: [curl, nftables]
```
- (observed) `virsh vol-info` · `net-dumpxml --inactive` · `cloud-init status --long` 은 2026-09-17 에 쳤다. 볼륨 일곱의 용량과 실제 할당은 이렇다 — **선언한 크기와 디스크가 실제로 먹는 양이 크게 다르다.** 오버레이라 쓴 만큼만 먹는다.
```text
@@ -182,7 +182,6 @@ scp kc-lab-edge:/tmp/letsencrypt-backup-*.tgz ~/
**「철거해도 남는 것」 표의 패키지 줄도 같은 이유로 틀렸다.** 그 줄은 `nginx` 와 `certbot` 을 남는 쪽에 적어 두었는데, 둘 다 게스트 안에 있으므로 게스트와 함께 사라진다. 랩 호스트에 남는 것은 `libvirt` · `qemu` · `kubectl` 과, 쓰이지 않는 호스트 쪽 `certbot` 이다.
`/etc/letsencrypt/` 는 정책으로 남긴다. 한도 때문이 아니다 — Let's Encrypt 의 「같은 이름 조합에 주당 중복 5장」 제한은 가끔 재구축하는 정도로는 근처에도 못 간다.
남기는 까닭은 지금 재발급이 되는지를 모르기 때문이다. 이 실험대의 이름 셋은 tailnet 주소를 가리키고, `100.64.0.0/10` 은 CGNAT(Carrier-Grade NAT, 통신사 공용 주소 변환)용 예약 대역이라 공개 인터넷에서 라우팅되지 않는다. HTTP-01 검증은 Let's Encrypt 가 우리 서버로 들어오는 방식이므로 그 주소로는 검증이 성립하지 않는다. 지금 설정이 DNS-01 이면 지우고 다시 받으면 끝이고, HTTP-01 이면 검증 방식부터 손봐야 한다. 어느 쪽인지는 certbot 설정을 읽는 열린 물음이 한 줄로 닫는다.