Post

우분투에서 kvm을 이용해 가상머신 생성하기

우분투에서 kvm을 이용해 가상머신 생성하기

컴퓨터에 우분투를 깔아서 쿠버네티스 환경을 만들기 위해 가상머신 여러개를 만들어 클러스터로 묶는 작업을 해야한다 이전에는 윈도우 환경에서 virtual box를 이용해서 구성을 해봤지만 지금은 우분투에서 kvm + qemu + libvirt + terraform을 이용해서 한번에 가상머신을 구축해본다

 

개념

KVM: 리눅스 커널을 하이퍼바이저로

KVM (Kernel-based Virtual Machine)은 리눅스 커널에 내장된 타입 1 하이퍼바이저(Type 1 Hypervisor) 기술이다 여기서 타입 1 하이퍼바이저란, 운영체제가 하드웨어 위에서 직접 실행되는 것처럼, 하드웨어 위에서 바로 동작하여 가상 머신을 제어하는 방식을 의미한다

 출처: https://ko.wikipedia.org/wiki/하이퍼바이저

주요 특징

  • 커널 모듈 (Kernel Module) KVM은 별도의 프로그램이 아니라 리눅스 커널의 일부로 동작하는 모듈(kvm.ko) modprobe kvm-intel이나 modprobe kvm-amd 같은 명령어로 활성화된다 이 방식은 리눅스 커널이 가진 강력한 메모리 관리, 프로세스 스케줄링 등의 기능을 그대로 활용할 수 있어 매우 효율적이고 안정적임 즉, 리눅스 자체가 하이퍼바이저가 되는 것
  • 하드웨어 가상화 지원 (Hardware-assisted Virtualization) KVM의 핵심 역할은 CPU 제조사(Intel, AMD)가 제공하는 하드웨어 가상화 기능(Intel VT-x, AMD-V)을 사용하는 것 KVM은 이 하드웨어 기능을 제어할 수 있는 통로(/dev/kvm이라는 특수 장치 파일)를 만들고, 이 통로를 통해 가상 머신의 CPU 명령어를 실제 하드웨어 CPU가 직접, 그리고 안전하게 처리하도록 중계한다
  • CPU와 메모리 중심 KVM은 가상화의 가장 핵심적인 부분, 즉 CPU와 메모리 가상화에만 집중 가상 디스크, 가상 네트워크 카드, USB 장치 등 주변 장치(I/O)가 어떻게 동작하는지는 KVM의 관심사가 아니라서 이 부분은 QEMU와 같은 다른 프로그램의 도움이 필요하다

 

QEMU: 다재다능한 가상 머신 에뮬레이터

QEMU (Quick EMUlator)는 본래 하드웨어 에뮬레이터로 시작했으며, 현재는 KVM의 가장 중요한 파트너로 활약하는 유저스페이스(userspace) 프로그램 커널이 아닌 일반 애플리케이션처럼 실행된다

핵심 역할과 두 가지 모드

  1. 순수 에뮬레이션 모드 (Full Emulation Mode) QEMU의 본래 기능 이 모드에서 QEMU는 Binary Translation중에서 TCG (Tiny Code Generator)라는 동적 번역기를 사용하여 한 종류의 CPU 아키텍처용 코드를 다른 종류의 CPU에서 실행할 수 있도록 실시간으로 번역한다 예를 들어, 인텔 x86 PC에서 ARM CPU용으로 만들어진 안드로이드 OS를 실행하는 것이 가능 이 방식은 매우 유연하지만, 모든 것을 소프트웨어로 처리하기 때문에 성능이 매우 느리다
  2. 가속기 모드 (Accelerator Mode with KVM) 오늘날 리눅스 가상화의 표준 방식 QEMU가 KVM의 존재를 감지하면, CPU와 메모리 관련 작업을 직접 처리하지 않고 /dev/kvm 장치를 통해 KVM에 모두 위임한다 이 모드에서 QEMU의 역할은 다음과 같이 바뀐다
    • I/O 하드웨어 에뮬레이션: KVM이 신경 쓰지 않는 디스크 컨트롤러, 네트워크 카드(NIC), 그래픽 카드, USB 포트 등 모든 주변 장치를 에뮬레이션
    • 가상 머신 생명주기 관리: 가상 머신의 BIOS 또는 UEFI를 제공하고, 전체적인 시스템을 구성하고 실행
    • VirtIO 지원: 성능 향상을 위해 QEMU는 VirtIO라는 표준화된 고성능 가상 장치 드라이버를 제공 게스트 OS에 VirtIO 드라이버를 설치하면, 일반적인 하드웨어를 에뮬레이션하는 것보다 훨씬 빠른 속도로 디스크 및 네트워크 I/O를 처리할 수 있다

 

libvirt: 일관된 가상화 관리 계층

libvirt는 다양한 가상화 기술을 관리하기 위한 오픈소스 API, 데몬(daemon), 그리고 관리 도구의 집합 KVM+QEMU의 복잡성을 감추고 사용자에게 편리하고 일관된 인터페이스를 제공하는 것이 주 목적이다

주요 기능 및 구성요소

  • 추상화 API (Abstraction API) libvirt의 가장 큰 가치는 추상화 사용자는 백엔드 기술이 KVM인지, Xen인지, 혹은 VirtualBox인지 신경 쓸 필요 없이 동일한 libvirt API와 명령어를 사용할 수 있다
  • 데몬 (libvirtd) 백그라운드에서 항상 실행되며 API 요청을 받아 처리하는 핵심 서비스 virshvirt-manager 같은 클라이언트 도구로부터 명령을 받아서 실제 QEMU 프로세스를 실행하고 관리한다
  • 관리 도구 (Management Tools) libvirt는 사용자가 상호작용할 수 있는 여러 도구를 제공
    • virsh: 가장 대표적인 커맨드 라인 인터페이스(CLI), VM의 시작, 중지, 상태 확인, 실시간 마이그레이션 등 거의 모든 관리가 가능
    • virt-manager: 데스크톱 환경에서 사용하는 그래픽(GUI) 관리 도구
    • virt-install: 커맨드 라인에서 VM 설치 및 생성을 도와주는 도구=
  • XML 기반 설정 libvirt는 VM의 모든 설정(CPU 개수, 메모리 크기, 디스크 경로, 네트워크 연결 등)을 표준화된 XML 형식으로 정의하고 관리할 수 있다 이 XML 파일 덕분에 VM 설정을 쉽게 복제하거나, 버전 관리 시스템(Git 등)으로 추적하고, 다른 시스템으로 이전하는 것이 매우 용이하다 이과정을 또 다른 방법을 이용할 수 있는데 그 방법이 terraform이다

 

Terraform: 인프라를 코드로 관리(IaC)

인프라를 코드로 관리(IaC)하는 도구로, 명령어와 설정 파일(코드)을 통해 로컬 가상머신(VM)과 퍼블릭 클라우드 리소스를 모두 생성하고 관리할 수 있다

로컬 VM 환경에서 Terraform 사용법

로컬 환경(사용자 컴퓨터, 사내 서버 등)에서 Terraform을 사용할 때는 주로 KVM, VirtualBox, vSphere 같은 하이퍼바이저와 연동되는 ‘프로바이더(Provider)’를 이용한다 프로바이더는 Terraform이 특정 플랫폼의 API를 이해하고 제어할 수 있게 해주는 플러그인

작동 방식:

  1. 프로바이더 정의: 사용자는 설정 파일(.tf)에 KVM과 같은 로컬 하이퍼바이저를 위한 프로바이더를 지정
  2. 리소스 정의: 동일한 파일에 생성할 VM의 사양(CPU, 메모리, 디스크 이미지 경로, 네트워크 등)을 코드로 작성
  3. 실행: 터미널에서 terraform apply 명령어를 실행하면 Terraform이 해당 프로바이더를 통해 KVM의 API(내부적으로는 libvirt)를 호출하여 정의된 사양대로 VM을 생성.

이 방식은 Vagrant와 유사하게 개발 환경을 코드로 관리하고, 동일한 VM을 반복적으로 만들거나 팀원과 공유할 때 매우 유용하다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
terraform {
  required_providers {
    libvirt = {
      source = "dmacvicar/libvirt"
    }
  }
}

# libvirt 프로바이더 설정
provider "libvirt" {
  uri = "qemu:///system"
}

# KVM 가상머신 리소스 정의
resource "libvirt_domain" "my_vm" {
  name   = "terraform-vm-local"
  memory = "2048"
  vcpu   = "2"
  # ... 디스크 및 네트워크 설정
}

 

퍼블릭 클라우드 환경에서 Terraform 사용법

클라우드에서는 VM 하나를 넘어 네트워크, 스토리지, 데이터베이스, 로드 밸런서 등 인프라 전체를 코드로 다룰 수 있다

작동 방식:

  1. 프로바이더 정의: 설정 파일에 사용할 클라우드(예: aws)의 프로바이더를 정의하고, API 접근을 위한 인증 정보(Access Key 등)를 설정
  2. 리소스 정의: VM(AWS에서는 EC2 인스턴스)뿐만 아니라, 가상 사설 네트워크(VPC), 서브넷, 보안 그룹(Security Group), 데이터베이스(RDS) 등 서비스에 필요한 모든 자원을 코드로 정의
  3. 실행: terraform apply를 실행하면 Terraform이 해당 클라우드 제공자의 API 엔드포인트로 네트워크 요청을 보내 정의된 모든 리소스를 자동으로 생성하고 연결

이 방식은 복잡한 클라우드 아키텍처를 문서화하고, 버전 관리(Git)하며, 재사용할 수 있게 해줍니다. 클릭 몇 번의 실수로 장애가 발생하는 것을 막고, 언제나 동일한 구조의 인프라를 안정적으로 구축할 수 있게 됩니다.

 

앤서블(Ansible)

  • 서버 설정 관리: 여러 서버에 동일한 설정을 적용하거나 특정 상태를 유지하도록 관리
  • 소프트웨어 배포: 서버에 애플리케이션이나 여러 소프트웨어를 자동으로 설치하고 배포
  • 작업 자동화: 반복적인 시스템 관리 작업을 스크립트(플레이북)로 만들어 자동화

앤서블의 가장 큰 특징은 Agentless이다 관리할 서버에 별도의 프로그램을 설치할 필요없이, SSH 연결만으로 모든 작업을 수행할 수 있어 매우 편리하다 YAML 형식의 플레이북(Playbook)을 사용하여 작업 순서를 정의하는데, 사람이 읽고 이해하기 쉬운 형태

 

테라폼과의 차이점:

  • 테라폼: 클라우드 인프라(가상 머신, 네트워크, 스토리지 등)를 코드로 생성하고 관리 (집을 짓는 역할)
  • 앤서블: 이미 생성된 인프라 위에 소프트웨어를 설치하고 설정하는 역할 (지어진 집에 가구와 가전을 배치하는 역할)

 

구성

1. KVM 및 관련 패키지 설치

1
2
sudo apt update
sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager -y
  • qemu-kvm: 가상머신을 실행하는 핵심 패키지

  • libvirt-*: 가상머신을 관리하고 제어하는 라이브러리 및 도구

  • bridge-utils: 가상 네트워크를 설정하는 도구

  • virt-manager: 가상머신을 쉽게 생성하고 관리할 수 있는 GUI(그래픽 인터페이스) 관리자

 

2. 사용자 계정 권한 설정

가상머신을 sudo 명령어 없이 편리하게 관리하려면 현재 사용자를 libvirtkvm 그룹에 추가

1
2
sudo adduser $USER libvirt
sudo adduser $USER kvm

권한 설정을 적용하려면 시스템을 완전히 재부팅하거나, 로그아웃 후 다시 로그인

 

3. KVM 서비스 상태 확인

패키지 설치와 권한 설정이 완료되면, libvirtd 서비스가 잘 실행되고 있는지 확인

1
systemctl is-active libvirtd

 

4. Terraform VM 생성하기

필수 패키지 설치 및 GPG 키 추가

먼저 Terraform 패키지 저장소를 신뢰하기 위한 GPG 키를 시스템에 추가한다

1
2
sudo apt-get update && sudo apt-get install -y gnupg software-properties-common
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg

HashiCorp 저장소 추가

GPG 키를 확인한 후, 시스템에 HashiCorp 공식 저장소를 추가

1
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list

Terraform 설치

이제 패키지 목록을 업데이트하고 Terraform을 설치

1
2
3
sudo apt update
sudo apt install terraform -y
sudo apt install genisoimage

genisoimage는 테라폼에서 cloud-init iso 이미지를 생성하는 동안 mkisofs 명령어를 찾을 수 없을때 발생 추가로 설치해야한다

미리 정의된 테라폼을 이용할것 클론github

main.tf 파일에 ssh 키를 넣어야 나중에 ansible을 원활하게 할 수 있다

#### Terraform 실행

1
2
3
4
5
6
#main.tf 가 존재하는 위치에서 실행한다
terraform init
terraform plan # 설정확인
terraform apply # 적용

terraform apply --var vm=4 # 가상머신 4개 생성 개수 변경 가능 기본값 3

tf 파일 실행시 권한 오류 해결

해결 github

위 권한 오류가 발생한다면 위 링크에 해결 방법이 있다

  • 해당 파일 맨 아래줄을 확인 /etc/apparmor.d/abstractions/libvirt-qemu

    1
    
    vi /etc/apparmor.d/abstractions/libvirt-qemu
    

    아래 명령어가 없다면 추가한다 (맨 아래에는 없고 맨아래 주석위에 존재했음)

    1
    
      include if exists <abstractions/libvirt-qemu.d>
    
  • 폴더가 없다면 생성 /etc/apparmor.d/abstractions/libvirt-qemu.d

    1
    
    sudo mkdir -p /etc/apparmor.d/abstractions/libvirt-qemu.d
    
  • 해당 위치에 파일 생성 /etc/apparmor.d/abstractions/libvirt-qemu.d/override.

    1
    
    sudo vi /etc/apparmor.d/abstractions/libvirt-qemu.d/override
    
    1
    2
    3
    
    # /etc/apparmor.d/abstractions/libvirt-qemu.d/override
      
     /var/lib/libvirt/images/** rwk,
    
  • 재시작 AppAmor

    1
    
    sudo systemctl restart apparmor
    

위 명령어를 실행하면 정삭적으로 실행된다

 

libvirt에 ‘default’ 정의 안됨 오류

  • 현재 스토리지 풀 확인

    먼저 현재 시스템에 어떤 스토리지 풀이 있는지 확인

    1
    
    virsh pool-list --all
    

    아마 이 명령어의 결과가 비어 있거나, ‘default’ 풀이 inactive 상태 비활성화 상태면 바로 활성화 단계로 이동

  • 풀이 없다면 생성한다

    1
    
    virsh pool-define-as default dir --target /var/lib/libvirt/images
    
  • 풀 빌드

    1
    
     virsh pool-build default
    
  • 풀 활성화

    1
    2
    3
    4
    5
    
    # 풀을 활성화(시작)합니다.
    sudo virsh pool-start default
      
    # 시스템 재부팅 시 풀이 자동으로 시작되도록 설정합니다. (매우 중요)
    sudo virsh pool-autostart default
    

 

5. Ansible로 환경 구축

먼저 파이썬을 설치해야한다 파이썬 가상환경에서 Ansible을 사용하는 이유는 프로젝트를 진행하다 보면 각기 다른 버전의 Ansible이나 관련 라이브러리가 필요한 경우가 생기는데

  • A 프로젝트: Ansible 2.9 버전과 특정 라이브러리 v1.0이 필요
  • B 프로젝트: Ansible 2.12 버전과 동일 라이브러리 v2.0이 필요

가상환경(venv)은 이런 문제를 해결 할 수 있다

 

파이썬 설치와 가상환경 실행

1
2
sudo apt update
sudo apt install python3-pip python3.10-venv -y

이후 playbook이 있는 프로젝트 폴더로 이동

1
2
python3 -m venv .venv # 가상환경 생성
source .venv/bin/activate # 가상환경 활성화

Ansible 설치

Ansible은 Python 기반이므로, Python과 패키지 관리자인 pip가 설치되어 있어야 한다

1
2
pip3 install ansible
ansible --version #설치확인

Ansible 연결 테스트

플레이북을 실행하기 전에, Ansible이 모든 VM에 정상적으로 접속할 수 있는지 확인할 수 있다 ping 모듈을 사용하면 간단하게 테스트한다

1
ansible all -i inventory.ini -m ping
  • all: inventory.ini에 있는 모든 호스트를 대상
  • -i inventory.ini: 사용할 인벤토리 파일을 지정
  • -m ping: ping 모듈을 사용 (ICMP ping이 아닌, SSH 접속 후 간단한 스크립트를 실행하여 응답을 확인하는 방식)

Ansible 실행

1
make all

 

6. 클러스터 확인

  • 마스터 노드에 SSH로 접속

    1
    
    ssh ubuntu@192.168.100.100 -i ~/.ssh/id_rsa
    

    (IP 주소는 inventory.ini에 지정한 마스터 노드 IP)

  • 마스터 노드 터미널에서 kubectl 명령어로 노드 상태를 확인

    1
    
    kubectl get nodes -o wide
    
This post is licensed under CC BY 4.0 by the author.