KVM Host에서 virsh을 통해 CLI 모드만으로 Linux VM을 컨트롤하는 방법을 기술한다.
운영상 원격에서 GUI를 띄우기 힘든 환경에서 CLI 모드를 사용하면 유용하다.
본인의 테스트 시스템(테스크탑, Intel i3-8100 기반)에는 VMWare ESXi 6.7 U2가 설치되어 있으며,
이 문서대로 진행 시 위와 같은 VM 스택으로 구성된다. (TYPE 1)
ESXi 위에 CentOS 7 KVM Host VM을 설치 후 virsh를 이용해 CentOS 7 VM을 설치하는 것을 설명한다.
목차
1. CentOS 7 KVM Host VM 구성
1.1 ESXi에 CentOS 7 VM을 설치
마이너 버전은 크게 상관없고 여기서는 CentOS 7.7 minimal을 설치 진행함.
ESXi에서 아래와 같은 스펙으로 VM을 생성
- CPU : 2EA
- MEM : 8G
- HDD : 32G
- NIC : 1EA (Bridged)
OS Install 진행에서 Timezone과 root password 설정해서 설치를 진행한다.
♦ ESXi Host 대신 다른 Hypervisor를 사용해도 무방하다. Linux 기반 KVM도 괜찮다. (아래 TYPE 1-2, TYPE 3의 형태가 되겠다.)
1.2 CentOS 7 VM 기본 구성
1) Selinux Disable 처리
[root@KVM-HOST ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
2) 네트워크 활성화
[root@KVM-HOST ~]# sed -i 's/ONBOOT=no/ONBOOT=yes/g' /etc/sysconfig/network-scripts/ifcfg-ens192
⇒ 장치명에 따라 ifcfg-ens192 부분은 수정이 필요할 수 있다.
⇒ 공유기의 dhcp 서버로부터 ip를 자동으로 받는다는 전제로 dhcp client 설정으로 진행. 본인의 네트워크 환경에 따라 static 설정이 필요할 수 있다.
3) 리부팅
[root@KVM-HOST ~]# reboot
2. KVM-HOST의 KVM 구성
2.1. KVM 설치 및 환경 구성
1) KVM 인스톨
[root@KVM-HOST ~]# yum install qemu kvm qemu-kvm libvirt virt-install bridge-utils virt-manager dejavu-lgc-sans-fonts virt-viewer libguestfs-tools
2) libvirtd 구동 및 시작서비스 등록
[root@KVM-HOST ~]# systemctl start libvirtd [root@KVM-HOST ~]# systemctl enable libvirtd
⇒ 구동 시 virbr0 이름으로 vNIC이 생성된다. 이 vNIC은 NAT로 동작이 된다. 즉, 생성되는 VM에게 이 vNIC을 통해 NAT IP를 제공한다.
3) VM 이미지 디렉토리 생성
[root@KVM-HOST ~]# mkdir /home/vm-images [root@KVM-HOST ~]# chown qemu.qemu /home/vm-images
⇒ VM 이미지(qcow, qcow2, raw) 파일이 위치할 곳
4) ISO 저장소 디렉토리 생성
[root@KVM-HOST ~]# mkdir /home/iso [root@KVM-HOST ~]# chown qemu.qemu /home/iso
⇒ 해당 디렉토리의 권한이 qemu 유저에게 부족하면 vm install 시 permission 에러가 발생될 수 있다.
2.2 환경 구성 및 브릿지 네트워크 구성
1) ISO 파일 업로드
CentOS-7-x86_64-Minimal-1804.iso 파일을 /home/iso에 업로드
2) bridge vNIC 생성
기존 NIC의 config 파일에 설정 추가
[root@KVM-HOST ~]# vi /etc/sysconfig/network-scripts/ifcfg-ens192 BRIDGE=br0
br0 vNIC config 파일 생성
[root@KVM-HOST ~]# vi /etc/sysconfig/network-scripts/ifcfg-br0 NAME="br0" DEVICE="br0" BOOTPROTO="dhcp" IPV6INIT="yes" IPV6_AUTOCONF="yes" ONBOOT="yes" TYPE="Bridge" DELAY="0"
⇒ 이렇게 설정 후 network를 restart 하면
[root@KVM-HOST ~]# systemctl restart network
아래와 같이 NIC가 확인된다.
[root@KVM-HOST ~]# ip -4 -c a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000 inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 valid_lft forever preferred_lft forever 12: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 inet 192.168.0.12/24 brd 192.168.0.255 scope global noprefixroute br0 valid_lft forever preferred_lft forever
⇒ libvirtd를 구동하면 생성되는 virbr0 vNIC (VM NAT 제공용)은 그대로 있고
⇒ ens192 NIC는 사라지고 br0 vNIC가 대신하게 된다. 기존에 dhcp로 받았던 192.168.0.12 ip를 그대로 유지한다.
만약 br0에 static ip로 설정하고 싶다면 아래와 같이 수정을 한다.
[root@KVM-HOST ~]# vi /etc/sysconfig/network-scripts/ifcfg-br0 NAME="br0" DEVICE="br0" BOOTPROTO="static" IPV6INIT="yes" IPV6_AUTOCONF="yes" ONBOOT="yes" TYPE="Bridge" DELAY="0" IPADDR=192.168.0.12 NETMASK=255.255.255.0 GATEWAY=192.168.0.1
2.3 vm 설치
1) virt-install 명령을 통해 vm install
[root@KVM-HOST ~]# virt-install \ --network bridge:br0 \ --name centos75 \ --ram=1024 \ --os-type=linux \ --os-variant=centos7.0 \ --vcpus=1 \ --disk path=/home/vm-images/centos75.qcow2,size=10,format=qcow2 \ --location /home/iso/CentOS-7-x86_64-Minimal-1804.iso \ --graphics none \ --extra-args="console=tty0 console=ttyS0,115200"
⇒ 옵션 설명 :
--graphics none
이 옵션에 의해 vm을 cli 모드로 설치를 할 수 있다. vnc로 지정하면 vnc를 통해 gui 접근도 가능하다.
- How to install KVM on CentOS 7 / RHEL 7 Headless Server
https://www.cyberciti.biz/faq/how-to-install-kvm-on-centos-7-rhel-7-headless-server/
--extra-args="console=tty0 console=ttyS0,115200"
이 옵션에 의해 cli 모드 이지만 VM의 console로 접근이 가능하다.
--location 옵션 대신 --cdrom 옵션을 줄 수 있지만 --extra-args 옵션을 병행시엔 --location 옵션으로만 설치 가능하다.
그 외 옵션은 virt-install --help 를 통해 확인 가능하다.
2) VM OS 설치 진행
iso를 통해 부팅이 진행된다. (KVM-HOST의 터미널 창에 vm의 콘솔이 자동으로 뜬다.)
[ OK ] Stopped target Switch Root. [ OK ] Stopped target Initrd File Systems. Starting Read and set NIS domainname from /etc/sysconfig/network... [ OK ] Listening on Delayed Shutdown Socket. [ OK ] Listening on LVM2 poll daemon socket. [ OK ] Created slice User and Session Slice. [ OK ] Listening on LVM2 metadata daemon socket. [ OK ] Created slice system-selinux\x2dpol...grate\x2dlocal\x2dchanges.slice. [ OK ] Listening on udev Kernel Socket. [ OK ] Reached target Timers. Mounting Debug File System... ~~ 중간 생략 ~~
그리고 cli 모드의 OS 설치 메뉴가 아래와 같이 뜬다.
Starting installer, one moment... anaconda 21.48.22.134-1 for CentOS 7 started. * installation log files are stored in /tmp during the installation * shell is available on TTY2 * when reporting a bug add logs from /tmp as separate text/plain attachments 12:24:24 Not asking for VNC because we don't have a network ================================================================================ ================================================================================ Installation 1) [x] Language settings 2) [!] Time settings (English (United States)) (Timezone is not set.) 3) [!] Installation source 4) [!] Software selection (Processing...) (Processing...) 5) [!] Installation Destination 6) [x] Kdump (No disks selected) (Kdump is enabled) 7) [ ] Network configuration 8) [!] Root password (Not connected) (Password is not set.) 9) [!] User creation (No user will be created) Please make your choice from above ['q' to quit | 'b' to begin installation | 'r' to refresh]: [anaconda] 1:main* 2:shell 3:log 4:storage-lo> Switch tab: Alt+Tab | Help: F1
⇒ Language settings, Time settings, Installation Destination, Root password 설정을 마치면 OS 설치가 진행된다.
3) vm의 console로 접근
MV OS 설치를 마치고 해당 VM의 Console에 다시 접근하려면
[root@KVM-HOST ~]# virsh console centos75 Connected to domain centos75 Escape character is ^]
⇒ 엔터를 한번 입력해 준다.
⇒ vm의 콘솔에서 빠져나오려면 Ctrl + ] 키를 입력한다.
[root@KVM-HOST ~]# virsh console centos75 Connected to domain centos75 Escape character is ^] CentOS Linux 7 (Core) Kernel 3.10.0-862.el7.x86_64 on an x86_64 localhost login: root Password: Last login: Mon Jul 6 16:07:23 on ttyS0 [root@localhost ~]#
⇒ CentOS 7.5 VM의 console로 root/pw 를 입려 후 로긴하면 [root@localhost ~]# 프롬프트가 떨어진다.
⇒ console로 접근 후 ip 설정을 하고서 ssh로 접속을 하여 다른 설정 등을 하면 되겠다.
3. kvm (virt) 명령 모음
3.1 virsh
virsh는 bash shell에서 옵션과 함께 명령을 수행하는 것 뿐만아니라 interactive terminal도 제공해 준다.
# virsh Welcome to virsh, the virtualization interactive terminal. Type: 'help' for help with commands 'quit' to quit virsh #
1) running중인 vm 리스트 출력
[root@KVM-HOST ~]# virsh list Id Name State ---------------------------------------------------- 1 centos75 running 5 centos75-2 running
2) 설치되어 있는 vm 리스트 출력
[root@KVM-HOST ~]# virsh list --all Id Name State ---------------------------------------------------- 1 centos75 running 5 centos75-2 running
3) 정상적인 shutdown process를 밟아서 vm OS를 끔
[root@KVM-HOST ~]# virsh shutdown centos75 Domain centos75 is being shutdown [root@KVM-HOST ~]# virsh list Id Name State ---------------------------------------------------- 5 centos75-2 running [root@KVM-HOST ~]# virsh list --all Id Name State ---------------------------------------------------- 5 centos75-2 running - centos75 shut off
⇒ list --all 옵션으로 확인 시 shutdown을 한 centos75는 shut off로 확인된다.
⇒ 아래 상황에서 shutdown 명령으로 전원이 꺼지지 않는 경우가 발생할 수 있다.
- vm에 전원 관리 패키지인 acpid가 없어서 (vm에 설치 필요)
- vm의 OS가 온전하게 부팅되지 않은 상태일 경우
4) 강제로 vm을 끈다.
[root@KVM-HOST ~]# virsh destroy centos75-2 Domain centos75-2 destroyed [root@KVM-HOST ~]# virsh list --all Id Name State ---------------------------------------------------- - centos75-2 shut off - centos75 shut off
⇒ 물리 시스템으로 치면 강제로 전원을 내린것과 같다.
⇒ virsh shutdown으로 shut off가 진행되지 않는다면 destory로 강제 shutdown을 수행한다.
⇒ host 시스템에서 실행 중인 vm의 qemu 프로세스를 kill 해도 vm이 강제 종료된다.
5) vm 영구 삭제
[root@KVM-HOST ~]# virsh undefine centos75-2 --remove-all-storage Domain centos75-2 has been undefined Volume 'vda'(/home/vm-images/centos75-2.qcow2) removed. [root@KVM-HOST ~]# virsh list --all Id Name State ---------------------------------------------------- - centos75 shut off [root@KVM-HOST ~]# ls -la /home/vm-images/centos75-2.qcow2 ls: cannot access /home/vm-images/centos75-2.qcow2: No such file or directory [root@KVM-HOST ~]# virsh edit centos75-2 error: failed to get domain 'centos75-2' error: Domain not found: no domain with matching name 'centos75-2'
⇒ 저장소의 qcow2 파일 및 구성 xml 파일 삭제됨. vm을 종료 후 진행해야 한다.
6) vm xml config 파일 수정
[root@KVM-HOST ~]# virsh edit cnetos75
vm의 xml config 파일들은 아래 디렉토리에 위치해 있다.
[root@KVM-HOST ~]# ls -la /etc/libvirt/qemu total 8 drwx------ 3 root root 64 Jul 6 22:02 . drwx------ 6 root root 230 Jul 6 15:12 .. -rw------- 1 root root 3841 Jul 6 22:02 centos75-2.xml -rw------- 1 root root 3834 Jul 6 15:31 centos75.xml drwx------ 3 root root 42 Jul 6 15:10 networks
7) xml dump
기존 xml 파일을 dump 하기
[root@KVM-HOST ~]# virsh dumpxml VM-NAME > /tmp/VM-Name.xml
VM을 등록 해제하고, 다시 등록
[root@KVM-HOST ~]# virsh undefine VM-Nanme [root@KVM-HOST ~]# virsh define /tmp/VM-Name.xml
⇒ 만약 VM의 환경구성을 수정하고 싶으면 xml 파일을 수정한 후 등록한다.
⇒ 이 방법은 VM의 이름을 변경하고자 할때에 쓰면 유용하다. (undefine 후 vm 이름 변경 -> define)
7) 네트워크
[root@KVM-HOST ~]# virsh net-list Name State Autostart Persistent ---------------------------------------------------------- default active yes yes [root@KVM-HOST ~]# net-info --network default Name: default UUID: b0c37760-515a-4d9f-8255-e983557808ae Active: yes Persistent: yes Autostart: yes Bridge: virbr0 [root@KVM-HOST ~]# virsh net-dhcp-leases default Expiry Time MAC address Protocol IP address Hostname Client ID or DUID ------------------------------------------------------------------------------------------------------------------- 2020-07-08 18:05:50 52:54:00:70:b8:3c ipv4 192.168.122.241/24 - - 2020-07-08 18:19:34 52:54:00:8a:01:70 ipv4 192.168.122.253/24 - -
⇒ default network (virbr0) dhcp 서버를 통해 vm에 할당된 NAT IP를 표시
8) storage pool
[root@KVM-HOST ~]# virsh list --all Id Name State ---------------------------------------------------- 112 vm003 running 113 vm004 running [root@KVM-HOST ~]# ls -la /home/vm-images/cent77/ total 7991696 drwxr-xr-x 2 root root 82 Jul 13 20:55 . drwxr-xr-x 3 root root 40 Jul 10 09:43 .. -rw------- 1 root root 1406533632 Jul 13 20:53 vm001.qcow2 -rw------- 1 root root 1406533632 Jul 13 15:36 vm002.qcow2 -rw------- 1 qemu qemu 1406533632 Jul 13 20:58 vm003.qcow2 -rw------- 1 qemu qemu 1406533632 Jul 13 20:58 vm004.qcow2 [root@KVM-HOST ~]# virsh pool-list Name State Autostart ------------------------------------------- cent77 active yes default active yes iso active yes vm-images active yes [root@KVM-HOST ~]# virsh vol-list cent77 Name Path ------------------------------------------------------------------------------ vm001.qcow2 /home/vm-images/cent77/vm001.qcow2 vm002.qcow2 /home/vm-images/cent77/vm002.qcow2 vm003.qcow2 /home/vm-images/cent77/vm003.qcow2 vm004.qcow2 /home/vm-images/cent77/vm004.qcow2 [root@KVM-HOST ~]# virsh vol-delete --pool cent77 vm001.qcow2 Vol vm001.qcow2 deleted [root@KVM-HOST ~]# virsh vol-delete --pool cent77 vm002.qcow2 Vol vm002.qcow2 deleted [root@KVM-HOST ~]# virsh pool-refresh cent77 Pool cent77 refreshed [root@KVM-HOST ~]# ls -la /home/vm-images/cent77/ total 5244680 drwxr-xr-x 2 root root 44 Jul 13 20:59 . drwxr-xr-x 3 root root 40 Jul 10 09:43 .. -rw------- 1 qemu qemu 1406533632 Jul 13 20:59 vm003.qcow2 -rw------- 1 qemu qemu 1406533632 Jul 13 20:59 vm004.qcow2 [root@KVM-HOST ~]# virsh vol-list cent77 Name Path ------------------------------------------------------------------------------ vm003.qcow2 /home/vm-images/cent77/vm003.qcow2 vm004.qcow2 /home/vm-images/cent77/vm004.qcow2
- Verify that the storage pool is defined:
# virsh pool-list
- Destroy the storage pool:
# virsh pool-destroy <pool_name>
- Undefine the configuration for the inactive storage pool:
# virsh pool-undefine <pool_nanme>
- Verify that the storage pool has been removed from the host:
# virsh pool-list
3.2 variant OS list
1) variant OS 리스트 출력
virt-install 명령의 --os-variant 옵션에 적용할 수 있는 OS List를 출력
[root@KVM-HOST ~]# osinfo-query os Short ID | Name | Version | ID ----------------------+----------------------------------------------------+----------+----------------------------------------- alpinelinux3.5 | Alpine Linux 3.5 | 3.5 | http://alpinelinux.org/alpinelinux/3.5 alpinelinux3.6 | Alpine Linux 3.6 | 3.6 | http://alpinelinux.org/alpinelinux/3.6 ~~ snip ~~ centos6.8 | CentOS 6.8 | 6.8 | http://centos.org/centos/6.8 centos6.9 | CentOS 6.9 | 6.9 | http://centos.org/centos/6.9 centos7.0 | CentOS 7.0 | 7.0 | http://centos.org/centos/7.0 cirros0.3.0 | CirrOS 0.3.0 | 0.3.0 | http://cirros-cloud.net/cirros/0.3.0
⇒ 예전에는 아래와 같은 명령으로 OS 리스트가 출력되었던 것으로 보이나 에러가 남. osinfo-query os 명령을 사용할 것.
[root@KVM-HOST ~]# virt-install --os-variant list ERROR --name is required
3.3. virt-viewer
shinjaehun@losttemple:~$ virt-viewer -c qemu:///system VM-NAME &
⇒ virt-viewer를 통해 vm을 보기 위해서는 아래 조건이 충족되어야 함.
- VM의 모드가 Graphic 이어야 함
- KVM Host에 'X Window System'이 설치되어 있어야함
- 터미널 클라이언트를 통해 virt-viewer를 띄우는 경우 x11-forwarding이 구성되어 있어야 함.
4. Remote에서 X 띄우기
KVM Host의 Run Level 3 모드에서 VM을 CLI로 운영할 수 있다.
물론 Windows OS를 Guest VM으로 이용 시 CLI로는 한계가 있다.
그럴 때는 단순히 X Window System만 설치하고 GUI는 Remote에서 띄우는 방식으로도 가능하다.
4.1 X Window 설치
[root@KVM-HOST ~]# yum groupinstall "X Window System" -y
4.2 터미널 프로그램 설정
⇒ putty에 x11 forwading을 xming으로 설정 후 virt-manager X(GUI)를 띄움.
⇒ 또는 xshell, xmanager 조합으로 virt-manager X(GUI)를 띄움.
4.3 터미널 프로그램에서 GUI 실행
[root@KVM-HOST ~]# virt-manager
실행 후 터미널 프로그램을 통해 GUI 메뉴가 아래와 같이 뜬다.
필자는 서버를 최대한 가볍게 운영하는걸 선호한다.
그래서 RHEL(CentOS)를 minimal로 최소로 설치 후 필요시에만 패키지를 추가해서 설치한다.
Run Level 5(GUI 모드)로 돌리면 불필요한 로그들이 로깅되고, 보안 및 패치 검토 등, 운영에 부담이 되기 때문이다.