Files
document-haness/docs/virtualization/tech-log-studio/lab-environment-build/reference/reference-a-config-file-does-not-mean-the-same-thing-on-two-distros.md
T
DongHyeonkaandClaude Opus 5 2109f726fe feat(pipeline): keycloak-session-store 25편·virtualization 59편을 S3→S5→S6 으로 돌린다
기록 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>
2026-09-17 11:01:55 +09:00

8.2 KiB

kind, slug, title, topic, topicName, project, status, sourceRevision, source
kind slug title topic topicName project status sourceRevision source
REFERENCE a-config-file-does-not-mean-the-same-thing-on-two-distros 같은 설정 파일이 두 배포판에서 같은 뜻이 아니다 — 옮기기 전에 세 가지를 본다 lab-environment-build 실험대 환경 구성 virtualization 게시 전 9465582b5d1630eb4ae7c4e078021486919bf6b6
final/document.md#203-실측으로-드러난-함정-셋
final/document.md#284-nginx-설정-구조-sites-available-은-nginx-기능이-아니다
final/document.md#288-게스트-배포판-debian이란-무엇이고-ubuntu와-무엇이-다른가
final/document.md#286-패키지명-대응표
final/document.md#287-없어서-오히려-편한-것
final/document.md#285-롤링-릴리스와-부분-업그레이드-금지
final/document.md#212-"이건-arch라서-하는-건가-"에-대한-답
final/document.md#209-nginx-keycloak-lab-conf-스티키-스위치와-신뢰-경계

같은 설정 파일이 두 배포판에서 같은 뜻이 아니다 — 옮기기 전에 세 가지를 본다

설정 파일을 배포판이 다른 기계로 옮기기 전에 셋을 본다. 그 지시어가 대상의 판올림에 있는가, 패키지가 기본으로 켜 둔 것과 충돌하지 않는가, 그 배포판이 그 관례를 갖고 있는가. 이 실험대의 함정 셋이 전부 여기 걸렸다.

관계

  • 단계별 구축 문서는 작성 시점이 아니라 실행 순서로 검증한다 그 기준은 순서와 위치를 보고 이 기준은 대상 기계를 본다. 그 기록이 자기 예외 절에서 배포판 차이를 이쪽으로 넘긴다.
  • 엣지 게스트에 nginx 를 세우고 호스트 DNAT 으로 밖에서 들어오는 길을 연다 Arch 호스트에서 쓰던 nginx 설정이 Debian 12 게스트로 건너가는 절차가 그 기록에 있다.
  • cloud-init 시드로 게스트 세 대를 만들고 SSH 가 키로 붙게 한다 부트 시점 설정이 게스트 판올림의 검사기를 통과해야 하는 대목이 그 절차 안에 있다.
  • cloud-init 이 안 도는 원인은 넷인데 증상은 「SSH 가 안 붙는다」 하나였다 원인이 옮긴 파일 안에 없을 때 증상이 어떻게 보이는지를 그 기록이 보여 준다.
  • 가까운 층부터 한 층씩 건너뛰며 확인한다 — 층마다 성공 신호가 다르다 증상이 난 층부터 좁혀 오는 절차이고, 이 기준은 그 층에 닿은 뒤 파일을 의심할지 기계를 의심할지를 가른다.

목적

이 기준이 막는 것은 원인이 파일 안에 없는 두 증상이다. 하나는 설정 전체가 뜨지 않는 것이고, 다른 하나는 파일을 제자리에 놓았는데 아무 일도 일어나지 않는 것이다. 둘 다 파일을 아무리 읽어도 나오지 않는다.

§203 이 실측으로 드러난 함정 셋을 적었는데 셋 다 배포판 차이였다. 이 실험대는 호스트가 Arch(nginx 1.30.4)이고 엣지 게스트가 Debian 12(nginx 1.22.1)라 같은 설정이 두 판올림 사이를 오갔다.

규칙

1. 그 지시어가 대상의 판올림에 있는가

http2 on; 은 nginx 1.25.1 이상이다. Arch 에서 쓰던 설정을 Debian 12 게스트로 그대로 옮기면 unknown directive "http2" 가 나면서 설정 전체가 죽는다.

없다는 것을 확인하는 데서 멈추면 규칙이 답을 내지 않는다. 양쪽에서 도는 형태가 무엇인지까지 찾는다. listen 443 ssl http2; 형태는 1.22 와 1.30 양쪽에서 다 돈다.

설정 정본 deploy/lab/edge/nginx-keycloak-lab.conf 의 주석이 그 형태를 고른 까닭을 파일 안에 적어 두었다. 따로 떼어 쓰는 지시어 쪽은 nginx 1.25.1 이상을 요구하는데 엣지 게스트는 nginx 1.22 를 쓰는 Debian 12 다. listen 의 인자로 쓰는 형태는 양쪽에서 다 돌고, 이 실험대가 실제로 돌리는 것도 그쪽이다.

2. 패키지가 기본으로 켜 둔 것과 충돌하지 않는가

Debian 계열은 /etc/nginx/sites-enabled/default 가 처음부터 붙어 있고 :80default_server 로 선언돼 있어서, 실험대 설정의 listen 80 default_server 와 충돌한다. 심볼릭 링크를 걸 때 그 기본 사이트를 같이 지운다.

3. 그 배포판이 그 관례를 갖고 있는가

sites-availablesites-enabled 는 nginx 의 기능이 아니라 Debian/Ubuntu 패키지 메인테이너가 만든 관례다. nginx 가 아는 것은 include 지시어 하나뿐이고 나머지는 패키지가 미리 깔아 둔 디렉터리 구조다.

Arch 는 /etc/nginx/nginx.conf 한 파일이 전부이고 include 줄도 없다. http { } 안에 include /etc/nginx/sites-enabled/*; 를 직접 넣어야 이 파일이 효력을 갖는다. 넣지 않으면 아무 일도 일어나지 않고 오류조차 나지 않는다. 최종 병합된 설정에 내 파일이 들어갔는지는 nginx -T 로 확인한다.

2번과 3번은 같은 관례의 양면이다. 한쪽은 있어서 충돌하고 한쪽은 없어서 손으로 넣어야 한다.

적용 조건

한 기계에서 쓰던 설정 파일을 다른 배포판이나 다른 판올림의 기계로 옮기는 모든 곳에 적용한다. 이 실험대에서는 호스트 Arch 와 게스트 Debian 12 사이, 그리고 운영과 실험대 사이다.

특히 자주 걸리는 것 : 데몬 설정(nginx · systemd 유닛)과 부트 시점 설정(cloud-init)

이 기준은 파일을 옮길 때 한 번 도는 검사이지 막히는 것마다 꺼내 드는 설명이 아니다. §212 가 적었듯 낯선 것의 대부분은 배포판 때문이 아니다. 클라우드가 대신 해 주던 일(KVM · libvirt · cloud-init · DHCP 예약)과 이미 누가 해 두었던 일(nginx upstream · certbot · k3s 설치)이 대부분이고, 진짜 배포판 고유는 얼마 되지 않는다 — 이 실험대에서는 conf.d include 부재, 롤링 업그레이드, libvirtd.socket, 패키지명이다.

같은 구성을 Ubuntu 에서 해도 가상화와 네트워크 층은 명령 이름만 조금 바뀐다.

예외

같은 계열 안에서도 판올림이 다르면 1번이 그대로 걸린다. Debian 과 Ubuntu 는 aptdpkg 와 systemd 와 디렉터리 구조가 같은 계열인데 패키지 판올림이 달라서다.

배포판이 같으면 안 걸리는 것도 아니다. Arch 는 롤링 릴리스이고 부분 업그레이드를 지원하지 않아서, pacman -Sy 패키지 로 DB 만 갱신하고 일부만 설치하면 같은 기계 안에서도 공유 라이브러리 판이 어긋난다.

순서와 위치 문제는 이 축에서 안 잡힌다. 「단계별 구축 문서는 작성 시점이 아니라 실행 순서로 검증한다」가 그쪽을 맡고, 그 기록이 자기 예외 절에서 이쪽을 가리킨다. 두 기준이 서로의 사각을 덮는다.

1번은 문서로 판올림을 대조해 예측할 수 있다. 2번과 3번은 그 배포판에 실제로 깔아 봐야 드러난다 — 기본으로 붙어 있는 사이트가 무엇인지와 그 배포판이 어떤 include 관례를 갖는지는 패키지 메인테이너가 정한다.

배포판 차이가 아닌 것을 이 기준으로 설명하지 않는다. SELinux 와 AppArmor 가 Arch 에 기본 활성이 아닌 것은 이 기준이 잡는 종류이지만, RHEL 계열에서 k3s 에 정책 패키지가 필요한 것은 옮긴 설정의 문제가 아니라 그 배포판의 보안 모듈 문제다.

예시

http2 on; 을 쓴 설정을 Debian 12 의 nginx 1.22.1 로 옮기자 unknown directive "http2" 로 설정 검사가 실패했다.

Debian 기본 사이트를 지우지 않은 채 실험대 설정을 켜자 :80default_server 가 두 번 선언됐다.

Arch 에 sites-enabled 디렉터리를 만들어 파일을 넣었는데 include 줄이 없어 오류 없이 무시됐다.

게스트의 cloud-init 22.4.2 스키마 검사기가 sudo 를 리스트로 적은 형태를 거부했다. 어느 키가 걸렸는지는 알려 주지 않고 users.0 블록을 통째로 찍은 뒤 어느 스키마에도 안 맞는다고만 한다. 그 형태로도 부팅은 됐고 NOPASSWD sudo 도 멀쩡히 돌았다.

certbot DNS 플러그인의 패키지 이름이 Arch 에서 certbot-dns-cloudflare 이고 Debian/Ubuntu 에서 python3-certbot-dns-cloudflare 다.