기록 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>
6.3 KiB
6.3 KiB
kind, slug, title, topic, topicName, project, status, questionStatus, sourceRevision, source, evidence
| kind | slug | title | topic | topicName | project | status | questionStatus | sourceRevision | source | evidence | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| QUESTION | does-the-renewal-timer-actually-renew | 갱신 타이머가 실제 갱신에서도 도는가 | operations-that-report-success | 운영 절차의 완료 판정 — 백업 · 판올림 · Secret · 인증서 갱신 | keycloak-session-store | 게시 전 | OPEN | cdac9b8178391311d8eca1ebc6cac15bb62d79af |
|
|
갱신 타이머가 실제 갱신에서도 도는가
deploy 훅은 강제 갱신으로만 검증했고, 타이머가 스스로 갱신하는 날도 그 훅이 도는지는 재지 않았다. 만료 30일 전에야 조건이 성립해 약 59일 뒤에나 시험할 수 있다. 그때까지 타이머는 매번 SUCCESS 를 찍는다.
관계
- 새 인증서가 디스크에 있고 38분 25초 동안 옛 인증서가 나갔다 이 질문이 나온 결함이다. reload 를 부르는 경로가 셋 다 비어 있었다.
- deploy 훅 하나가 그 공백을 1~2초로 줄였다 그 훅을 강제 갱신으로만 시험했고, 타이머 경로는 남겨 두었다.
사실
- certbot-renew.timer 는 하루 두 번 도는 일정으로 잡혀 있다. RandomizedDelaySec : 12h Persistent : true
- 2026-09-04 에 그 타이머가 두 번 돌았고 둘 다 status=0/SUCCESS 로 끝났다.
- 같은 날 서빙 인증서는 만료까지 88일 남아 있었다. 두 번의 SUCCESS 는 갱신을 하지 않은 채 끝난 것이다.
- certbot 의 인증서 상태 출력이 남은 일수를 VALID: 89 days 로 찍었다. 89일은 만료까지 남은 일수다. 다만 그 출력은 D-4 의 강제 갱신이 만든 인증서를 본 것이고, D-4a 가 다시 받은 인증서에 대해서는 같은 출력이 증거에 없다. 두 장은 만료 시각이 다르다. certbot 은 30일 남았을 때 갱신하므로 갱신 조건은 약 59일 뒤에 성립한다.
- D-4 에서 새 인증서가 디스크에 기록된 시각과 실제 서빙이 바뀐 시각 사이가 2305초, 38분 25초 비었다. 그 사이 428회 관측했다.
- 그때 reload 를 건 것은 사람이었다. certbot-renew.service 에 ExecStartPost 가 없었고 renewal-hooks 의 deploy · post · pre 세 디렉터리가 다 비어 있었으며 certbot 의 nginx 플러그인도 없었다.
- D-4a 에서 deploy 훅 하나를 넣고 강제 갱신하자 갱신에서 서빙까지가 1~2초로 줄었다.
- 누가 reload 를 걸었는지는 워커 프로세스 번호(PID)로 갈린다. 사람이 걸었을 때 28829, 훅이 걸었을 때 37252 였고 마스터 585 는 그대로였다.
- 훅이 돌 때 certbot 은 Hook 'deploy-hook' ran with error output 을 찍었다. 실패는 아니었고 nginx 의 types_hash 경고가 stderr 로 나간 것이며 내용은 test is successful · signal process started 였다.
가정
- 타이머가 스스로 갱신하는 경로도 같은 certbot renew 를 부르고 같은 deploy/ 훅을 실행한다. 이 실험대의 기록이 그렇게 판단했고, 그 판단대로라면 남은 미지수는 타이머가 뜨는가 하나이며 그것은 D-4 에서 확인됐다. 훅 실행까지 같다는 부분은 실행으로 확인하지 않았다.
- 갱신일까지 아무도 이 호스트의 타이머 유닛과 훅 파일을 건드리지 않는다.
미지수
- 타이머가 실제 갱신을 수행하는 날에도 deploy/ 훅이 도는가. 이 실험대가 훅을 확인한 경로는 --force-renewal 하나뿐이다.
- --dry-run 에서 Running deploy-hook command 줄이 나오는가. 강제 갱신으로 바로 검증하는 바람에 dry-run 경로 자체를 거치지 않았다.
- 훅이 실제로 실패하면 certbot 이 무엇을 찍는가. 성공한 훅의 출력만 봤다.
- 훅이 /tmp 에 로그를 남기도록 만들면 타이머가 돌렸을 때 그 파일을 밖에서 찾을 수 있는가. certbot-renew.service 는 PrivateTmp=true 이고, 이 실험은 훅에 로그를 넣지 않았다.
제약
- 만료 30일 전에야 갱신 조건이 성립하므로 실제 갱신은 약 59일 뒤다. 다만 기다리는 것 말고도 이 실험대가 적어 둔 길이 하나 있다 — certbot renew --dry-run 은 인증서를 발급하지 않고 발급 한도도 깎지 않으면서 훅이 호출되는지까지는 보여 준다.
- 강제 갱신으로는 이 질문에 답할 수 없다. 그 경로는 D-4a 에서 이미 검증했고, 지금 묻는 것은 타이머가 스스로 도는 경로다.
- deploy 훅 파일은 지우지 않고 남긴다. 지우면 D-4 의 상태로 돌아간다.
- 발급 한도가 있다. 강제 갱신을 쓸 때는 이번 주에 몇 장 발급했는지 센다.
선택지
갱신일이 와야 끝까지 시험할 수 있지만 그 전에 고를 수 있는 것이 하나 있다.
certbot renew --dry-run 을 먼저 돌려 훅이 호출되는지만 본다 : 발급도 한도 소모도 없다. 다만 실제 갱신에서 훅이 무엇을 받는지까지는 답하지 않는다. 이 실험대는 이 줄을 미검증으로 표시했고 돌리지 않았다.
약 59일을 기다렸다가 실제 갱신을 본다 : 이 질문에 온전히 답하는 유일한 경로다.
다음 검증
약 59일 뒤, 만료 30일 전 조건이 성립해 타이머가 갱신을 수행한 날에 두 가지를 읽는다.
- nginx 워커의 lstart 를 읽어 갱신 시각 근처인지 본다. 마스터는 그대로이고 워커만 새것이어야 한다.
- 서빙 인증서의 serial 과 notAfter 를 읽어 notAfter 가 밀렸는지 본다.
판정은 이 둘로 한다. certbot 이 찍는 문구로는 갈리지 않는다 — D-4a 에서 ran with error output 은 실패가 아니었다.
닫는 조건 : 워커 PID 가 바뀌고 서빙 일련번호가 새 인증서와 같으면 닫는다. 그렇지 않으면 훅이 강제 갱신에서만 도는 것이므로 타이머 유닛 쪽에 훅을 다시 건다.