Skip to main content
실습하다 설정이 꼬였을 때, Kafka부터 다시 지우지 않고 깨끗한 VM으로 돌아갈 수 있으면 어떨까요?
Kafka를 처음 실행하는 데는 broker 하나면 충분해요. 하지만 설치 방식, data directory, network 설정이 섞이면 개념을 보는 시간보다 환경을 복구하는 시간이 더 길어질 수 있어요. 그래서 먼저 같은 Ubuntu에서 출발하는 VM 두 대를 준비할게요.
  • kafka-docker: Ubuntu 안에서 공식 Kafka Docker image를 실행해요.
  • kafka-ubuntu: Ubuntu에 Java와 Kafka binary archive를 직접 설치해요.
두 환경은 설치 방식만 달라요. 다음 글부터 topic, key, consumer group, offset을 같은 이름과 같은 record로 확인합니다.
이 VM에서 이어갈 실습은 Apache Kafka 4.3.1을 기준으로 해요. VM 준비 절차는 Ubuntu 26.04 LTS, amd64와 해당 Ubuntu·Docker 공식 문서를 기준으로 해요. 아래의 2 vCPU, 4 GiB RAM, 25 GiB disk는 이 시리즈가 사용하는 학습용 profile이지 Kafka나 Ubuntu의 일반적인 최소 사양이 아니에요.

완성할 환경부터 그려봐요

처음 네 실습에서는 client도 broker와 같은 VM에서 실행하고 localhost:9092로 접속해요. 그래서 기본 NAT network면 충분합니다. 나중에 여러 broker를 서로 다른 VM에 띄울 때 고정된 hostname과 VM 사이의 통신을 다시 설계할 거예요.

CLI host를 먼저 확인해요

이 글은 GUI가 없는 Ubuntu CLI host를 기준으로 해요. virt-install과 virsh는 VM 안이 아니라 VM을 실행할 host에서 사용합니다.
1

CPU virtualization을 확인해요

Ubuntu의 kvm-ok는 cpu-checker package에 들어 있어요.
Hardware virtualization을 사용할 수 있다는 결과가 나와야 해요. 사용할 수 없다면 BIOS 또는 UEFI에서 Intel VT-x나 AMD-V가 꺼져 있지 않은지 먼저 확인하세요.
2

KVM, libvirt, virt-install을 설치해요

마지막 명령이 active를 출력하면 libvirt service가 요청을 받을 준비가 된 거예요.
3

현재 사용자에게 VM 관리 권한을 줘요

이미 libvirt group에 속해 있다는 메시지가 나올 수도 있어요. 새로 추가됐다면 로그아웃한 뒤 다시 로그인해야 group 권한이 반영됩니다.
4

default NAT network를 켜요

Active: yes와 Autostart: yes가 보여야 해요. 두 VM은 이 network에서 사설 address를 받고 host를 거쳐 인터넷에 나갑니다.
kvm-ok가 hardware acceleration을 사용할 수 있다고 알리고, libvirtd가 active이며, virsh --connect qemu:///system list --all과 net-info default가 권한 오류 없이 끝나면 VM을 만들 준비가 됐어요.

Ubuntu cloud image를 받고 checksum을 확인해요

화면에서 installer 항목을 고르는 대신, 설치가 끝난 Ubuntu 26.04 LTS cloud image에 cloud-init 설정을 주입할게요. Host가 ARM이라면 architecture가 맞는 공식 image를 골라야 하며, amd64 image를 그대로 사용하면 안 돼요.
1

Cloud image와 SHA256SUMS를 받아요

2

내려받은 image를 검증해요

ubuntu-26.04-server-cloudimg-amd64.img: OK가 나오기 전에는 VM disk를 만들지 마세요. FAILED가 나오면 손상된 파일을 사용하지 말고 공식 cloud image server에서 다시 받으세요.

두 VM을 같은 profile로 준비해요

이제 host terminal에서 cloud-init 설정과 VM disk를 만든 뒤 virt-install로 두 VM을 정의할게요. 두 VM은 같은 base image에서 출발하지만 각각 처음 boot하며 서로 다른 hostname과 machine identity를 만듭니다.
1

실습 전용 SSH key를 만들어요

Host에서 두 VM에 접속할 때 사용할 key예요. 이미 만들었다면 기존 key를 그대로 사용합니다.
2

두 VM의 cloud-init 설정을 만들어요

두 VM 모두 kafka 계정을 사용하지만 hostname은 다르게 넣어요. Password login은 열지 않고 앞에서 만든 SSH public key만 등록합니다.
이 실습은 IP를 libvirt DHCP lease에서 읽고, VM을 끈 뒤 snapshot을 만들어요. qemu-guest-agent가 필요하지 않으므로 첫 boot에서 package를 설치하거나 systemctl을 실행하지 않습니다.
3

두 qcow2 disk를 25 GiB로 만들어요

검증한 cloud image를 각 VM의 독립 disk로 복사하고 virtual size를 늘려요. 이 명령을 실행하기 전에 같은 이름의 VM과 disk가 없어야 합니다.
4

CLI 옵션으로 두 VM을 만들어요

Host의 osinfo-db가 Ubuntu 26.04를 알면 그 profile을 사용하고, 아직 없다면 generic으로 넘어가요. Disk와 NIC는 아래에서 virtio로 직접 지정하므로 이 fallback도 같은 resource profile을 만듭니다.다음 명령은 각 VM에 2 vCPU, 4 GiB RAM, 25 GiB qcow2 disk, default NAT의 virtio NIC를 지정해요. --graphics none과 --noautoconsole이 GUI console을 만들거나 열지 않게 합니다.
Host resource가 부족하다면 한 VM을 virsh shutdown으로 끈 뒤 다른 VM을 실행해도 돼요. 이 profile을 Kafka의 일반적인 최소 사양으로 해석하지는 마세요.
5

IP를 확인하고 SSH로 접속해요

첫 boot에서는 cloud-init이 사용자와 SSH 설정을 적용하므로 잠시 기다려야 할 수 있어요. DHCP address가 보이면 각 VM에 접속해 초기화가 끝날 때까지 기다립니다.
IP 변수가 비어 있어 test가 실패하면 잠시 기다린 뒤 이 명령을 다시 실행하세요.
기존 VM에서 systemctl 인증을 요구한다면Authenticating as: kafka가 보이면 해당 systemctl은 cloud-init의 root 단계가 아니라 kafka login session에서 실행된 거예요. Ctrl+C로 취소하세요. 이 실습에서는 qemu-guest-agent를 enable하거나 start할 필요가 없습니다.기존 VM에서는 아래 명령으로 passwordless sudo와 첫 boot 결과만 확인할 수 있어요.
첫 명령이 password prompt 없이 끝나면 cloud-init이 만든 sudo rule은 적용된 거예요. 예전 runcmd 때문에 cloud-init 상태가 error여도 SSH 접속과 virsh --source lease 확인이 된다면 이 실습은 계속 진행할 수 있습니다.
기초 글에서는 같은 명령을 두 환경에서 차례로 확인해요. kafka-docker를 종료한 뒤 kafka-ubuntu를 실행해도 됩니다. 세 broker 장애 실습에 들어갈 때 별도의 다중 VM profile을 준비할게요.

각 VM의 출발 상태를 기록해요

두 VM에 로그인해서 hostname, address, clock, disk를 확인해요. 아래 결과는 복사해 두면 나중에 listener나 disk 문제를 추적할 때 기준점이 됩니다.
두 VM에서 확인할 항목은 이렇습니다.

설치 방식별 도구를 준비해요

kafka-docker VM에서 Docker의 공식 apt repository를 사용해 Engine을 설치해요.
1

Docker repository key를 등록해요

2

Docker apt source를 등록해요

3

Docker Engine을 설치하고 확인해요

다음 Kafka 글의 Docker 명령은 sudo docker를 사용해요. Root 없이 실행하도록 바꾸고 싶다면 Docker의 Linux post-install 안내를 먼저 읽고 권한 범위를 이해하세요.
단지 sudo를 생략하려고 사용자를 docker group에 추가하지 마세요. Docker daemon을 제어할 수 있는 계정은 host에서 높은 권한을 얻을 수 있어요. 이 시리즈는 권한 경계를 숨기지 않기 위해 sudo docker를 그대로 사용합니다.

Kafka를 설치하기 전 snapshot을 남겨요

두 VM을 정상 종료한 뒤 host의 virsh로 각각 tooling-ready snapshot을 만들어요. 아래 snapshot은 qcow2 disk를 사용하는, 전원이 꺼진 VM을 기준으로 합니다.
두 VM의 상태가 모두 shut off가 된 뒤 snapshot을 만드세요.
Snapshot restore는 VM disk를 과거 상태로 되돌려요. 이후 만든 topic, record, consumer offset이 필요하다면 먼저 별도로 보존하세요. 다음 글에서 working-first-record snapshot을 추가로 만들기 전까지 tooling-ready는 Kafka가 전혀 설치되지 않은 복구 지점이에요.
kafka-docker에서 sudo docker version이 성공하고, kafka-ubuntu에서 Java 21이 확인되며, 두 VM 모두 tooling-ready snapshot을 가지고 있다면 다음 글을 시작할 준비가 됐어요.

이전 글

Kafka가 왜 전달보다 기록을 중심에 두는지 다시 봐요.

다음 글

두 VM에 Kafka를 실행하고 같은 첫 record를 왕복해요.