fix(setup): 실험대에서 35편을 끝까지 밟고 어긋난 명령·결과 31건을 고친다

test-server 를 비우고 다시 세운 뒤 Setup 기록 35편(virtualization 9 ·
keycloak-session-store 26)을 문서에 적힌 명령 그대로 쳤다. 어긋난 자리를
기록과 SSOT 양쪽에 실측과 함께 넣었다.

막히던 것
- 04 의 인증서 경로가 live/hyeonworks.com 이라 nginx 가 [emerg] 로 안 떴다.
  실제 계보는 live/auth.hyeonworks.com 이고 「문제가 생기면」은 진단이 거꾸로였다
- 인증서가 와일드카드가 아니다. SAN 이 auth·app1·app2 셋뿐이라 그 밖의 이름은
  TLS 에서 끊기고 curl 이 exit 60 · %{http_code} 000 을 낸다. SSOT 안에서
  두 문단이 서로 어긋나 있었다
- A-7 14번 ①이 kc-lab-1 에서 여섯 줄 다 실패하는데 마지막 date 만 「차단」을 찍는다

검사가 실패할 수 없던 자리
- B-1 의 세션 키 고르기는 앞 단계가 $KEY 를 채워 둬서 루프가 한 건도 못 맞혀도
  통과한다. KEY= 로 비우고 키마다 1/0 을 찍게 바꿨다
- k3s-agent 유닛의 sed -i 는 패턴에 $HOME 이 들어 있어 아무 줄도 안 바꾼 채 성공한다

certbot
- renew --dry-run 의 종료 코드는 성공도 0, 실패도 0, 다른 사유의 실패는 1 이다.
  본문의 renew failure(s) 로만 판정할 수 있다
- --dry-run 은 staging 서버를 쓰는데 renewal/*.conf 의 account= 는 운영 계정을
  가리킨다. 실패한 dry-run 이 staging 계정을 하나 더 만들어 다음 실행이 계속 멎는다
- 훅을 755 로 놓고 시뮬레이션이 성공해도 Running deploy-hook command 는 안 나온다.
  certbot 2.1.0 에는 --run-deploy-hooks 도 없다
- 강제 갱신은 실제로 쳤고 서빙까지 닿았다. serial 06F3E0EF…1373 → 065547…3DF1,
  notAfter Dec 3 → Dec 16, nginx worker 2629 4712 → 4745 4754

독자가 칠 수 있는 형태로
- 안 되는 형태가 번호 붙은 단계에 앉아 있던 8곳을 뒤집고, 되는 형태를 ①로 올렸다
- 랩 안에서 공개 이름을 치는 curl 65줄에 --resolve 를 붙였다. 붙인 형태를 실제로
  쳐서 문서가 적은 값과 같은지 확인했다
- 힙독·sed -i·echo >>·&&·|| 를 편집기 + 파일 리스팅 + 분할 형태로 바꿨다
- 닫는 코드펜스가 빠져 뒤 200여 줄의 블록 종류가 뒤집혀 있던 곳을 포함해 3곳을 고쳤다

관문: check_body PASS · check_prose error 0 · check_evidence 두 프로젝트 문제 없음 ·
verify-tech-log-tree error 0 · verify-project-layout error 0 · 코드펜스 전수 0건

남은 것: B-0 주입은 keycloak-pattern 저장소의 소스를 고치고 이미지를 다시 구워야
해서 안 했다(unknown).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
DongHyeonka
2026-09-17 19:38:12 +09:00
co-authored by Claude Opus 5
parent 4a457afde9
commit 32e39e20aa
150 changed files with 6066 additions and 269 deletions
@@ -0,0 +1,225 @@
K0=10.42.1.64 K1=10.42.0.29 PG=10.42.1.46
=== 주입 전에 flannel.1 에 무엇이 걸려 있나 ===
qdisc noqueue 0: root refcnt 2
=== 주입 ① 밴드 3개짜리 분류기 ===
exit=0
=== 주입 ② 3번 밴드에 200ms ===
exit=0
=== 주입 ③ 출발지가 postgres 인 패킷을 3번 밴드로 ===
exit=0
=== 주입 ④ 주입 시각 ===
17:56:37 주입
=== 주입 검증 ① 넣은 직후의 카운터 ===
qdisc prio 1: root refcnt 2 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc netem 30: parent 1:3 limit 1000 delay 200ms
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
=== 주입 검증 ② 요청을 한 번 보낸다 ===
1.855960
=== 주입 검증 ③ 다시 센다 ===
qdisc netem 30: parent 1:3 limit 1000 delay 200ms
Sent 1556 bytes 18 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
=== 관찰 1 ① 구간별 시간 (keycloak-1) ===
connect 0.000552 ttfb 1.864861 total 1.864966
=== 관찰 1 ② 20회 반복 — keycloak-1 ===
1.860758
1.870170
1.872980
1.876086
1.857782
1.859351
1.858796
1.860100
1.864847
1.874546
1.856623
1.870452
1.879456
1.867865
1.861147
1.861699
1.867978
1.862271
1.864539
1.857025
20회 평균 1865 ms 최대 1879 ms
=== 관찰 1 ③ 20회 반복 — keycloak-0 (대조군) ===
0.039154
0.043190
0.052382
0.037677
0.036750
0.037014
0.038348
0.035596
0.036738
0.038740
0.036093
0.040349
0.038105
0.040798
0.035273
0.042598
0.045344
0.038030
0.046025
0.034717
20회 평균 40 ms 최대 52 ms
=== 관찰 2 ① 동시 20건 ===
17:57:39 부하 시작
17:58:02 부하 끝
=== 관찰 3 ① 부하 직후에 읽는다 ===
agroal_blocking_time_max_milliseconds{datasource="default"} 20000.0
agroal_max_used_count{datasource="default"} 18.0
agroal_acquire_count_total{datasource="default"} 2020.0
agroal_active_count{datasource="default"} 0.0
agroal_awaiting_count{datasource="default"} 0.0
agroal_blocking_time_average_milliseconds{datasource="default"} 114.0
agroal_available_count{datasource="default"} 18.0
agroal_blocking_time_total_milliseconds{datasource="default"} 230680.0
=== 관찰 2 ② 다 모였는지부터 센다 ===
20 /tmp/load.txt
=== 관찰 2 ③ 원본을 본다 ===
200 1.889034
200 1.871238
200 1.967936
200 3.399275
200 4.813854
200 6.247018
200 7.652515
200 9.066673
200 10.495914
200 11.919137
200 13.326469
200 14.736787
200 16.159992
200 17.588220
200 21.854297
200 22.214107
200 22.207834
200 22.216690
200 22.245645
200 22.242271
=== 관찰 2 ④ 상태 코드와 시간을 나눠 본다 ===
20 200
1.871238
1.889034
1.967936
3.399275
4.813854
6.247018
7.652515
9.066673
10.495914
11.919137
13.326469
14.736787
16.159992
17.588220
21.854297
22.207834
22.214107
22.216690
22.242271
22.245645
=== 관찰 2 ⑤ 정렬 방식을 갈라 본다 — sort (사전순) ===
200 1.871238
200 1.889034
200 1.967936
200 10.495914
200 11.919137
200 13.326469
200 14.736787
200 16.159992
200 17.588220
200 21.854297
200 22.207834
200 22.214107
200 22.216690
200 22.242271
200 22.245645
200 3.399275
200 4.813854
200 6.247018
200 7.652515
200 9.066673
=== 관찰 2 ⑤ sort -g ===
200 1.871238
200 1.889034
200 1.967936
200 10.495914
200 11.919137
200 13.326469
200 14.736787
200 16.159992
200 17.588220
200 21.854297
200 22.207834
200 22.214107
200 22.216690
200 22.242271
200 22.245645
200 3.399275
200 4.813854
200 6.247018
200 7.652515
200 9.066673
=== 관찰 2 ⑥ sort -g -k2 ===
200 1.871238
200 1.889034
200 1.967936
200 3.399275
200 4.813854
200 6.247018
200 7.652515
200 9.066673
200 10.495914
200 11.919137
200 13.326469
200 14.736787
200 16.159992
200 17.588220
200 21.854297
200 22.207834
200 22.214107
200 22.216690
200 22.242271
200 22.245645
=== 관찰 4 ① 최근 이벤트 ===
57m Normal ScalingReplicaSet deployment/oauth2-proxy Scaled up replica set oauth2-proxy-d9b587458 from 0 to 1
57m Normal Pulled pod/oauth2-proxy-d9b587458-7x9jt Container image "quay.io/oauth2-proxy/oauth2-proxy:v7.7.1" already present on machine and can be accessed by the pod
57m Normal SuccessfulCreate replicaset/oauth2-proxy-d9b587458 Created pod: oauth2-proxy-d9b587458-7x9jt
57m Normal Created pod/oauth2-proxy-d9b587458-7x9jt Container created
57m Normal Started pod/oauth2-proxy-d9b587458-7x9jt Container started
57m Normal Created pod/oauth2-proxy-d9b587458-njxdw Container created
57m Normal Killing pod/oauth2-proxy-6c56c4c94f-gq484 Stopping container oauth2-proxy
57m Normal SuccessfulDelete replicaset/oauth2-proxy-6c56c4c94f Deleted pod: oauth2-proxy-6c56c4c94f-gq484
57m Normal Pulled pod/oauth2-proxy-d9b587458-njxdw Container image "quay.io/oauth2-proxy/oauth2-proxy:v7.7.1" already present on machine and can be accessed by the pod
57m Normal ScalingReplicaSet deployment/oauth2-proxy Scaled up replica set oauth2-proxy-d9b587458 from 1 to 2
57m Normal Started pod/oauth2-proxy-d9b587458-njxdw Container started
57m Normal SuccessfulCreate replicaset/oauth2-proxy-d9b587458 Created pod: oauth2-proxy-d9b587458-njxdw
57m Normal ScalingReplicaSet deployment/oauth2-proxy Scaled down replica set oauth2-proxy-6c56c4c94f from 2 to 1
57m Normal SuccessfulDelete replicaset/oauth2-proxy-6c56c4c94f Deleted pod: oauth2-proxy-6c56c4c94f-szr6j
57m Normal ScalingReplicaSet deployment/oauth2-proxy Scaled down replica set oauth2-proxy-6c56c4c94f from 1 to 0
57m Normal Killing pod/oauth2-proxy-6c56c4c94f-szr6j Stopping container oauth2-proxy
115s Normal Created pod/a6-probe Container created
115s Normal Pulled pod/a6-probe Container image "curlimages/curl:8.11.1" already present on machine and can be accessed by the pod
114s Normal Started pod/a6-probe Container started
19s Warning Unhealthy pod/keycloak-1 Readiness probe failed: Get "http://10.42.0.29:9000/health/ready": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
=== 관찰 4 ② 파드 상태 ===
NAME READY STATUS RESTARTS AGE
a6-probe 1/1 Running 0 115s
bff-5d97897676-nmlqs 1/1 Running 0 152m
bff-5d97897676-zvfhp 1/1 Running 0 152m
keycloak-0 1/1 Running 0 123m
keycloak-1 1/1 Running 0 123m
oauth2-proxy-d9b587458-7x9jt 1/1 Running 0 57m
oauth2-proxy-d9b587458-njxdw 1/1 Running 0 57m
postgres-7b474b88c8-48lrr 1/1 Running 0 162m
redis-f94bc6dbf-s674z 1/1 Running 0 125m
=== 관찰 5 ① 미검증 — 충돌 로그를 센다 ===
0
exit=1