--- kind: REFERENCE slug: a-config-file-does-not-mean-the-same-thing-on-two-distros title: 같은 설정 파일이 두 배포판에서 같은 뜻이 아니다 — 옮기기 전에 세 가지를 본다 topic: lab-environment-build topicName: 실험대 환경 구성 project: virtualization status: 게시 전 sourceRevision: 9465582b5d1630eb4ae7c4e078021486919bf6b6 source: - 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` 가 처음부터 붙어 있고 `:80` 에 `default_server` 로 선언돼 있어서, 실험대 설정의 `listen 80 default_server` 와 충돌한다. 심볼릭 링크를 걸 때 그 기본 사이트를 같이 지운다. ### 3. 그 배포판이 그 관례를 갖고 있는가 `sites-available` 과 `sites-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 는 `apt` 와 `dpkg` 와 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 기본 사이트를 지우지 않은 채 실험대 설정을 켜자 `:80` 의 `default_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` 다.