Files
keycloak-pattern/docs/guides/00-lab-host
DongHyeonkaandClaude Opus 5 8062cc9a19 docs(guides): bring the seven setup guides in line with the practitioner skill
The guides were written before the skill existed and a scored audit found
three gaps. Fixed by a subagent running under the skill, with measured
values, versions, IPs and quoted output declared off limits.

The big one: every step showed a command and its output, and almost none
said which line to look at or what it meant. 64 interpretation pairs added
across the seven files, weighted where the reading is hardest — 20 in the
Keycloak stage, where a Secret existing and a pod having received it are
different facts.

Only the extracting form of curl appeared. Where the reader meets a response
for the first time the guides now open with curl -I or curl -v and name the
lines worth reading; -w '%{http_code}' survives only where the code is a
value being compared — two upstream nodes against each other, or the 900-run
control loop.

Listing Secret keys went from a three-stage pipe to kubectl describe secret,
which prints the key names and their byte counts in one native command
without exposing a value.

And a tool assumption: jq and yamllint are installed on neither the lab host
nor the guests. The guides now say so where JSON is read by eye, rather than
sending the reader to install something mid-diagnosis. cloud-init schema is
on the guests and is now the guest-side check.

Also removes a stray Playwright screenshot committed at the repository root
in 919547a; the evidence copy under docs/evidence/b7a-orphan-session/ is the
one the document references.

Four things the audit left standing are recorded in the agent's report rather
than papered over — notably that 04's reload measurements are stated without
a reproduction procedure, and that 05 and 06 reference each other as
prerequisites.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 17:33:31 +09:00
..

00 — lab host 준비

이 단계가 끝나면

virsh list 가 sudo 없이 돌고, VM 을 만들 수 있는 상태가 된다.

전제

물리 기계 한 대. 이 실험대는 Arch Linux 를 썼지만 배포판은 상관없다 — 패키지 이름만 다르다.


1. CPU 가상화가 켜져 있는가

BIOS 에서 꺼져 있으면 아무것도 못 한다. 먼저 본다.

확인 — CPU 가 하드웨어 가상화 확장을 내놓고 있는가

grep -Eo 'vmx|svm' /proc/cpuinfo | head -1

어디를 봐야 하는가 — 출력 한 줄이 전부다. vmx(Intel) 또는 svm(AMD) 중 하나가 찍히는가, 아니면 아무것도 안 찍히는가.

이 결과가 의미하는 것 — 찍혔으면 이 호스트에서 KVM 을 쓸 수 있다. 다음 단계로 간다. 빈 출력은 「CPU 가 못 한다」가 아니라 대개 BIOS 에서 꺼져 있다는 뜻이다 — 재부팅해 Intel VT-x / AMD-V 를 켜고 다시 잰다. 여기서 막히면 뒤의 어떤 단계도 의미가 없으므로 진행하지 않는다.

실측 — 이 실험대의 호스트는 16 코어 전부에서 지원한다.

2. KVM 모듈이 올라와 있는가

확인 — 커널이 그 확장을 실제로 잡고 있는가

lsmod | grep kvm

형태 (이 실험대에서 캡처해 두지 않았다 — 줄 모양만)

kvm_intel   ...
kvm         ...

어디를 봐야 하는가 — 왼쪽 첫 열의 모듈 이름 두 개. 벤더 모듈 (kvm_intel 또는 kvm_amd)과 공용 kvm둘 다 있어야 한다. 셋째 열은 이 모듈을 쓰고 있는 쪽의 수라서, 아직 VM 이 없으면 0 인 것이 정상이다.

이 결과가 의미하는 것 — 두 줄이면 커널이 하드웨어 가상화를 쓸 준비가 됐고 virt-install 이 KVM 가속으로 뜬다. kvm 만 있고 벤더 모듈이 없으면 1번의 BIOS 설정이 커널까지 안 넘어온 것이다 — sudo modprobe kvm_intel 로 직접 올려 보면 거부 사유가 그대로 나온다. 아무것도 없으면 1번으로 돌아간다.

왜 이걸 먼저 보나. KVM 없이도 QEMU 는 돌지만 소프트웨어 에뮬레이션이 되어 수십 배 느리다. VM 두 대가 「뜨긴 뜨는데 느리다」면 대개 여기다.

3. 패키지 설치

하기 (Arch)

sudo pacman -S --needed qemu-full libvirt virt-install dnsmasq

Debian/Ubuntu 면 이름이 다르다.

sudo apt install qemu-system-x86 libvirt-daemon-system virtinst cloud-image-utils
무엇 하는 일
qemu 실제로 가상 기계를 돌리는 것
libvirt qemu 를 관리하는 층 (virsh 가 여기 붙는다)
virt-install VM 을 만드는 명령
dnsmasq 가상 네트워크의 DHCP·DNS

확인 — 두 실행 파일이 PATH 에 들어왔는가

virsh --version
qemu-system-x86_64 --version

어디를 봐야 하는가 — 판 번호 두 줄. 명령을 못 찾는다(command not found)면 패키지가 안 깔린 것이고, 번호가 나오면 깔린 것이다.

이 결과가 의미하는 것 — 여기서 나오는 libvirt 판 번호가 뒤의 옵션 이름을 가른다. 이 실험대는 libvirt 12.7.0 · QEMU emulator version 11.1.1 이었다 (문서 끝 실측값 블록). 훨씬 낮은 판이면 virt-install --cloud-init 같은 옵션의 동작이 다를 수 있으니, 01 에서 막힐 때 이 번호를 같이 본다.

4. libvirt 를 띄우고 권한을 받는다

하기

sudo systemctl enable --now libvirtd.socket
sudo usermod -aG libvirt "$USER"

그리고 로그아웃했다 다시 들어온다. 보조 그룹은 로그인할 때 정해지므로 usermod 만으로는 지금 셸에 반영되지 않는다.

확인 — 지금 이 셸이 libvirt 에 sudo 없이 붙는가

groups            # libvirt 가 보여야 한다
virsh list --all  # sudo 없이 돌아야 한다

실측

donghyeon libvirt wheel

어디를 봐야 하는가groups 출력에 libvirt 가 끼어 있는가, 그리고 virsh list --all머리글만 있는 빈 표라도 오류 없이 끝나는가. 아직 VM 을 안 만들었으므로 표가 비어 있는 것이 정상이다 — 봐야 할 것은 표의 내용이 아니라 명령이 통과했다는 사실이다.

이 결과가 의미하는 것 — 둘 다 통과하면 이 셸에서 VM 을 만들 수 있고, 01 로 넘어가도 된다. groupslibvirt 가 없으면 usermod 는 됐지만 지금 로그인 세션이 옛 그룹 목록을 들고 있는 것이다 — 로그아웃/로그인 한다. groups 에는 있는데 virshPermission denied 면 그룹이 아니라 소켓 문제이므로 systemctl status libvirtd.socket 을 본다.

libvirtd.service 가 아니라 .socket 을 켠 이유. 소켓 활성화라서 데몬이 미리 떠 있지 않아도 virsh 가 접속하는 순간 systemd 가 띄운다. 자원을 아끼고, 데몬을 재시작해도 클라이언트가 끊기지 않는다.

5. 연결 URI 를 고정한다

virsh 는 기본으로 qemu:///session(사용자 단위)에 붙는데, VM 은 qemu:///system(시스템 단위)에 만들어야 한다. 이걸 안 맞추면 만든 VM 이 안 보인다.

하기 — 셸 프로필에 넣는다

echo 'export LIBVIRT_DEFAULT_URI=qemu:///system' >> ~/.bashrc

확인 — 지금 셸이 어느 하이퍼바이저를 보고 있는가

virsh uri
qemu:///system

어디를 봐야 하는가 — 끝의 한 낱말. system 인가 session 인가.

이 결과가 의미하는 것qemu:///system 이면 뒤에서 만들 VM 과 지금 virsh 가 같은 곳을 본다. qemu:///session 이면 사용자 단위 하이퍼바이저를 보고 있어 VM 은 만들어졌는데 virsh list 에 안 나오는 상태가 된다. .bashrc 에 넣은 것은 새로 여는 셸에만 적용되므로, 지금 셸에서는 export LIBVIRT_DEFAULT_URI=qemu:///system 을 한 번 더 치거나 새 셸을 연다.

6. 기본 네트워크

확인 — VM 이 붙을 가상 네트워크가 살아 있는가

virsh net-list --all

실측

 Name      State    Autostart   Persistent
--------------------------------------------
 default   active   yes         yes

어디를 봐야 하는가default 행의 State 와 Autostart 두 칸. --all 을 준 이유가 여기 있다 — 빼면 inactive 인 네트워크는 아예 목록에 안 나와서 「없음」과 「꺼짐」을 구분할 수 없다.

이 결과가 의미하는 것active + yes 면 지금도, 호스트를 재부팅한 뒤에도 virbr0192.168.122.0/24 가 있다. inactive 면 VM 을 만들어도 DHCP 가 없어 IP 를 못 받는다. Autostart 가 no지금은 되지만 호스트를 재부팅한 다음 01 의 SSH 가 전부 실패하고, 원인을 게스트에서 찾게 된다. 둘 중 하나라도 어긋나면 아래 두 줄로 맞춘다.

virsh net-start default
virsh net-autostart default

이 네트워크가 virbr0 브리지와 192.168.122.0/24 대역을 만든다. VM 들이 여기 붙는다.


막히면

증상 원인 확인
virsh list 에 permission denied 그룹 반영 안 됨 로그아웃/로그인 했는가. groups 에 libvirt 가 있는가
만든 VM 이 목록에 없다 URI 가 session virsh uri
VM 이 극단적으로 느리다 KVM 미사용 lsmod | grep kvm · BIOS
net-start default 실패 dnsmasq 없음 패키지 설치 확인

이 단계의 실측값

돌고 있는 실험대에서 그대로 읽은 것이다.

libvirt   12.7.0
qemu      QEMU emulator version 11.1.1
그룹      donghyeon libvirt wheel
네트워크  default / active / autostart yes