zresmon CI 구축기 - QEMU 멀티 Distro 풀테스트

2026/09/02 DevOps Rust OpenZFS 2759자 · 약 8분

zresmon 후속 이야기. 2026-09-01 완료, 최종 결과 14 jobs / 0 failures.

시리즈: ZFS 소스 학습 (5/5) zresmon에서 도구를 만들었다면, 이 글은 그 도구를 9개 distro에서 검증한 CI 구축기입니다.

TL;DR

  • 호스티드 러너 커널은 통제 불가 → ZFS kmod 빌드 실패
  • QEMU로 각 distro VM을 띄워 자체 커널에서 소스빌드
  • 9 distro × 17 랩케이스 실제 풀 대상 실행
  • 디버깅 6건: KVM 권한, 패키지명, PATH, rustup HOME
  • 최종: 14 jobs / 0 failures

문제: 호스티드 러너로는 안 됐다

zresmon은 ZFS 커널 모듈 위에서 동작하는 TUI입니다. 테스트하려면 실제 ZFS 모듈이 로드된 환경이 필요합니다. GitHub Actions 호스티드 러너에서 시도한 결과:

시도결과이유
ubuntu-22.04 + zfs-dkms 2.1❌ 빌드 실패2.1 dkms는 6.x 커널과 미호환
ubuntu-24.04 + zfs-dkms 2.2❌ 빌드 실패kernel 6.17-azure와 불일치
ubuntu-26.04 + ZFS 소스빌드 2.4.1❌ configure 실패kernel 7.0 > ZFS 2.4.1 max 6.19

결론: 러너 커널이 아니라 자체 커널을 가진 VM에서 테스트해야 합니다. QEMU로 각 distro의 클라우드 이미지를 부팅합니다.

해결: QEMU VM 매트릭스

아래 그림이 전체 아키텍처입니다.

zresmon CI: QEMU VM 매트릭스 아키텍처 GitHub Actions ubuntu-latest 러너 qemu-boot.sh 이미지 다운로드 · resize · cloud-init · 부팅 SSH 대기 (최대 15분) hostfwd tcp::2222 → :22 QEMU VM (KVM, 4 vCPU, 8G RAM) almalinux8~10 · centos-stream9/10 · debian12/13 · fedora43/44 · ubuntu22/24 vm-payload.sh (VM 내부) ① 빌드 의존성 설치 (apt/dnf) ② OpenZFS 2.4.1 소스빌드 ③ make install · modprobe zfs ④ rustup + zresmon 클론 ⑤ cargo test --all (유닛) ⑥ 랩 매트릭스 17케이스   (sudo cargo test -- --ignored) 소요 시간 (VM당) 이미지 다운로드~30초 부팅 + SSH 대기~2분 ZFS 소스빌드~5분 유닛 테스트~30초 랩 매트릭스 17케이스~15분 합계~12-25분 9개 distro가 병렬 실행됩니다. 전체 파이프라인은 가장 느린 VM 기준 ~25분.
그림 1 - QEMU VM 매트릭스. 러너에서 qemu-boot.sh로 VM을 띄우고 vm-payload.sh를 전송해 ZFS 소스빌드부터 풀테스트까지 실행

디버깅 여정

KVM 권한 (전체 실패)

첫 시도는 전멸이었습니다. qemu-system-x86_64: failed to initialize kvm: Permission denied.

원인: 러너 유저는 /dev/kvm에 접근 불가.

해결: sudo qemu-system-x86_64로 root 권한 실행. OpenZFS CI는 libvirt로 해결하는데, libvirt도 결국 qemu를 root로 돌립니다. sudo 직접 실행이 더 간단합니다.

패키지명 차이

Error: Unable to find a match: libelf-devel     # Fedora/EL
Error: Unable to find a match: libtirpc-devel   # EL9 (CRB 필요)

해결: elfutils-libelf-devel로 수정 + CRB/Powertools 저장소 활성화.

zpool PATH (debian12)

/tmp/vm-payload.sh: line 38: zpool: command not found

원인: 소스빌드가 /usr/local/sbin에 설치하지만 비-root 셸 PATH에 없음.

해결: payload에 export PATH="/usr/local/sbin:$PATH" 추가.

rustup HOME 불일치 (전체 dnf 계열)

error: rustup could not choose a version of cargo to run

원인: sudo cargo 실행 시 rustup이 root의 HOME을 보지만 툴체인은 유저 홈에 설치돼 있음.

해결: 환경 변수를 명시적으로 전달.

sudo -E env \
  "PATH=$PATH" \
  "RUSTUP_HOME=$HOME/.rustup" \
  "CARGO_HOME=$HOME/.cargo" \
  "HOME=$HOME" \
  cargo test --test lab_matrix -- --ignored --nocapture

centos-stream9 미러 실패 (일시적)

dnf clean all 후 retry 3회로 해결했습니다.

debian13 UEFI 부팅

debian13 클라우드 이미지는 UEFI 부팅이 필요해서 QEMU에 OVMF 펌웨어를 지정했습니다.

최종 결과

✓ check          (ubuntu-latest: fmt/clippy/unit/build)
✓ scripts        (bash -n)
✓ musl           (static binary artifact)
✓ qemu-full ×9   (각 distro에서 ZFS 2.4.1 소스빌드 → 랩 17케이스)
Distro커널결과
almalinux84.18
almalinux95.14
almalinux106.12
centos-stream95.14
centos-stream106.12
debian126.1
debian136.12
fedora436.17
fedora446.17
ubuntu225.15
ubuntu246.8

14 jobs / 0 failures.

교훈

  • 커널 모듈 테스트는 VM에서. 호스티드 러너 커널은 통제 불가. QEMU VM으로 자체 커널을 제공하면 어떤 ZFS 버전이든 빌드 가능
  • 소스빌드가 제일 확실. distro 패키지는 커널 버전에 종속되지만 소스빌드는 그 자리에서 컴파일하므로 항상 일치
  • sudo + rustup은 HOME 명시. RUSTUP_HOME/CARGO_HOME/HOME을 전부 env로 전달해야 rustup이 툴체인을 찾음
  • cloud-init SSH 유저는 distro마다 다름. almalinux/almalinux, centos/cloud-user, debian/debian, fedora/fedora, ubuntu/ubuntu

이 CI가 없었다면 zresmon의 3단 폴백 체인이 실제로 필요하다는 것을 9개 distro에서 확인할 수 없었을 것입니다. 특히 빌드 변종 차이(scan kstat 생성 안 됨, rebuild 문구 없음)가 distro별로도 재현되어 폴백 설계의 정당성이 입증됐습니다.

HeonJe Lee | 선임연구원
게이트웨이 On-promise 제품 팀에서 시스템 모니터링 및 관리를 쉽게 다가갈 수 있도록 하기 위한 업무를 하고 있습니다.

Contact: lhjnano@gmail.com

Search

    Table of Contents