📌 KVM (Kernel-based Virtual Machine) – CLI 환경에서 사용하기
KVM은 Linux 기반의 가상화 솔루션으로, CLI(Command Line Interface)에서 virsh, virt-install, virt-builder 등의 명령어를 사용하여 VM을 관리할 수 있음.
🎯 GUI 환경에서 VM 및 네트워크를 생성하고 관리했던 것들을 CLI 환경에서 할 것.
virsh list - 동작중인 VM들의 목록
--all : 모든 VM(도메인) 목록
실습
[root@kvm11 ~]# cd /etc/libvirt/qemu/

[root@kvm22 ~]# cd /etc/libvirt/qemu/

kvm1에는 vyos.xml과 vyosrm.xml이 없는 이유는?
- 전에 우리가 했던 migration에서 kvm11에 있던 것을 kvm22로 옮겨줬기 때문임

# vm1을 GUI환경에서 삭제

virsh define : xml 파일로부터 도메인을 정의
[root@kvm qemu]# virsh define vm2.xml
# 정의할 때는 xml 파일명으로 정의
[root@kvm qemu]# virsh undefine vm1
# 정의한 vm을 삭제할 때는 도메인의 이름으로 하면 됨
[root@kvm ~]# cd /etc/libvirt/qemu/
- 도메인이 정의된 파일들의 목록 확인 가능.
[root@KVM1 ~]# ls /remote
os test.txt vm
[root@KVM1 ~]# virsh

[root@KVM1 ~]# virsh list
- 내가 갖고 있는 virtual들을 볼 수 있음

[root@KVM1 ~]# virsh list --all

[root@KVM1 ~]# cd /etc/libvirt/qemu/
- 도메인의 정의된 파일들의 목록 확인 가능
[root@KVM1 qemu]# ls
networks vyos.xml
[root@KVM1 qemu]# vi vyos.xml
- 내가 만든 파일이 어디 네트워크를 사용하고 있는지? 볼 수 있음

- vm 1을 생성 후 복사

- 그리고 삭제 했을 때

- 복사한 파일만 남았음

- xml 파일로부터 도메인을 정의함
[root@KVM1 qemu]# virsh define vm2.xml

- 복사했기 때문에 원래는 vm2지만 vm1로 보임

- 정의할 때는 파일명으로 하는 게 좋음
[root@KVM1 qemu]# virsh undefine vm1
Domain vm1 has been undefined
- virt-install로 도메인 정의
[root@KVM1 qemu]# virt-install --name=vm3 --vcpus=2 --memory=512 --os-variant=debian10 \
> --cdrom=/remote/os/vyos.iso --network bridge=br0 --graphic=vnc --noautoconsole \
> --disk path=/remote/vm/vm3.img,size=5
# > 따라 치는 거 아님 \하고 enter 하면 다음 줄로 넘어감

위에 명령어가 의미하는 것을 나타내보면

# --vcpus=2 --memory=512

# --cdrom=/remote/os/vyos.iso

# --os-variant=debian10


# --disk path=/remote/vm/vm3.img, size=5
# --graphic=vnc : 콘솔화면 출력 방식
# --noautoconsole : vm은 생성하되, 접속하진 않음
-라는 위의 과정을 명령어로 끝낸 것

- vm3가 새로 생성된 걸 확인할 수 있음

- vm3 콘솔 안으로 들어감

- 위에서 나타내는 ^는 콘솔을 의미함(ctrl)
- 콘솔화면에서 빠져나오고 싶으면 Ctrl + ]

- vm을 완전히 삭제하고 싶다면 destroy 하고 undefine 해주기
[root@KVM1 qemu]# virsh destroy vm3
[root@KVM1 qemu]# virsh undefine vm3


- 삭제가 잘 된 걸 확인할 수 있음

https://download.cirros-cloud.net/
Index of /
download.cirros-cloud.net
cirros



- 잘 설치된 걸 확인하고 이름 변경
/remote/vm
[root@KVM1 vm]# ls
cirros-0.5.2-x86_64-disk.img networks vm2.xml vyos.xml
[root@KVM1 vm]# mv cirros-0.5.2-x86_64-disk.img cirros.img
[root@KVM1 vm]# cp cirros.img c1.img
[root@KVM1 vm]# cp cirros.img c2.img

vm으로 넘어가서
- 원래 있던 파일을 불러올게

- 이 파일을 불러올게








- kvm에서 만든 네트워크들에 대한 xml이 있는


- kvmnet1은 예전에 gui환경에서 생성한 네트워크
-> 우리가 몇몇 정보를 제외하고 비슷하게 xml을 구성한다면 네트워크를 정의할 수 있을 것임
[root@KVM1 networks]# cp kvmnet1.xml kvmnet2.xml
[root@KVM1 networks]# vi kvmnet2.xml
- kvm1을 복사한 걸 내용 수정해 주고 uuid나 맥주소 삭제

root@KVM1 networks]# virsh net-define kvmnet2.xml

[root@KVM1 networks]# virsh net-start kvmnet2
[root@KVM1 networks]# virsh net-autostart kvmnet2


- GUI 상에서도 네트워크가 잘 만들어진 걸 확인 가능함.

- 빨간 상자만 확인하면 잘 된 걸 확인할 수 있음.
[root@KVM1 networks]# virt-install --name=c2 --memory=512 --vcpu=2 --network network=kvmnet2 --disk=/remote/vm/c2.img --import --noautoconsole --graphic=vnc
실습) CLI환경에서 비슷한 방식으로 kvm 서버에 kvmnet3 대역을 192.168.3.0/24로 구성하되 dhcp를 활성화하여 kvmnet3에서 생성되는 vm들이 dhcp로 아이피를 받아오도록 해보세요.
c3.img를 통해 생성된 vm이 dhcp로 아이피를 잘 받아왔나 확인해 보세요.
정리)
1. kvmnet3 대역을 192.168.3.0/24로 구성
2. 네트워크 적용
3. c3.img vm 생성
4. VM내부에서 DHCP로 IP 확인
5. DHCP 할당된 IP확인
[root@KVM1 networks]# cp kvmnet2.xml kvmnet3.xml
[root@KVM1 networks]# vi kvmnet3.xml


[root@KVM1 vm]# cp c2.img c3.img
[root@KVM1 vm]# cp /remote/vm/cirros.img /remote/vm/c3.img
virt-install --name=c3 --memory=512 --vcpu=2 --network network=kvmnet3 --disk=/remote/vm/c3.img --import --noautoconsole --graphic=vnc

- 이 상태에서 당황하지 말고 기다리면

- 잘 된 걸 확인할 수 있음

- 최초의 부팅되지 않은 이미지와 부팅되어 VM정보가 포함된 이미지는 용량부터가 많은 차이가 남.
[root@KVM1 networks]# virsh migrate --unsafe --live c3 qemu+ssh://211.183.3.60/system

kvm2
[root@kvm2 ~]# cd /etc/libvirt/qemu/networks
<network>
<name>kvmnet3</name>
<bridge name='virbr3' stp='on' delay='0'/>
<domain name='kvmnet3'/>
<ip address='192.168.3.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.3.100' end='192.168.3.200'/>
</dhcp>
</ip>
</network>
[root@kvm2 networks]# virsh net-define kvmnet3.xml
[root@kvm2 networks]# virsh net-start kvmnet3
[root@kvm2 networks]# virsh net-autostart kvmnet3
kvm1

# kvm2라는 호스트네임을 못 찾고 있다.
[root@kvm networks]# vi /etc/hosts

# 작은 dns인 /etc/hosts에 kvm2의 주소를 안내


[root@kvm networks]# virsh migrate --unsafe --live --verbose --persistent --undefinesource c1 qemu+ssh://211.183.3.60/system
# --verbose : 진행상황 표시
# --persistent : 영구적으로
# --undefinesource : shutdown 된 vm을 남기지 않는

vm의 커스텀이미지를 제작
: 내가 원하는 정보를 넣는 커스텀 이미지를 생성 (나만의 AMI와 비슷)
[root@KVM1 networks]# yum install -y libguestfs*
- virt-builder라는 명령을 통해 말 그대로 이미지를 빌드할 예정임

[root@KVM1 networks]# virt-builder

[root@KVM1 networks]# virt-builder --list
- 밑에 내용이 나오는데 오래 걸리는 편 임/ 대략 2~3분?

[root@KVM1 networks]# virt-builder centos-7.8 --size=7G --format=qcow2 -o /remote/vm/cent7.img --root-password password:test123
# -o : 아웃풋(저장될 디스크 이미지)
# centos-7.8 이미지를 베이스로 하여 크기가 7GB인 qcow2 형식의 디스크를 만들어서 /remote/vm 경로에 cent7.img로 저장을 시키겠다. root계정의 암호는 test123으로 정하겠음.

[root@kvm networks]# cp /remote/vm/cent7.img /remote/vm/cen1.img
# 순수한 이미지는 그대로 두고 복사를 해서 쓰자.
[root@kvm networks]# virt-install --name=cen1 --vcpus=2 --ram=2048 --network bridge=br0 --disk=/remote/vm/cen1.img --import --noautoconsole --graphic=vnc
[root@kvm networks]# virsh console cen1
# 생성한 vm에 콘솔 접속

- localhost 위치에 있는 걸 확인할 수 있음.


- vmnet8의 dhcp를 활성화해서 cen1이 IP를 부여받는지 보자.

- 버추얼 네트워크 에디터로부터 IP를 잘 부여받음

초기 설정
sed -i s/SELINUX=enforcing/SELINUX=disabled/g /etc/selinux/config
reboot
systemctl stop firewalld
systemctl disable firewalld
cat <<EOF> /etc/yum.repos.d/CentOS-Base.repo
[base]
name=CentOS-$releasever - Base
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&infra=$infra
baseurl=https://vault.centos.org/7.9.2009/os/x86_64/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
#released updates
[updates]
name=CentOS-$releasever - Updates
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates&infra=$infra
baseurl=https://vault.centos.org/7.9.2009/updates/x86_64/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras&infra=$infra
baseurl=https://vault.centos.org/7.9.2009/extras/x86_64/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=centosplus&infra=$infra
baseurl=https://vault.centos.org/7.9.2009/centosplus/x86_64/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
#contrib - packages by Centos Users
[contrib]
name=CentOS-$releasever - Contrib
#mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=contrib&infra=$infra
baseurl=https://vault.centos.org/7.9.2009/contrib/x86_64/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
[root@localhost ~]# yum install -y httpd
[root@localhost ~]# systemctl restart httpd
[root@localhost ~]# echo vmtest > /var/www/html/index.html
[root@localhost ~]# curl localhost
vmtest

# 브라우저에서도 접속이 잘 되더라.
localhost에서 벗어나기 위해 ctrl + ]
virt-builder로 생성한 cent7.img는 순수한 이미지 파일.
- 이미지로 들어가는 명령어 인지, 아님 boot를 생성할 때 들어가는 이미지인지 구분하는 것이 중요함
1번과 2번의 차이를 이해하는 게 중요함. 이미지에 들어가는 건지, 아니면 이미지로부터 vm이 생성될 때 들어가는 건지.

[root@kvm11 ~]# cd /etc/libvirt/qemu/networks
kvm1
[root@KVM1 networks]# cp /remote/vm/cent7.img /remote/vm/cen2.img
[root@KVM1 networks]# cp /remote/vm/cent7.img /remote/vm/cen3.img
# 추가로 두 개의 이미지를 더 복사
virt-customize
: virt-builder로 생성된 순수한 이미지에 설정을 추가.
[root@kvm networks]# virt-customize -a /remote/vm/cen2.img --firstboot-command \
> 'systemctl disable firewalld && systemctl stop firewalld'
# 방화벽을 끄고 비활성화하는 명령어 추가.
[root@kvm networks]# virt-install --name=cen2 --vcpus=2 --ram=2048 --network bridge=br0 --disk=/remote/vm/cen2.img --import --noautoconsole --graphic=vnc
# 설치 후 진입하여 방화벽이 꺼져있는지 확인.

[root@kvm networks]# virsh console cen2
- 잘 꺼져 있는 걸 확인 가능함

--firstboot-command : 이미지를 처음 부팅했을 때 실행할 명령어
--firstboot-install : 이미지 첫 부팅 시 설치하는 명령어.
virt-customize를 통한 관리자 암호 변경.
[root@kvm11 ~]# cd /etc/libvirt/qemu/networks
[root@KVM1 networks]# cp /remote/vm/cent7.img /remote/vm/cent7-1.img
[root@KVM1 networks]# virt-customize -a /remote/vm/cent7-1.img --root-password password:test1234

[root@kvm networks]# virt-install --name cent7-1 --ram=2048 --vcpus=2 --network bridge=br0 --disk=/remote/vm/cent7-1.img --import --noautoconsole --graphic=vnc
[root@kvm networks]# virsh console cent7-1

key pair
kvm이 private key를 갖고 있는 상태인데
cent7-1에는 /.ssh/authorized_keys에 연결함
# kvm 호스트를 ssh-client, cent7-1이라는 VM을 ssh-server로 하여 암호인증 없이 키페어 인증으로 ssh 접속을 하고 싶음
- 이 상태로 만들어주고 실행할 예정.


- 다 enter치면 자동으로 암호가 생성됨

- 랜덤 암호 생성


- 키 암호를 복사해서 localhost에 만들어줄 것 임

localhost
[root@localhost ~]# mkdir ~/. ssh
[root@localhost ~]# vi ~/.ssh/authorized_keysmkdir

- 혹시 모르니까 localhost의 비밀번호를 확인해 보고

kvm1
- 비밀번호 치라는 문구 없이 잘 로그인되는 걸 확인할 수 있음

실습) --upload 를 비롯한 virt-builder --help 목록에 나오는 명령어들을 활용하여 암호설정 없이 접속가능한 cent-ssh.img 이미지를 만들어보세요. (베이스이미지 - centos7.9) 방식은 여러 가지가 있을 수 있음. 위에서 수동으로 했던 설정(퍼블릭키 복사)을 아예 이미지화하라는 뜻.
--selinux-relabel : 혹시 이미지생성할 때 셀리눅스 관련 에러가 뜬다면 이 옵션을 붙이세요.
정리)
리다이렉션(Redirection)이란?
리다이렉션(Redirection)은 어떤 입력이나 출력을 다른 곳으로 보내는 것을 의미함.
예를 들어,
- 웹에서 리다이렉션 → 사용자가 A 사이트에 접속했지만 자동으로 B 사이트로 이동함
- 리눅스 명령어에서 리다이렉션 → 명령어의 출력 결과를 파일에 저장하거나 다른 명령어로 전달함
[root@KVM1 ~]# cd /etc/libvirt/qemu/networks/
[root@KVM1 networks]# cp /remote/vm/cent7.img /remote/vm/cent7.9.img
[root@KVM1 networks]# virt-customize -a /remote/vm/cent7.9.img --root-password password:test1234 --selinux-relabel
--selinux-relabel : 혹시 이미지생성할 때 셀리눅스 관련 에러가 뜬다면 이 옵션을 붙이세요. ssh 접속 시 암호 안 묻게 할 때도 이 옵션을 꼭 붙여주세요.
[root@KVM1 networks]# virt-install --name cent7.9 --ram=2048 --vcpus=2 --network bridge=br0 --disk=/remote/vm/cent7.9.img --import --noautoconsole --graphic=vnc
[root@KVM1 networks]# virsh console cent7.9
[root@KVM1 networks]# cat ~/.ssh/id_rsa.pub
[root@localhost ~]# mkdir ~/.ssh
[root@localhost ~]# vi ~/.ssh/authorized_keys
- authorized_keys 이름을 똑같이 해줘야 됨
[root@localhost ~]# ip add

[root@KVM1 networks]# ssh root@211.183.3.133
이건 수동으로 입력한 실습이고 문제에서 원한 건 virt-builder를 사용하여 CentOS 7.8 이미지를 사용하는 것
[root@KVM1 networks]# virt-builder centos-7.7 \
> --size 10G \
> --format qcow2 \
> --output cent7.7.img \
> --hostname cent7.8 \
> --root-password password:test1234 \
> --ssh-inject root:file:/root/. ssh/id_rsa.pub \
> --selinux-relabel
위의 코드 설정
[root@KVM1 networks]# virt-builder centos-7.7 \
✔ virt-builder centos-7.8 → CentOS 7.8 베이스 이미지 사용
> --size 10G \
✔ --size 10G → 이미지 크기 10GB
> --format qcow2 \
✔ --format qcow2 → QEMU/KVM용 qcow2 포맷
> --output cent7.7.img \
✔ --output cent7.7.img → 최종 생성 파일 이름
> --root-password password:test1234 \
✔ --root-password password:centos → root 비밀번호 설정 (centos)
> --hostname cent7.8 → VM의 호스트네임 설정/ 7.7로 해야될 걸 7.8로 한 바보.
✔ --hostname cent-ssh → VM의 호스트네임 설정
> --ssh-inject root:file:/root/.ssh/id_rsa.pub \
✔ --ssh-inject root:file:/root/.ssh/id_rsa.pub → SSH 키 자동 삽입
> --selinux-relabel
✔ --selinux-relabel → SELinux 오류 방지 (필요한 경우 추가)

- 실수로 network에서 설치했음, 원래는 vm임
[root@KVM1 networks]# virt-install --name cent7.7 --ram=2048 --vcpus=2 --network bridge=br0 --disk=cent7.7.img --import --noautoconsole --graphic=vnc
ip add

[root@KVM1 ~]# ssh root@211.183.3.134

- 암호 입력 없이 넘어가는 걸 확인할 수 있음
자율 과제) centos-7.8을 베이스이미지로 하여 커스터마이징 된 이미지로 VM을 생성했을 때 해당 vm의 주소로 웹브라우저 접속 시 KVM is easy라는 문구가 뜨도록 해보세요.
풀이)
centos7 자체가(iso는 물론 img파일들도) 레포지토리에 문제가 있다. 따라서 레포를 수정해 줘야 httpd 설치가 가능할 것 임.
[root@kvm vm]# cp cent7.img repo.img
virt-customize -a /remote/vm/repo.img --selinux-relabel --upload /etc/yum.repos.d/CentOS-Base.repo:/etc/yum.repos.d/CentOS-Base.repo --firstboot-install httpd --firstboot-command 'echo kvm is easy > /var/www/html/index.html' --firstboot-command 'systemctl disable --now firewalld && systemctl enable --now httpd'
# 이미지커스터마이징.
# 베이스이미지를 업로드
# 호스트에서 게스트이미지에 파일 같은 것들을 복사하거나 할 때, 이미 해당파일이 존재하는 경우 어떻게 될지만 조금 신경 쓰면 된다.(덮어쓰기가 될지, 이미 파일이 존재해서 실패 등등..)
# 결국 이미지를 생성 후 잘 되는지 검증(테스트)만 잘하면 된다.
virt-install --name repo --ram=2048 --vcpus=2 --network bridge=br0 --disk=/remote/vm/repo.img --import --noautoconsole --graphic=vnc
# VM 생성

# 콘솔 접속 후 ip를 알아낸 다음 웹브라우저로 접속해서 확인.
'AWS Cloud School 8기 > 서버가상화_클라우드 이미지' 카테고리의 다른 글
Open vSwitch/ openvswitch 실행 안될 때 (2) | 2025.03.06 |
---|---|
KVM(Kernel-Based Virtual Machine)/ kvmnet (5) | 2025.02.20 |
Site-to-Site VPN (2) | 2025.02.17 |
Server-Client VPN/ 와이파이 대역 활용한 실습 (0) | 2025.02.13 |
VyOS 실습 (코드만) (1) | 2025.02.11 |