Wok라는 웹기반 관리도구에 kimchi라는 kvm (가상화) 관리툴 플러그인을 설치하여 vm 관리를 쉽게 할 수 있게한다.

다른 도구인 cockpit을 사용하여 vm을 관리할 수 도 있지만 wok & kimchi가 더 편리하기 때문에 이것을 이용하여 vm 관리를 한다.

구성 환경

Physical Server : VMWare ESXi 8.0 U2 (or Baremetal)

Virtualization Server : KVM Host

  • OS : Rocky Linux 9.3
  • Disk : 300G (OS 영역)
    2TB (Guest Image 영역)
    RAM : 16G

이 글에서는 ESXi 하이퍼바이저 상에 올렸으나 일반적으로는 KVM Host를 베어메탈에 올려서 사용한다.

KVM 호스트 생성 및 OS 설치

  1. ESXi 상에 VM 생성
    위 KVM Host 사양으로 VM을 생성한다. (환경에 따라 Disk, Ram 사이즈 설정)
  2. 중첩 가상화를 위한 설정 (베어메탈의 경우 생략)
    VM이 stop된 상태에서
    설정 편집 - vm옵션 - 고급 - 구성매개변수(구성편집) - 매개변수추가 - vhv.enable = TRUE
    (혹은 이글 참조 : https://www.server-world.info/en/note?os=ESXi_8&p=vm&f=4)
  3. OS 설치
    VM(또는 베어메탈)에 Rocky Linux 9.3 설치 (minimal 로 설치)

OS 환경 설정

  1. selinux off
    # sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
    # grubby --update-kernel ALL --args selinux=0
    (* RHEL 9부터는 selinux disable 를 커널 파라메터에도 지정해야 didable 가능)
    (* selinux를 disable 하지 않을 시 wokd에 의해 nginx가 구동되지 않는다.)
  2. firewalld off
    # systemctl disable firewalld
  3. 네트워크 세팅
    # ip 세팅
  4. 중첩 가상화 설정 (베어메탈의 경우 생략)
    # cat << EOF > /etc/modprobe.d/kvmintel.conf
    options kvm_intel nested=1
    options kvm_intel enable_shadow_vmcs=1
    options kvm_intel enable_apicv=1
    options kvm_intel ept=1
    EOF

    # grubby --update-kernel ALL --args intel_iommu=on
  5. 커널 initramfs 이미지 업데이트
    # grub2-mkconfig -o /etc/grub2.cfg
  6. sshd 설정
    /etc/ssh/sshd_config 파일의 내용 중 아래 라인 수정
    #PermitRootLogin prohibit-password #--> PermitRootLogin yes 로 변경
  7. hostname 설정
    # hostnamectl set-hostname 'my-kvmserver'
  8. vim 및 wget 설치
    # dnf install -y wget vim-enhanced net-tools
    # mv -f ~/.vimrc ~/.vimrc_bak; wget https://mapoo.net/downfiles/Linux/vimrc -O ~/.vimrc --no-check-certificate
  9. 재부팅
    # reboot
  10. 중첩 가상화 지원 확인
    # cat /sys/module/kvm_intel/parameters/nested
    Y (또는 1)

Install wok

  1. git 설치
    # cd /root
    # dnf install -y git
  2. git clone
    # git clone https://github.com/kimchi-project/wok.git
  3. make, python, nginx 등의 패키지 설치
    # yum install -y automake gcc make libtool libxslt gettext-devel python3-pip python3-devel openldap-devel nginx libxml2-devel libxslt-devel
  4. python 모듈 설치
    # pip3 install pyflakes pyyaml
    # pip3 install --upgrade pip setuptools
    # pip3 install cherrypy python-pam Cheetah3 lxml psutil jsonschema pyOpenSSL
    # pip3 install websockify==0.7.0
    # pip3 install python-ldap
  5. wok 설치
    # cd /root/wok
    # git checkout 3.0.0
    # ./autogen.sh --system
    # make
    # make install
  6. 웹페이지 세션 타임아웃 값 조정
    (10분 -> 1440분(24시간)으로 변경)
    # sed -i 's/#session_timeout\ =\ 10/session_timeout\ =\ 1440/g' /etc/wok/wok.conf
  7. 서비스 설정
    # systemctl enable wokd
    # systemctl start wokd

Install kimchi plugin

  1. kimchi 설치
    # cd /root
    # git clone https://github.com/kimchi-project/kimchi.git
    # ./autogen.sh --system --with-spice-html5 --with-spice-web-client
    # make
    # make install
  2. python3-magic 및 virt 관련 패키지 설치
    # dnf install -y python3-magic
    # dnf install -y libvirt libvirt-devel libnl3-devel qemu-kvm parted-devel
    (parted-devel의 경우 codeready repo에 포함된 패키지임)
  3. python 모듈 설치
    # pip3 install libvirt-python distro paramiko Image ipaddr configobj ethtool pyparted
  4. qemu spice 설정
    # vi /etc/libvirt/qemu.conf
    spice_auto_unix_socket = 1 --> 주석제거
  5. libvirtd 서비스 설정
    # systemctl enable libvirtd
    # systemctl start libvirtd
    # systemctl restart wokd

Install nonvc

  1. novnc 설치
    # cd /root
    # git clone https://github.com/novnc/noVNC.git
    # cd noVNC
    # git checkout wasm
  2. 인증서 키 생성
    # openssl req -new -x509 -days 3650 -nodes -out self.pem -keyout self.pem
  3. novnc 파일 복사
    # cp -r /root/noVNC/ /usr/share/wok/plugins/kimchi/ui/novnc
    # ln -s /usr/share/wok/plugins/kimchi/ui/novnc /usr/share/novnc

아래 코드는 위 설치 과정을 주석을 빼고 순차적으로 넣어 둔 것임.
쉘에 복붙해서 수행하면 손 쉽게 설치 가능.

환경 설정 및 리부팅 (수행 후 리부팅 필요)

## prefaring
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
grubby --update-kernel ALL --args selinux=0

systemctl disable firewalld

grubby --update-kernel ALL --args intel_iommu=on
cat << EOF > /etc/modprobe.d/kvmintel.conf
options kvm_intel nested=1
options kvm_intel enable_shadow_vmcs=1
options kvm_intel enable_apicv=1
options kvm_intel ept=1
EOF

if test -d /sys/firmware/efi; then grub2-mkconfig -o /boot/efi/EFI/`cat /etc/redhat-release | awk '{print tolower($1)}'`/grub.cfg; else grub2-mkconfig -o /boot/grub2/grub.cfg; fi

#reboot
echo 'Do reboot for apply~!'

프로그램 설치 및 구성

## install packages and python modules
dnf install -y wget vim-enhanced net-tools git automake gcc make libtool libxslt gettext-devel python3-pip python3-devel openldap-devel nginx libxml2-devel libxslt-devel python3-magic libvirt libvirt-devel libnl3-devel qemu-kvm parted-devel
mv -f ~/.vimrc ~/.vimrc_bak; wget https://mapoo.net/downfiles/Linux/vimrc -O ~/.vimrc --no-check-certificate
pip3 install pyflakes pyyaml
pip3 install --upgrade pip setuptools
pip3 install cherrypy python-pam Cheetah3 lxml psutil jsonschema pyOpenSSL python-ldap libvirt-python distro paramiko Image ipaddr configobj ethtool pyparted
pip3 install websockify==0.7.0


## install wok
cd /root
yum install -y git
git clone https://github.com/kimchi-project/wok.git
cd /root/wok
git checkout 3.0.0
./autogen.sh --system
make
make install
sed -i 's/#session_timeout\ =\ 10/session_timeout\ =\ 1440/g' /etc/wok/wok.conf


## install kimchi
cd /root
git clone https://github.com/kimchi-project/kimchi.git
cd /root/kimchi
./autogen.sh --system --with-spice-html5 --with-spice-web-client
make
make install
sed -i 's/\#spice_auto_unix_socket/spice_auto_unix_socket/g' /etc/libvirt/qemu.conf


## install novnc
cd /root
git clone https://github.com/novnc/noVNC.git
cd noVNC
git checkout wasm
openssl req -new -x509 -days 3650 -nodes -out self.pem -keyout self.pem -subj "/C=KR/ST=Seoul/L=Seoul/O=example/CN=www.example.com"
cp -r /root/noVNC/ /usr/share/wok/plugins/kimchi/ui/novnc
ln -s /usr/share/wok/plugins/kimchi/ui/novnc /usr/share/novnc


## run service
systemctl enable libvirtd
systemctl start libvirtd
systemctl enable wokd
systemctl start wokd

-> 설치 완료 후 약 30초 후 쯤 웹브라우저를 통해 https://kvm-server-ip:8001 주소로 접속하면 wok 로그인 화면이 출력됨.

kvm storage 디렉토리 설정

(해당 작업은 생략 가능, 환경에 따라 선택 적용)

기본적으로 default 저장소가 / (root) 쪽에 위치하도록 설정되어 있음.
아래는 용량이 많은 곳으로 심볼릭 링크 처리하는 것임.

  1. default vm 저장소 디렉토리 재구성
    # mkdir -p /nvme/vms/images/
    # cd /var/lib/libvirt/
    # rm -rf images/
    # ln -s /nvme/vms/images/ images
  2. default iso 저장소 디렉토리 재구성
    # mkdir /home/isos
    # cd /var/lib/kimchi/
    # rm -rf isos
    # ln -sf /home/isos isos

wok 접속

  1. kvm 서버의 ip 확인
    예로 192.168.0.13 으로 가정
  2. 웹 접속
    https://192.168.0.13:8001
  3. 로그인 화면

vm 생성

  1. iso 다운로드
    # cd /home/isos
    # wget https://mirror.kakao.com/centos/7.9.2009/isos/x86_64/CentOS-7-x86_64-Minimal-2009.iso
    # chown qemu.kvm CentOS-7-x86_64-Minimal-2009.iso
  2. template 작성
    wok에서 virtualization - 템플리트 - 템플리트 추가
    template name : 적정한 이름 입력
    '추가 ISO 검색' 클릭
    CentOS7-x86 … 선택 - 작성
  3. guest 생성
    wok에서 virtualization - 게스트 - Add guest - 가상머신 이름 입력 후 생성했던 템플리트 선택 - 작성
    vm 생성 이 후 스펙 변경은 해당 vm을 선택 후 edit 에서 변경 가능
  4. 생성된 vm 리스트

(이 글은 2024.01.23에 작성됨)

Rocky Linux 8.9에서도 위와 동일한 방법으로 구성이 가능하다.

Issue & Tip

외부망에서 vm으로 접속

libvirt / kvm이 설치되면 기본적으로 virbr0 라는 브릿지 NIC이 생성되며 이는 ens33과 vnetX 장치를 연결해 주는 역활을 한다.

기본적으로 virbr0에는 192.168.122.1 ip가 할당된다. 그리고 vm 들에게는 192.168.122.0/24 대역의 ip가 할당된다.

kvm (wok)호스트의 NIC(여기서는 en33)에는 물리적인 라우터(가상 라우터가 될수도 있다)로 부터 ip를 받고 외부와 통신이 된다. (아래 ip 정보 참조)

[root@rocky93-wok ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:32:cc:73 brd ff:ff:ff:ff:ff:ff
    altname enp2s1
    inet 192.168.0.13/24 brd 192.168.0.255 scope global dynamic noprefixroute ens33
       valid_lft 6955sec preferred_lft 6955sec
    inet6 fe80::20c:29ff:fe32:cc73/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: virbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 52:54:00:73:09:ed brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
4: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master virbr0 state UNKNOWN group default qlen 1000
    link/ether fe:54:00:14:33:0b brd ff:ff:ff:ff:ff:ff
    inet6 fe80::fc54:ff:fe14:330b/64 scope link 
       valid_lft forever preferred_lft forever

외부에서 VM으로 접근을 위해서는 iptable를 이용한 Port FOWARD를 사용.

예) 외부에서 192.168.122.15 ip를 가진 cenos7-test vm으로 ssh 연결

- 연결하고자 하는 VM의 IP 확인

[root@rocky93-wok ~]# virsh list
 Id   Name           State
------------------------------
 3    centos7-test   running


[root@rocky93-wok ~]# virsh net-dhcp-leases default
 Expiry Time           MAC address         Protocol   IP address           Hostname      Client ID or DUID
---------------------------------------------------------------------------------------------------------
 2024-01-25 17:52:06   52:54:00:14:33:0b   ipv4       192.168.122.15/24    centos7-test  -

- IP Forward 설정 및 확인

[root@rocky93-wok ~]# iptables -I FORWARD 1 -o virbr0 -m state -s 192.168.0.0/24 -d 192.168.122.0/24 --state NEW,RELATED,ESTABLISHED -j ACCEPT
[root@rocky93-wok ~]# iptables -n -L FORWARD --line-numbers
Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination         
1    ACCEPT     all  --  192.168.0.0/24       192.168.122.0/24     state NEW,RELATED,ESTABLISHED
2    LIBVIRT_FWX  all  --  0.0.0.0/0            0.0.0.0/0           
3    LIBVIRT_FWI  all  --  0.0.0.0/0            0.0.0.0/0           
4    LIBVIRT_FWO  all  --  0.0.0.0/0            0.0.0.0/0 

-> 순서가 중요. 1번 라인에 위치 필요. 동작하지 않는다면 아래처러 FOWARD 룰을 지우고 다시 셋업

[root@rocky93-wok ~]# iptables -D FORWARD -o virbr0 -m state -s 192.168.0.0/24 -d 192.168.122.0/24 --state NEW,RELATED,ESTABLISHED -j ACCEPT
[root@rocky93-wok ~]# iptables -D FORWARD 4; iptables -D FORWARD 3; iptables -D FORWARD 2; iptables -D FORWARD 1
[root@rocky93-wok ~]# iptables -A FORWARD -o virbr0 -m state -s 192.168.0.0/24 -d 192.168.122.0/24 --state NEW,RELATED,ESTABLISHED -j ACCEPT
[root@rocky93-wok ~]# iptables -n -L FORWARD --line-numbers
Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination         
1    ACCEPT     all  --  192.168.0.0/24       192.168.122.0/24     state NEW,RELATED,ESTABLISHED

- Prerouting 설정 (192.168.0.13 / 2215 포트로 접근 시 192.168.122.15 / 22 포트로 라우팅) 및 확인

[root@rocky93-wok ~]# iptables -t nat -A PREROUTING -d 192.168.0.13 -p tcp --dport 2215 -j DNAT --to-destination 192.168.122.15:22
[root@rocky93-wok ~]# iptables -n -t nat -L PREROUTING
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       tcp  --  0.0.0.0/0            192.168.0.13         tcp dpt:2215 to:192.168.122.15:22

- 외부에서 접속
# ip a
192.168.0.4/24 (클라이언트 IP)
# ssh -p 2215 192.168.0.13 (VM으로 ssh 접속)

wok webpage session timeout

# vi /etc/wok/wok.conf
#session_timeout = 10   --> 주석 제거 후 원하는 수치로 변경 (단위: 분)

# systemctl stop nginx ; systemctl stop wokd
# systemctl start wokd

-

RHEL 9 Guest VM Kernel panic Problem

RHEL 9 계열 (Rocky linux 9, Alma linux 9, Oracle Linux 9, CentOS Stream 9 등)의 VM 설치 시 ISO 부팅과 함께 아래와 같이 커널패닉이 발생된다.

kernel panic - not syncing : Attempted to kill init

원인 :

RHEL 9은 CPU microarchitecture levels - x86-64-v2 를 요구한다. (참조 문서)
그런데 vm spec 설정에 cpu host-passthrough 설정을 하지 않으면 x86-64-v2에서 요구되는 sse4 등의 cpu flag를 사용하지 못한다.
그래서 initramfs 커널 로딩 과정에서 커널 패닉이 발생된다.

해결 방법 :

먼저 rocky 9 vm을 만들어 놓고 kvm (wok) 호스트 서버에서 아래와 같이 설정

# virsh edit rocky93-vm
  <cpu mode='custom' match='exact' check='none'>
    <model fallback='forbid'>qemu64</model>
    <numa>
      <cell id='0' cpus='0-3' memory='2097152' unit='KiB'/>
    </numa>
  </cpu>

--> 위 부분을 찾아서 아래처럼 설정 (1줄 수정, 1줄 추가)
  <cpu mode='host-passthrough' check='none' migratable='on'>   # --> custom -> host-passthrough 으로 변경
    <feature policy='require' name='vmx'/>                     # --> 이 줄 추가

    <model fallback='forbid'>qemu64</model>
    <numa>
      <cell id='0' cpus='0-3' memory='2097152' unit='KiB'/>
    </numa>
  </cpu>

이 후 vm을 켜고 설치를 진행하면 된다.

그리고 설치 후 아래와 같이 명령을 수행하면 sse4 플래그가 지원되는 것을 확인 할 수 있다.
(만약 host-passthrough 설정이 없는 Rocky linux8 vm에서 확인 시 sse4가 출력되지 않는다.)

[root@rocky93-vm ~]# cat /etc/redhat-release   (os release 정보 확인)
Rocky Linux release 9.3 (Blue Onyx)

[root@rocky93-vm ~]# virt-what  (kvm 호스트 기반의 가상머신임을 확인)
redhat
kvm

[root@rocky93-vm ~]# cat /proc/cpuinfo | grep sse4    (cpu flag 확인)
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm rdseed adx smap xsaveopt arat vnmi umip md_clear flush_l1d arch_capabilities

참고로 이 설정을 하게되면 중첩 가상화(Nested Virtualization)도 지원하게 된다. 즉, Rocky linux 9.3 VM 위에 VM을 올릴 수 있게된다.
(추가적으로 VM에 이 포스트에 기재된 'OS 환경 설정 - 4. 중첩 가상화 설정 (베어메탈의 경우 생략)' 부분도 추가 설정이 필요하다.)

그러면 KVM 위에 OpenStack, oVirt(RHV), OpenShift Virtualization, Proxmox와 같은 가상화 솔루션을 VM 형태로 설치해서 구동해 볼 수 있다.

웹 UI 동작 이상

현상 : 웹 창에서 설정 후 저장 시 아래 메시지가 빨간색으로 표시되면서 창이 닫히지 않는 이슈

The server encountered an unexpected condition which prevented it from fulfilling the request.

참고 문서 : https://github.com/kimchi-project/kimchi/issues/792

해결 방법 :

# mv /var/lib/kimchi/objectstore /tmp

# systemctl stop wokd

# systemctl stop nginx

# systemctl start wokd

# systemctl start nginx

Virtualization 탭이 사라졌을 경우

웹 UI에서 KCHCONN0002E 메시지와 함께 Virtualization 메뉴가 사라진 경우
kimchi 플러그인이 libvirtd 데몬과 통신을 실패하는 경우로, wokd 데몬을 조작하다가 발생될 수 있음. 아래처럼 데몬들을 내렸다가 올린다.

systemctl stop libvirtd-admin.socket
systemctl stop libvirtd-ro.socket
systemctl stop libvirtd.socket
systemctl stop libvirtd
systemctl stop wokd
systemctl start libvirtd
systemctl start libvirtd-admin.socket
systemctl start libvirtd-ro.socket
systemctl start libvirtd.socket
systemctl start wokd

그래도 해소가 안되면 서버 재부팅 (재부팅 후에도 해결이 안되면 추가로 libvirt-dbus 패키지를 설치하고 재부팅)

-

Extend storage size of the guest vm

template를 통해 vm을 생성 시 template에 정의된 storage size (default : 10G)를 따라간다.

10G로 생성된 vm의 사이즈를 50G로 늘리고자 한다면 아래와 같이 진행

  1. vm의 이미지 파일 위치 확인
    • kimchi ui에서 vm - Actions - Edit - Storage - hda device 부분에서 path 확인
  2. 용량 확인
    • # qemu-img info /var/lib/libvirt/images/0841ef71-1e59-4d46-b8fe-bd2ed844b626-0.img
      virtual size: 10 GiB (10737418240 bytes)
  3. qcow2 image 파일 확장
    • # qemu-img resize /var/lib/libvirt/images/0841ef71-1e59-4d46-b8fe-bd2ed844b626-0.img +40G
  4. 용량 확인
    • # qemu-img info /var/lib/libvirt/images/0841ef71-1e59-4d46-b8fe-bd2ed844b626-0.img
      virtual size: 50 GiB (53687091200 bytes)

virsh 명령어 팁

  • vm 들의 전체 dhcp ip 현황 확인
    • # virsh net-dhcp-leases default
  • 전체 vm 리스트 확인
    • # virsh list --all
  • 구동 중인 vm 리스트 확인
    • # virsh list
  • VM 운영 조작
    • # virsh start 'vm명' #--> vm 시작
    • # virsh stop 'vm명' #--> vm 종료 (graceful)
    • # virsh destroy 'vm명' #--> vm 전원끄기
    • # virsh undefine 'vm명' #--> vm 삭제

Wok & Kimchi on Rocky Linux 9
태그:                         

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다