Tagged: KVM

Running a arm64 of guest on x86_64 host via kvm

최근들어 arm64 아키텍쳐가 인기가 많아졌다. 애플의 실리콘 반도체라고 불리는것도 arm64 기반이며 Windows 11 도 arm64 에서도 작동된다. 리눅스는 오래전부터 다양한 아키텍쳐로 포팅이되었기 때문에 arm64 를 위한 배포판도 다양하게 존재한다. 문제는 arm64 아키텍쳐를 경험하기 위해서 arm64 하드웨어가 있어야 했지만, 이제는 x86_64 기반의 가상머신을 이용하면 arm64 아키텍쳐를 게스트로 운영할 수 있다.

이 문서는 x86_64 기반 가상머신에서 arm64 아키텍쳐기반의 게스트를 실행하는 방법에 대해서 기술한 것이다.

x86_64 가상머신

x86_64 아키텍쳐 기반의 가상머신으로 리눅스 운영체제를 기반으로 KVM 을 활용하고 있다. GUI 툴로서 virt-manager, CLI 로는 virsh 를 활용해서 간단하게 게스트를 생성하고 운영하고 있다. arm64 아키텍쳐 게스트를 운영하기 위한 호스트로서 x86_64 아키텍쳐 기반 가상머신 스펙은 다음과 같다.

  • OS: Ubuntu 22.04
  • Kernel: 5.15.0-207.156.6.el9uek.x86_64
  • CPU: AMD Ryzen 7 2700X Eight-Core Processor

libvirt vs QEMU

arm64 아키텍쳐기반 게스트를 운영하기 위해서는 QEMU 를 사용해야 한다. QEMU 는 가상머신 에뮬레이터라고 생각하면 된다. 문제는 QEMU 는 CLI 기반만 제공한다.

반면에 libvirt 는 KVM/QEMU 등을 지원하는 일종의 핸들러 라이브러리고 생각하면 된다. libvirt 를 이용하면 xml 기반으로 게스트 관련 가상머신 스펙을 정의할 수 있으며 virt-manager 와같은 GUI 툴도 활용할 수 있다.

QEMU 에뮬레이터라고 했기 때문에 arm64 를 위한 QEMU 에뮬레이터를 설치하면 arm64 기반 게스트 운영체제를 운영할 수 있다. 다음과 같이 arm64 를 위한 QEMU 에뮬레이터를 설치해준다.

위 패키지를 설치가 완료되면 다음과 같이 virt-manager 에서 게스트를 생성할때에 Architecture options 이 생긴다.

qemu-system-arm 패키지 설치후 virt-manager 에서 Architecture options 이 나타난다.

arm64 를 위한 지원 파일 생성(Optional)

Ubuntu22.04 에서는 이 과정이 필요하지 않다.

arm64 게스트 실행을 위해서 파일이 필요하다. 첫번째로 NVRAM 변수들을 저장하기 위한 플래쉬 볼륨(Flash volume) 을 생성해야 한다.

두번째로 ARM UEFI 펌웨어 파일이 필요하다.

이제 필요한 사항은 모두 갖춰졌다.

Amazon Linux Arm64 이미지 실행

처음부터 Arm64 기반 OS 를 게스트로 설치하면서 생성할 수도 있다. 하지만 이미 있는 Arm64 기반 OS를 가져다 쓸 수도 있다. 여기서는 Amazon Linux 를 가져다 사용해 보도록 하겠다.

Amazon Linux 는 Amazon 이 AWS 서비스에서 사용할 목적으로 만든 배포판이다. 현재 Amazon Linux2 와 Amazon Linux3 등 다양한 버전을 제공한다. 최근 프로젝트가 Amazon Linux2 를 많이 사용하고 있어서 Amazon Linux2 Arm64 기반 OS 이미지를 게스트로 한번 실행 보도록 하겠다.

Amazon Linux2 는 다음과같이 다운로드 할 수 있다. 이미지 파일은  Amazon Linux 2 virtual machine images 에서 찾을 수 있다.

seed.iso 만들기

Amazon Linux2 는 기본적으로 ec2-user 라는 시스템 계정이 있으며, 로그인을 위해 패스워드 방식이 아닌 SSH 인증키 방식을 사용한다. 하지만 배포되는 이미지에 맞는 인증키가 따로 없기 때문에 부팅과정에서 이 부분을 변경하도록 해야하는데, 이를 위해서 seed.iso 를 만들어 게스트 OS 에 CD-ROM 에 넣어 부팅해준다. 이 부분에 대한 설명은 다음의 페이지에서 찾을 수 있다.

간단하게, 시스템 호스트 이름(나중에 변경하면 된다) 과 ec2-user 에 로그인 패스워드를 변경하도록 seed.iso 파일을 만들어 보도록 하겠다.

먼저 작업을 위한 디렉토리 seedconfig 만들고 meta-data, user-data 파일을 생성한다.

로그인이 가능하도록 필요한 부분만 넣었다. 이제 다음과 같이 seed.iso 파일을 생성해 준다.

virt-manager 로 Amazon Linux2 생성하기

이제 준비할 것들은 모두 갖췄다. virt-manager 를 이용해서 Amazon Linux2 를 구동해 보자.

새로운 게스트 생성하기

OS 이미지가 있기 때문에 Import 로 하고 Arm64 는 aarch64 로 선택, Machine Type 은 virt 다.

amazon linux2 이미지, 운영체제 종류 선택

다운로드 받은 amazon linux2 이미지와 운영체제 종류를 선택한다. 운영체제 종류를 잘 모르겠다면 Generic Linux 로 해도 된다.

Memory, Cpu 는 사양에 맞게 조절해주고 다음을 선택한다.

Customize configuration before install 필수

가상머신 이름을 지정하고 네트워크 선택을 한다음에 반드시 Customize configuration before install 를 체크해 준다. 그리고 Finish 를 하면 다음과 같은 화면이 나온다.

Firmware 를 Custom 선택

Firmware 를 Custom 으로 하고 no-secboot.fd 선택해 준다. 그리고 설치를 시작해 준다.

정상적으로 부팅

정상적으로 부팅이 된다. 로그인이 안되기 때문에 앞에서 만든 seed.iso 파일을 이용해야 한다. 이를 위해서 Amazon Linux2 게스트 OS 에 CD-ROM 하드웨어를 추가해 준다.

CD-ROM 하드웨어 추가

이제 VM 을 다시 시작시키면 seed.iso 에 user-data 에 설정한 ec2-user 의 패스워드로 로그인이 가능해 진다.

정상적으로 로그인 성공

정상적으로 로그인이 성공했다. ec2-user 는 기본적으로 sudoer 권한을 가지고 있기 때문에 sudo 를 이용해서 root 작업을 할 수 있다.

sshd 에 설정에서 패스워드 인증을 활성화 해준다.

설정을 변경해 줬기 때문에 sshd 를 재시작 해준다.

이렇게 sshd 로 패스워드 인증방식을 활성화 했기 때문에 원격에서 접속도 가능해진다.

마지막으로 Amazon Linux2 게스트 를 셧다운 해주고 seed.iso 를 위한 CD-ROM 하드웨어를 삭제해준다.

VMWare,VirtualBox VM 이미지를 KVM 이미지로 변경하기

프로젝트를 하다보니 윈도우즈 시스템을 사용하고 있는 가운데, 리눅스 머신이 필요하게 되어서 vmplayer 를 이용해 가상머신으로서 리눅스를 테스트 용도로 설치해 사용하고 있었다. 이제 프로젝트도 전부 끝나게 되어서 노트북에 설치한 이 VMPlayer 의 OS 를 KVM 시스템으로 옮기 싶었다.

어떻게 VMWare, VirtualBox VM 이미지를 KVM 이미지로 바꿀 수 있을까 싶어 자료 조사를 하고 KVM 시스템으로 옮길 수 있었다. 이에 대한 내용을 정리한다.

qemu-img

VMPlayer 는 무료 소프트웨어이기 때문에 이미지 변경에 대한 툴을 제공하지 않는다. 이 경우에 KVM 리눅스 머신이 존재한다면 VMPlayer 의 이미지를 KVM 리눅스 머신으로 옮긴다.

KVM 리눅스 머신에는 qemu-img 를 사용할 수 있다. 이 명령어는 이미지를 변경할 수 있게 해준다. 만일 이 명령어가 존재하지 않는다면 다음과 같이 설치 해준다.

VMPlayer 이미지 옮기기 및 정보

여기서 한가지 조건이 존재한다. VMPlayer 를 이용해 VM 을 생성할때에 스토리지를 하나의 통 파일로 만들건지 아니면 여러조각의 파일로 조각해서 만들건지를 물어본다. 이 경우에는 스토리지 파일을 하나의 통 파일로 작성한 경우에 한 한다.

하나의 통파일로 작성할 경우에 VMPlayer 는 확장자 .vmdk 파일이 존재하게 된다. 이것을 KVM 리눅스 머신으로 옮겨준다. 옮겨준 파일은 qemu-img 명령어를 이용해 파일의 정보를 조회해 볼 수 있다.

VMPlayer 에서 스토리지를 생성할때에 30GiB 크기로 생성을 했으며, 사용하는 만큼만 실체적인 용량을 쓰도록 했기 때문에 5.06GiB 의 파일 크기를 가진다.

qcow2, raw 변경

qemu-img 를 사용해 KVM 이미지로 변경할 이미지 포맷을 지정할 수 있다. KVM 의 경우에 qcow2 나 raw 의 이미지를 지원한다. qcow2 의 경우에는 앞서 VMPlayer 파일 형식과 같이 총 용량은 정해져 있지만 사용하는 만큼만 실제 파일시스템에 반영이 된다. raw 는 그냥 전체 생성할때 지정한 용량이 파일 시스템에 반영이 된다.

qcow2 형식으로 변경은 다음과 같이 한다.

raw 형식으로 변경은 다음과 같다.

결론

qemu-img 명령어를 이용해 VMPlayer 의 이미지를 KVM 이미지로 변경이 가능하다. 변경 후에 VM 이미지를 Import 해 구동하면 정상적으로 OS 가 올라 온다.

KVM Image 용량 증설하기

KVM 가상화를 운영하고 있는데, 운영중인 VM 하나가 용량이 부족해지는 상황이 발생했다. KVM 가상화 VM 의 용량은 결국 이미지 파일 한개임으로 이 이미지 파일의 용량을 늘려주면 VM 의 용량이 사실상 늘어나는 것으로 생각했다.

하지만 현시점(2023) 에서 검색을 해보니 다양한 방법들이 존재했다. 그 중에는 VM 이미지를 로컬에 마운트해서 늘려주는 방법도 존재했지만 너무나 복잡해 보였다. 좀 더 쉬운 방법이 없을까 해서 검색한 결과 가장 쉬워보이는 것을 발견했고 이 방법으로 손쉽게 VM 용량을 늘리는데 성공했다.

VM 상태

용량을 늘리려는 VM 의 상태는 다음과 같다.

/dev/vda1 으로 파티션 하나로 보이지만 사실 SWAP 파티션도 존재한다. 이 SWAP 파티션의 /dev/vda2 디바이스이며 약 2G 용량을 차지한다.

VM 이미지 경로

VM 을 운영하는 Host 서버에서 VM 의 이미지가 어디에 있는지를 다음과 같이 살펴볼 수 있다.

VM 이미지 정보

VM 이미지의 정보를 아는 것은 매우 중요하다. VM 이미지의 타입이 존재하는데 raw, qemu 타입이다. 어떤 타입인지에 따라서 VM 이미지 용량을 늘리는 방법이 달라진다.

또, 가상 크기와 디스크 크기 정보 표시되는데 간혹 이 크기가 서로 다를 수가 있다.

기존 이미지 백업

혹시 모를 불상사를 방지하기 위해서 기존 이미지를 백업해 두자.

패키지 설치

VM 이미지를 늘리기 위한 작업을 위해서 필요한 패키지를 설치 해준다. 설치는 환경이 RedHat 기반이기 때문에 dnf 명령어로 설치를 하였다. 설치하는 패키지 이름은 배포판마다 다를 수 있다.

이 패키지를 설치하게 되면 virt-resize 명령어를 사용할 수 있다.

VM 이미지 디스크 정보

앞에서 VM 이미지 정보를 표시했다면 이제는 이미지 안에 디스크 정보를 봐야 한다. 각각 설치한 방법이 다르고 파티션 정보도 다르기 표시 되기 때문에 이를 잘 파악해야 한다.

VM 이미지 내의 디스크 정보는 다음과 같이 알 수 있다.

단일 파티션 /dev/sda1 만 보이지만 virt-df 명령어의 한계로 보인다. 왜냐하면 SWP 파티션도 존재하기 때문인데, 이 SWAP 파티션은 표시되지 않았다.

virt-filesystems 명령어를 통해서 이를 정확하게 알 수 있다.

위 정보를 보면 전체 50G 에 /dev/sda1 과 /dev/sda2 로 나뉘어 있다. /dev/sda2 는 swap 파티션으로 virt-df 일때는 나오지 않았다.

용량 증설을 위한 이미지 생성

다음과 같이 백업한 이미지를 가지고 작업을 진행한다.

이 작업은 매우 중요하다. truncate 명령어를 이용하는 것인데, -r 옵션으로 용량 증설을 위한 이미지를 만들었다. 그리고 그 이미지에 용량 증설을 설정한다. 여기서는 10G 용량을 늘린다

루트(/) 피티션 /dev/sda1 크기 변경

VM 이미지 내의 파티션 정보는 /dev/sda1 으로 보인다. 여기서 주의해야 할 것은 VM 이 가동된 후에 이미지 정보의 디바이스 이름은 /dev/vda1 으로 다르다. virt-df 혹은 virt-filesystems 나온 내용을 기반으로 디바스 이름을 정해야 한다.

용량 증설은 루트 파티션만 하면 됨으로 /dev/sda1 의 크기를 변경할 것이다.

변경 요약을 보면 /dev/sda1 의 용량이 증설될 것인데, 이 파티션의 파일시스템이 ext4 임으로 resize2fs 방법을 이용해서 크기가 확장될 것임을 알려주고 있다.

진행 상태를 보면 Copying /dev/sda1 으로 나오고 실행 명령어에서 변경전 이미지와 truncate 명령어로 새롭게 생성한 이미지를 인자로 줬는데, 아마도 변경전 이미지를 truncate 명령어로 새롭게 생성한 이미지에 순차적인 복사를 하는 것으로 보인다.

이미지 용량에 따라서 작업 시간는 차이를 보일 것이다.

새로운 이미지로 VM 시작한 후 파티션 확인

/mnt7/ubuntu20.04-new.img 이미지로 VM 을 부팅한다. 그리고 난 후 다음과 같이 파티션 용량이 늘었는지 체크한다.

용량이 10G 늘었다.

파일시스템 용량을 봐 본다.

앞에서 변경 요약을 보면 파일시스템이 뭔지를 파악하고 거기에 맞게 파티션 Resize 작업도 해주는 것으로 보인다. ext4 의 경우 resize2fs, XFS 의 경우에는 xfs_growfs 을 사용하는데 이런 작업은 파티션의 크기를 변경하는 것으로 VM 이미지 용량 증설과 함께 해준다.

따라서 별도의 파티션 용량 증설작업은 필요하지 않다.

virsh 를 통해 Ubuntu 20.04 에 console 로 접속하는 방법

KVM 가상화 시스템에서 virsh 를 통해 Ubuntu Guest OS에 Console 로 접속하는 방법은 다양한데 대부분 grub 부팅 옵션을 손보는 것이 였다. 하지만 Ubuntu 20.04 로 넘어오면서 이 방법이 훨씬 간단해 졌다.

먼저 Ubuntu 20.04 Guest 에 접속한 후에 다음과 같이 입력 하면 끝난다.

이렇게 한 후에 KVM 시스템에서 console 접속을 하면 접속이 잘된다.

이 방법은 18.04 에서도 가능하다.

UBUNTU 18.04 KVM 게스트에 콘솔 접속하기

KVM 가상화를 사용하고 있고 게스트로 Ubuntu18.04 를 사용하고 있다면 콘솔 접속을 위해서는 다음과 같이 해주어야 한다.

/etc/default/grub 편집

grub 에서 ttyS0 에 콘솔 접속이 되도록 다음과 같이 편집해 준다.

위와같이 편집을 한 후에 grub 을 다시 작성해준다.

위와같이 설정을 하고 재부팅을 한 후에 KVM 콘솔 접속을 하면 아주 잘 된다.

UBUNTU 14.04 KVM 게스트에 콘솔 접속하기

KVM 가상화를 사용하고 있고 게스트로 Ubuntu14.04 를 사용하고 있다면 콘솔 접속을 위해서는 다음과 같이 해주어야 한다.

ttyS0 터미널 설정

KVM 게스트인 Ubuntu14.04 에 콘솔로 접속하기 위해서는 게스트 Ubuntu14.04 에 ttyS0 터미널로 접속을 해야 한다. 그런데 Ubuntu 14.04 에는 ttyS0 터미널 설정이 되어 있지 않아 이를 설정을 해야 한다.

/etc/init/ttyS0.conf 파일을 다음과 같이 생성한다.

 

그리고 다음과 같이 /etc/securetty 파일에 ttyS0 를 추가 해준다.

 

/etc/default/grub 편집

이제 grub 에서 ttyS0 이 콘솔 접속이 되도록 다음과 같이 편접해 준다.

위와같이 편접을 한 후에 grub 을 다시 시작해 줍니다.

 

위와같이 설정을 하고 재부팅을 한 후에 KVM 콘솔 접속을 하면 아주 잘 됩니다.

 

KVM에 Bridge Network 설정

CentOS 6 에는 가상화로 KVM만 지원합니다. Xen은 빼버렸습니다. 가상화로 KVM을 하게되면 사용할 수 있게됩니다. 그런데, KVM을 활성화하게 되면 virbr0 라는 가상의 이더넷이 생성이되는데 이것이 NAT로 동작하게 됩니다. 그러니까 KVM의 게스트들은 virbr0 의 NAT를 이용해서 인터넷을 하게 되는 것입니다.

그런데 제가 집에서 사용하는 인터넷 사용환경은 공유기를 이용해서 각 피시에서 private ip 주소를 할당해서 사용합니다. 그래서 KVM의 게스트들도 직접 공유기로 부터 private ip 주소를 할당 받기를 원했습니다. 그렇게 하기위해서는 virbr0 를 NAT를 정지시키고 br0 을 만들어서 eth0와 br0를 Bridged 시키면 됩니다.

이 문서는 이것을 설명한 것입니다.

처음 KVM을 설치해서 보면 다음과 같이 나옵니다. NAT로 동작하고 있다는 증거입니다.

Bridged 로 바꿔보겠습니다. 절차는 다음과 같습니다.

  1. virbr0 를 지웁니다.
  2. eth0 에 dhcp 기능을 지우고 br0 로 Bridged 한다.
  3. br0 만드는데, dhcp 로 아이피를 새로 받도록 한다. TYPE 를 Bridged 로 해준다.

Virbr0 를 지운다. 

버추얼쉘(virsh) 명령어를 이용해 네트워크 리스트를 봅니다.

버추얼 네트워크 이름이 ‘default’로 나오네요. 이것을 지우겠습니다.

eth0 의 dhcp 를 지우고 br0 로 Bridged 한다.

다음과 같이 합니다.

br0 를 만든다.

다음과 같이 합니다.

위과정을 거치면 설정은 끝납니다. 한가지 더 있는데, 리눅스의 NetworkManager 데몬을 꺼주고 network 서비스를 다시 올려줍니다.

이제 virt-manager 로 KVM 게스트를 설치할 다음과 같이 이더넷을 설정해 주면 됩니다.

Virt-Manager 에서 Br0 설정

 

Ubuntu 16.04 KVM 게스트에 콘솔 접속하기

KVM 가상화를 사용하고 있고 게스트로 Ubuntu16.04 를 사용하고 있다면 콘솔 접속을 위해서는 Grub2 설정을 다음과 같이 해주면 된다.

위와같이 해주고 다음과 같이 grub 을 갱신해준다.

 

가상 Guest 이미지 마운팅

가상 Guest OS의 이미지를 마운트하는 법을 설명합니다. 이미지 마운트에는 두가지 방법이 있습니다.

첫번째방법

1.Guest OS 이미지에 파티션으로부터 디바이스 맵(Device Map)을 생성합니다.

2.볼륨(Volume) 그룹을 스캔합니다.

이렇게 볼륨이 잡히면 이 방법은 유효합니다. 그렇지 않으면 두번째 방법을 사용해야 합니다.

3.볼륨(volume) 그룹의 속성을 바꿉니다.

볼륨의 상태를 확인합니다.

4.이제 볼륨을 마운팅하면 됩니다.


이렇게 마운트가 되면 마운트 포인터(Mount Point)를 통해서 접근할 수 있습니다. 언마운트(Umount)는 다음과 같이 합니다.

5.언마운트(Unmount) 합니다.

6.볼륨속성을 바꿉니다.

7.디바이스 맵을 지웁니다.

두번째 방법

두번째 방법은 위의 첫번째 방법 2번째에서 오류가 날경우에 사용하면 됩니다. 즉, 볼륨을 스캔했는데 볼륨이 없다면 바로 마운팅하는 것입니다.

1.Guest OS 이미지에 파티션으로부터 디바이스 맵(Device Map)을 생성합니다.

2.볼륨 그룹을 스캔합니다.

이렇게 볼륨 그룹이 없다고 나옵니다.

3.그냥 마운트를 하면 됩니다.

4.Unmount 는 다음과 같이 합니다.

 

KVM Ubuntu 가상머신에 콘솔 접속하기

Ubuntu 를 KVM 가상머신으로 설치를 했다면 콘솔 접속을 해보면 안됩니다. 지난번에 CentOS6/7 배포판에서의 가상머신 콘솔접속에 대해서 다루어 었는데, Ubuntu 는 이들과 조금 다르기에 포스팅 해봅니다.

이 글은 ubuntu 14.04 를 대상으로 합니다.

처음 Ubuntu 를 KVM 가상머신으로 설치를 했다면 SSH 나 Virt-manager 나 vnc 를 이용해서 접속을 해야만 합니다. 그래야 콘솔접속을 위한 설정을 해볼 수 있습니다.

GRUB 설정

공통 Grub 설정은 /etc/default/grub 에 있습니다. 다음과 같이 설정을 해줍니다.

그리고 다음과 같이 업데이트를 해줍니다.

Serial 콘솔 만들기

다음과 같이 Serial 콘솔을 만들어 줍니다.

그리고 ttyS0.conf 파일을 다음과 같은 부분을 편집해 줍니다.

위와같이 수정해주고 리붓을 해줍니다.

테스트

Ubuntu 가상머신을 재부팅한 후에 호스트 서버에서 다음과 같이 콘솔 접속을 해봅니다. 그러면 다음과 같이 나오면 성공 입니다.

Enter 를 여러번 쳐주면 나옵니다.