

Ubuntu
(https://ubuntu.com/) 22.04 Server LTS 기준으로 가상머신 서버환경을 구축하는 방법을 소개합니다.
"virt-manager"
(https://virt-manager.org/)(KVM+QEMU UI management) 설치 조합을 권장드린다는 점 먼저 말씀드리며 윈도우 PC에 모두 있는 "원격 데스크톱 연결" 프로그램으로 가상머신 서버에 접속해서 "Virtual Machine Manager" UI를 통해서 KVM을 제어한다는 구성이라는 설명과 함께 읽어주시면 좋겠습니다.
Ubuntu
(https://ubuntu.com/) 22.04 Server LTS 배포판을 설치합니다. (본 문서는 22.04 기준으로 작성되었으나 14.04, 16.04, 18.04, 20.04 에서도 운영해왔으므로 큰 맥락에서는 구축 방법이 다르지 않습니다.)
$ sudo apt-get update $ sudo apt-get upgrade
$ sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target BIOS 설정에서 C-state 제한을 걸어서 최대 절전모드를 진입하지 않도록 할 수도 있습니다. 이 경우 C1 ~ C3E 까지만 허용하고 이상의 상태조정은 제한하도록 하시면 됩니다. 만약 최대 절전모드를 다시 허용하려면 다음과 같이 할 수 있습니다. $ sudo systemctl unmask sleep.target suspend.target hibernate.target hybrid-sleep.target
처음 설치시 첫 등록한 관리자 계정에서 다음과 같이 실행합니다. (위 최대 절전모드 해제한 경우 기본적으로 불필요) $ setterm --blink off --blank 0 --powersave off --powerdown 0 --store $ sudo setterm --blink off --blank 0 --powersave off --powerdown 0 --store
$ sudo apt-get install ntp
server 0.asia.pool.ntp.org server 1.asia.pool.ntp.org server 2.asia.pool.ntp.org server 3.asia.pool.ntp.org
$ sudo systemctl restart ntp.service
$ sudo timedatectl set-timezone Asia/Seoul 또는 $ sudo dpkg-reconfigure tzdata
$ sudo systemctl get-default graphical.target $ sudo systemctl set-default multi-user.target Created symlink /etc/systemd/system/default.target → /lib/systemd/system/multi-user.target.
$ sudo sysctl -p
$ sudo apt-get install zram-config ... $ sudo systemctl start zram-config.service $ sudo cat /proc/swaps Filename Type Size Used Priority /swap.img file 3907580 0 -2 /dev/zram0 partition 1953160 0 5
=> 만약 기존부터 운영하던 서버인 경우에는 설치 및 부팅에 문제가 발생할 가능성을 무시하기 어렵기 때문에 이 과정은 생략하세요. => !!! HWE Kernel이 의미하는 바를 잘 모르시겠다면 이 과정은 건너뛰세요. => Ubuntu 20.04 LTS 인 경우 $ sudo apt install --install-recommends linux-generic-hwe-20.04 => Ubuntu 22.04 LTS 인 경우 $ sudo apt install --install-recommends linux-generic-hwe-22.04
=> 아래는 netplan 설정파일 예시입니다. (lan0 가 eth0를 bridge로 구성한 것입니다.)
=> 참고) SR-IOV 가 현재로써는 네트워크 처리 성능이 가상화 환경에서는 제일 좋은거 같습니다.
=> 참고) 이 밖에도 macvlan, VXLAN, Bonding, ... 등의 구성을 이해하는 것도 좋습니다.
$ cat /etc/netplan/50-cloud-init.yaml
# netplain config file
network:
ethernets:
eth0:
optional: true
dhcp4: false
dhcp6: false
accept-ra: false
# wifis:
# wlan0:
# access-points:
# <wireless ssid>:
# password: <my wireless passphase>
# optional: true
# dhcp4: false
# dhcp6: false
# accept-ra: false
bridges:
lan0:
optional: true
# macaddress: <bridge mac address>
interfaces: [eth0]
mtu: 1500
parameters:
stp: false
forward-delay: 4
hello-time: 2
max-age: 20
dhcp4: false
dhcp6: false
accept-ra: false
addresses: [192.168.0.4/24]
nameservers:
addresses: [1.1.1.1,1.0.0.1,168.126.63.1,168.126.63.2,8.8.8.8,8.8.4.4]
routes:
- to: 0.0.0.0/0
via: 192.168.0.254
metric: 1
version: 2
$ sudo apt-get remove --purge nano
$ sudo apt-get remove --purge vim-tiny $ sudo apt-get install vim
$ sudo apt-get remove --purge ed
$ sudo apt-get remove --purge cloud-init
$ sudo apt-get remove --purge unattended-upgrades
$ sudo apt-get remove --purge snapd
$ sudo apt-get remove --purge modemmanager
$ sudo apt-get remove --purge sane-utils colord
# 삭제는 권장하고 싶지는 않습니다. 주의가 필요합니다. $ sudo apt-get remove --purge mdadm 또는 # 이 명령을 수행하고 물어보는 것을 모두 No 로 하시면 비활성화하게 됩니다. (이 명령에 의해서 "/etc/default/mdadm" 파일이 변경되고 initramfs이 갱신됩니다.) $ sudo dpkg-reconfigure mdadm
$ sudo apt autoremove --purge
$ sudo apt-get install xrdp xorgxrdp
$ sudo apt-get install ubuntu-desktop
$ sudo apt-get install ubuntu-desktop-minimal
$ sudo apt-get install xubuntu-desktop
$ sudo apt-get install kubuntu-desktop
$ sudo apt-get install xfce4 xfce4-terminal
$ sudo apt-get install libfontenc1 libxfont2 xfonts-encodings xfonts-utils xfonts-base xfonts-75dpi
$ sudo apt-get install xrdp xorgxrdp
선택사항, 유용할 수 있는 xfce 패키지가 필요하다면 추가적으로 설치를 진행합니다.
$ sudo apt-get install xfce4-clipman-plugin xfce4-cpugraph-plugin xfce4-netload-plugin xfce4-screenshooter xfce4-taskmanager xfce4-xkb-plugin
선택사항, 화면보호기는 불필요한 경우 다음과 같이 삭제합니다.
$ sudo apt-get remove --purge light-locker xscreensaver
설치 과정에서 "display manager"를 선택하라고 나올 수 있습니다. 이 경우 "lightdm" 을 선택하는 것을 기준으로 설명합니다. (선택 사항)
설치 완료 후 반드시 "/etc/xrdp/startwm.sh" 를 수정합니다. => 마지막 부분의 Xsession을 실행(exec)하는 부분은 모두 주석처리 또는 제거하시고 대신 그 위치에 "xfce4-session"가 실행되도록 하기와 같이 추가 (원격 접속이 잘 안되는 경우만 하시면 됩니다)
>>>
... 생략 ...
test -x /usr/bin/xfce4-session && exec /usr/bin/xfce4-session
#test -x /etc/X11/Xsession && exec /etc/X11/Xsession
#exec /bin/sh /etc/X11/Xsession
<<<
이렇게 설치하고 나면 xrdp 계정이 생성되는데 이 계정을 ssl-cert group 에 추가해주는게 좋습니다. (선택 사항, xrdp 접속시 인증서를 사용할 수 있도록 하는 사항)
$ cat /etc/group|grep ssl-cert
ssl-cert:x:120:xrdp
version: "2.1"
services:
xrdp:
image: hwport/ubuntu:xrdp
container_name: xrdp
hostname: xrdp
stdin_open: true
tty: true
# privileged: true
# cap_add:
# - "SYS_ADMIN"
# - "SYS_RESOURCE"
# - "SYS_PTRACE"
# - "NET_ADMIN"
# - "NET_BIND_SERVICE"
# - "NET_BROADCAST"
# - "NET_RAW"
# - "BPF" # >= Linux Kernel v5.8
# security_opt:
# - seccomp:unconfined
environment:
- container=docker
- TZ=Asia/Seoul
- TERM=xterm
- LC_ALL=C
- LANG=en_US.UTF-8
- EDITOR=vim
# volumes:
# - ./home:/home
# tmpfs:
# - /tmp
# - /run
# - /run/lock
network_mode: bridge
ports:
- "3389:3389"
restart: unless-stopped
$ docker compose up -d "xrdp" $ docker exec -i -t "xrdp" useradd -c "<comment>" -d "/home/<username>" -g "users" -G "users,adm,sudo,audio,input" -s "/bin/bash" -m "<username>" $ docker exec -i -t "xrdp" sh -c "echo \"<username>:<password>\" | chpasswd"
$ docker compose down
$ sudo apt-get install language-pack-ko
$ sudo apt-get install fonts-unfonts-core fonts-unfonts-extra
$ sudo apt-get install fonts-baekmuk
$ sudo apt-get install fonts-nanum fonts-nanum-coding fonts-nanum-extra
$ sudo apt-get install fonts-naver-d2coding
$ sudo apt-get install ibus ibus-hangul im-config zenity => 설치 후 설정사항 (im, ibus, ibus-hangul, Autostart 설정) - "im-config" 를 실행하여 "ibus"을 선택합니다. - "ibus-setup" 을 실행하여 "Input Method" 에 "Korean - Hangul"을 추가해줍니다. - 매 접속마다 한글 입력기가 실행되어야 하므로 "설정(Settings)" > "Session and Startup" 메뉴에서 "Application Autostart" 항목에 "/usr/bin/ibus-daemon -drx" 명령이 실행될 수 있도록 추가해주세요.
$ sudo apt-get install fcitx fcitx-hangul => 설치 후 /etc/default/im-config 를 편집기로 열어서 IM_CONFIG_DEFAULT_MODE 항목의 값을 auto 에서 fcitx 로 변경 후 저장하고 재부팅
$ sudo apt-get install pulseaudio
=> build 에 필요한 패키지 설치
$ sudo apt-get install build-essential dpkg-dev libpulse-dev git autoconf libtool
=> git source를 다운로드
$ git clone https://github.com/neutrinolabs/pulseaudio-module-xrdp.git /tmp/pulseaudio-module-xrdp
=> 빌드 및 설치
$ cd /tmp/pulseaudio-module-xrdp
$ ./scripts/install_pulseaudio_sources_apt.sh
마지막에 표시되는 PULSE_DIR=... 부분과 아래 configure의 실행시 인자가 일치해야 합니다. (기본적으로 PULSE_DIR은 "${HOME}/pulseaudio.src"를 가르키게 될 겁니다.)
Ubuntu 배포판이 아닌 경우는 "./scripts/install_pulseaudio_sources_apt_wrapper.sh" 으로 실행하면 됩니다.
$ ./bootstrap
$ ./configure PULSE_DIR=~/pulseaudio.src
$ make
$ sudo make install
=> 소스 및 중간파일들을 정리(삭제)
$ cd ..
$ rm -rf /tmp/pulseaudio-module-xrdp ~/pulseaudio.src
$ sudo apt-get install firefox
$ sudo apt-get install -y software-properties-common
$ sudo add-apt-repository -y ppa:mozillateam/ppa
$ echo 'Package: *
Pin: release o=LP-PPA-mozillateam
Pin-Priority: 1001' | sudo tee /etc/apt/preferences.d/mozilla-firefox
$ echo 'Unattended-Upgrade::Allowed-Origins:: "LP-PPA-mozillateam:${distro_codename}";' | sudo tee /etc/apt/apt.conf.d/51unattended-upgrades-firefox
$ sudo apt-get update
$ sudo apt-get install -y firefox
=> 이 경우 구글 크롬브라우져가 아닌 'without 구글' 버젼인 크로미움 브라우져입니다. $ sudo apt-get install chromium-browser
$ sudo apt-get install -y software-properties-common apt-transport-https wget ca-certificates gnupg2 ubuntu-keyring $ wget -O- https://dl.google.com/linux/linux_signing_key.pub | gpg --dearmor > /usr/share/keyrings/google-chrome.gpg \ && echo deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main | sudo tee /etc/apt/sources.list.d/google-chrome.list $ sudo apt-get update $ sudo apt-get install -y google-chrome-stable
$ sudo apt-get install -y software-properties-common $ sudo add-apt-repository -y ppa:maarten-fonville/android-studio $ sudo apt-get update $ sudo apt-get install -y android-studio

$ sudo apt-get install qemu-kvm libvirt-bin ovmf ubuntu-vm-builder bridge-utils
$ sudo apt install qemu-kvm ovmf bridge-utils libvirt-daemon-system
$ sudo apt install openvswitch-common openvswitch-switch
$ sudo add-apt-repository ppa:stefanberger/swtpm-focal && sudo apt update # 20.04 이하 버젼인 경우에만 필요 $ sudo apt install swtpm-tools
$ sudo apt install qemu-user-static qemu-system-arm qemu-efi-aarch64
$ sudo apt install libeql1
$ sudo adduser `id -un` render Adding user '<username>' to group 'render' ...
$ sudo adduser `id -un` libvirt Adding user '<username>' to group 'libvirt' ...
$ egrep -c '(vmx|svm)' /proc/cpuinfo
$ sudo apt-get install virt-manager
$ sudo apt-get install ssh-askpass-gnome
$ virsh list --all Id Name State ---------------------------------- $
$ virsh list --all libvir: Remote error : Permission denied error: failed to connect to the hypervisor $
$ sudo apt-get install virtualbox
$ sudo apt-get install docker.io $ sudo apt-get install docker-compose-v2
$ sudo usermod -a -G docker $(whoami)
{
"data-root": "/var/lib/docker",
"bridge":"br0",
"fixed-cidr":"192.168.0.240/29",
"default-gateway":"192.168.0.254",
"dns":["192.168.0.3","168.126.63.1","168.126.63.2"],
"mtu":1500,
"ipv6":false,
"iptables":false,
"ip-forward": false,
"ip-masq": false
}
OR
{
"data-root": "/var/lib/docker",
"bip": "198.18.1.1/24",
"userland-proxy": false
}
OR
{
"data-root": "/var/lib/docker",
"bip":"198.18.1.1/24",
"iptables":false,
"ip-forward":false,
"ip-masq":false,
"userland-proxy":true
}
OR
{
"data-root": "/var/lib/docker",
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "4",
"labels": "production_status",
"env": "os,customer"
},
"bip":"198.18.1.1/24",
"iptables":false,
"ip-forward":false,
"ip-masq":false,
"userland-proxy":true
}
=> Ubuntu 20.04 이전 버전인 경우 $ DOCKER_BUILDKIT=1 docker build --platform=local -o . https://github.com/docker/buildx.git $ mkdir -p ~/.docker/cli-plugins $ mv buildx ~/.docker/cli-plugins/docker-buildx $ docker buildx create --use /* 자세한 사용법은 'docker buildx create --help' 로 확인 후 적절히 추가 옵션을 주어 사용하실 수 있습니다. */ => Ubuntu 22.04 이상 버전인 경우 $ sudo apt install docker-buildx
$ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes $ docker buildx create --name multiarch --driver docker-container --use $ docker buildx inspect --bootstrap
$ docker buildx build --no-cache --push --platform linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/riscv64,linux/s390x --tag "<image-tag-name>" .
$ sudo apt install firewalld $ sudo apt install dnsmasq $ sudo systemctl enable --now firewalld $ sudo systemctl restart libvirtd
=> forward 를 허용하려면 (최신 버젼에서 추가된 옵션) : firewall-cmd [--permanent] [--zone=<zone>] --add-forward => 특정 인터페이스를 zone 에 합류 시키려면 : firewall-cmd [--permanent] [--zone=<zone>] --add-interface=<interface-name> => 특정 서비스를 zone 에 허용하려면 : firewall-cmd [--permanent] [--zone=<zone>] --add-service=<service-name> => 특정 포트를 zone 에 허용하려면 : firewall-cmd [--permanent] [--zone=<zone>] --add-port=<portid>[-<portid>]/<protocol> => IKE/NAT-T 허용 : firewall-cmd [--permanent] [--zone=<zone>] --add-service=ipsec => IPSec policy (out) 에 따른 허용 : firewall-cmd [--permanent] --direct --add-rule ipv4 nat POSTROUTING 0 -m policy --dir out --pol ipsec -j ACCEPT => IPSec policy (in) 에 따른 MSS 조정 : firewall-cmd [--permanent] --direct --add-rule ipv4 mangle PREROUTING 0 -m policy --pol ipsec --dir in -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1281:1536 -j TCPMSS --set-mss 1280 => IPSec policy (out) 에 따른 MSS 조정 : firewall-cmd [--permanent] --direct --add-rule ipv4 mangle POSTROUTING 0 -m policy --pol ipsec --dir out -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1281:1536 -j TCPMSS --set-mss 1280 => IPSec 출발지 대역만 Masquerade : firewall-cmd [--permanent] --direct --add-rule ipv4 nat POSTROUTING 0 -s 192.168.0.0/24 -j MASQUERADE => IPSec 목적지 대역만 Masquerade : firewall-cmd [--permanent] --direct --add-rule ipv4 nat POSTROUTING 0 -d 192.168.0.0/24 -j MASQUERADE => ESP 프로토콜 허용 : firewall-cmd [--permanent] [--zone=<zone>] --add-rich-rule='rule protocol value="esp" accept' => AH 프로토콜 허용 : firewall-cmd [--permanent] [--zone=<zone>] --add-rich-rule='rule protocol value="ah" accept' => IPCOMP 프로토콜 허용 : firewall-cmd [--permanent] [--zone=<zone>] --add-rich-rule='rule protocol value="ipcomp" accept' => IPEncap 프로토콜 허용 : firewall-cmd [--permanent] [--zone=<zone>] --add-rich-rule='rule protocol value="ipencap" accept' => 특정 출발지 대역 거부 : firewall-cmd [--permanent] [--zone=<zone>] --add-rich-rule='rule family="ipv4" source address="<address>/<prefix>" drop' => 특정 목적지 대역 거부 : firewall-cmd [--permanent] [--zone=<zone>] --add-rich-rule='rule family="ipv4" destination address="<address>/<prefix>" drop' => 특정 목적지 대역과 포트를 거부 : firewall-cmd [--permanent] [--zone=<zone>] --add-rich-rule='rule family="ipv4" destination address="<address>/<prefix>" port="23" protocol="tcp" drop' => 특정 포트 개방 (DNAT) : firewall-cmd [--permanent] [--zone=<zone>] --add-forward-port='port=<portid>:proto=<protocol>:toport=<portid>:toaddr=<to-address>' => Masquerade 허용 : firewall-cmd [--permanent] [--zone=<zone>] --add-masquerade => 특정 출발지 대역만 masquerade : firewall-cmd [--permanent] [--zone=<zone>] --add-rich-rule='rule family="ipv4" source address="<address>/<prefix>" masquerade' => 기본 정책을 REJECT가 아닌 DROP으로 처리하는 경우 : firewall-cmd [--permanent] [--zone=<zone>] --add-rich-rule='rule priority="32767" drop'
참고링크
(https://codepre.com/how-to-block-ip-addresses-from-countries-with-geoip-addon-in-iptables.html))
$ sudo apt install xtables-addons-common libtext-csv-xs-perl perl $ cd /usr/lib/xtables-addons/ $ sudo ./xt_geoip_dl $ sudo mkdir -p /usr/share/xt_geoip/ $ sudo cp -f /usr/lib/xtables-addons/dbip-country-lite.csv /usr/share/xt_geoip/ $ cd /usr/share/xt_geoip/ $ sudo perl /usr/lib/xtables-addons/xt_geoip_build dbip-country-lite.csv 554102 entries total ... $ sudo rm -f /usr/share/xt_geoip/dbip-country-lite.csv
$ sudo apt install xtables-addons-common libtext-csv-xs-perl perl $ cd /usr/libexec/xtables-addons/ $ sudo ./xt_geoip_dl $ sudo mkdir -p /usr/share/xt_geoip/ $ sudo cp -f /usr/libexec/xtables-addons/dbip-country-lite.csv /usr/share/xt_geoip/ $ cd /usr/share/xt_geoip/ $ sudo perl /usr/libexec/xtables-addons/xt_geoip_build dbip-country-lite.csv 554102 entries total ... $ sudo rm -f /usr/share/xt_geoip/dbip-country-lite.csv
$ sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -m geoip --src-cc CN,RU,KP -j DROP $ sudo firewall-cmd --reload $ sudo cat /etc/firewalld/direct.xml <?xml version="1.0" encoding="utf-8"?> <direct> <rule ipv="ipv4" table="filter" chain="INPUT" priority="0">-m geoip --src-cc CN,RU,KP -j DROP</rule> </direct>
... GRUB_CMDLINE_LINUX_DEFAULT="intel_iommu=on iommu=pt kvm.ignore_msrs=1 rd.driver.pre=vfio-pci vfio_iommu_type1.allow_unsafe_interrupts=1" ...
... GRUB_CMDLINE_LINUX_DEFAULT="amd_iommu=on iommu=pt kvm.ignore_msrs=1 rd.driver.pre=vfio-pci vfio_iommu_type1.allow_unsafe_interrupts=1" ...
$ sudo update-grub
sudo grub-mkconfig -o /boot/grub/grub.cfg
blacklist nouveau options nouveau modeset=0
$ sudo lspci -nnk ... <bus> <name> [<ID>] ...
$ sudo lspci -nnk ... 07:00.0 VGA compatible controller [0300]: NVIDIA Corporation G94GL [Quadro FX 1800] [10de:0638] (rev a1) ...
$ sudo lspci -nnk ... 07:00.0 VGA compatible controller [0300]: NVIDIA Corporation GK208B [GeForce GT 730] [10de:1287] (rev a1) ... 07:00.1 Audio device [0403]: NVIDIA Corporation GK208 HDMI/DP Audio Controller [10de:0e0f] (rev a1) ...
$ sudo lspci -nnk ... 07:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP108 [GeForce GT 1030] [10de:1d01] (rev a1) ... 07:00.1 Audio device [0403]: NVIDIA Corporation GP108 High Definition Audio Controller [10de:0fb8] (rev a1) ...
options vfio-pci ids=<ID>[,<...>] #options vfio-pci disable_vga=1
$ sudo update-initramfs -u
$ sudo reboot
$ sudo dmesg | grep -i -e DMAR -e IOMMU # 또는 => sudo dmesg | grep -E "DMAR|IOMMU" [ 0.016937] ACPI: DMAR 0x00000000BF77E0C0 000110 (v01 AMI OEMDMAR 00000001 MSFT 00000097) [ 0.017009] ACPI: Reserving DMAR table memory at [mem 0xbf77e0c0-0xbf77e1cf] [ 0.217765] DMAR: IOMMU enabled [ 0.462452] DMAR-IR: This system BIOS has enabled interrupt remapping [ 0.897740] DMAR: Host address width 40 [ 0.897744] DMAR: DRHD base: 0x000000fbffe000 flags: 0x1 [ 0.897755] DMAR: dmar0: reg_base_addr fbffe000 ver 1:0 cap c90780106f0462 ecap f020f6 [ 0.897760] DMAR: RMRR base: 0x000000000ed000 end: 0x000000000effff [ 0.897763] DMAR: RMRR base: 0x000000bf7ed000 end: 0x000000bf7fffff [ 0.897766] DMAR: ATSR flags: 0x0 [ 0.897788] DMAR: No SATC found [ 0.897796] DMAR: dmar0: Using Queued invalidation [ 0.907806] DMAR: Intel(R) Virtualization Technology for Directed I/O ...
$ sudo dmesg | grep -i vfio [ 8.015119] VFIO - User Level meta-driver version: 0.3 [ 8.034941] vfio-pci 0000:07:00.0: vgaarb: changed VGA decodes: olddecodes=io+mem,decodes=io+mem:owns=none [ 8.052303] vfio_pci: add [10de:0638[ffff:ffff]] class 0x000000/00000000 [ 567.518237] vfio-pci 0000:07:00.0: enabling device (0140 -> 0143) [127997.152879] vfio-pci 0000:07:00.0: enabling device (0400 -> 0403)


Windows용 qemu-utils 다운로드 링크
(https://www.qemu.org/download/#windows))
# 사용법 : qemu-img convert -O <변환하고자 하는 포맷 이름> <변환할 파일명:source> <변환된 포맷으로 저장할 파일명:target> 예) $ qemu-img convert -O qcow2 MyVMdisk1.vmdk MyVMdisk1.qcow2 이미지 변환 과정에서 크기를 최대한 줄이고자 한다면 "-c" 옵션도 함께 추가할 수 있습니다. (단, 이 경우 가상머신이 조금 느려질 수 있습니다.) 예) $ qemu-img convert -c -O qcow2 MyVMdisk1.vmdk MyVMdisk1.qcow2 -p 옵션을 사용하면 변환시 진행률을 확인 할 수 있습니다.
$ qemu-img --help |grep "Supported formats" Supported formats: blkdebug blkreplay blkverify bochs cloop dmg file ftp ftps host_cdrom host_device http https iscsi iser luks nbd null-aio null-co parallels qcow qcow2 qed quorum raw rbd replication sheepdog throttle vdi vhdx vmdk vpc vvfat
$ virsh --help
$ virsh list --all Id Name State ---------------------------------------------------- - Windows shut off ...
$ virsh start [--console] <Name> $ virsh shutdown <Name> $ virsh destroy <Name> $ virsh reboot <Name>
$ virsh console <Name> ... => ^] (Ctrl+']') 키를 누르면 Attach된 console에서 빠져나올 수 있습니다.
$ virsh edit "<가상머신 이름>"
다음과 같이 clock 설정 부분의 내용을 동일하게 편집하고 저장하고 가상머신을 재시작 해봅니다.
Guest 운영체제가 Windows 계열인 경우
>>>
<clock offset='localtime'>
<timer name='hpet' present='no'/>
<timer name='hypervclock' present='yes'/>
</clock>
<<<
또는 Guest 운영체제가 Linux 계열인 경우
>>>
<clock offset='localtime'>
<timer name='hpet' present='no'/>
<timer name='kvmclock' present='yes'/>
</clock>
<<<
rufus 유틸
(https://rufus.ie/)을 이용하여 USB로 만듭니다.
How to install Ubuntu using serial console
(https://github.com/ynkjm/ubuntu-serial-install) (내용이 최신 배포판과는 다소 다를 수 있으나 맥락은 동일합니다.)
default install label install menu label ^Install Ubuntu Server kernel /install/vmlinuz append vga=normal initrd=/install/initrd.gz -- console=tty0 console=ttyS0,115200n8 nosplash debug -
CONSOLE 0 SERIAL 0 115200 0 default menu.c32 prompt 0 menu title UNetbootin timeout 100 label unetbootindefault kernel /ubnkern append vga=normal initrd=/ubninit nomodeset askmethod console=tty0 console=ttyS0,115200n8
menuentry "Install Ubuntu Server" {
set gfxpayload=keep
linux /install/vmlinuz file=/cdrom/preseed/ubuntu-server.seed vga=normal console=tty0 console=ttyS0,115200n8 ---
initrd /install/initrd.gz
}
$ cat /etc/modprobe.d/kvm.conf options kvm_intel nested=Y
$ sudo do-release-upgrade
#!/bin/bash
# 이 예제 스크립트는 포트가 9/UDP 인 WOL magic packet을 수신하여 가상머신을 기동해주는 것이며 적절히 자신의 환경에 맞도록 수정해야 할 수 있습니다.
# WOL magic packet 을 전송하는 프로그램에 따라서 포트 번호가 다를 수 있습니다. (참고로 필자의 경우는 2304/UDP 로 변경해서 사용하고 있습니다.)
# listen to udp port 9 for packets, check if it is a magic packet
netcat -dkn -l 9 -u | stdbuf -o0 xxd -c 6 -p | stdbuf -o0 uniq | stdbuf -o0 grep -v 'ffffffffffff' | while read
do
echo "Got triggered with $REPLY"
mac="${REPLY:0:2}:${REPLY:2:2}:${REPLY:4:2}:${REPLY:6:2}:${REPLY:8:2}:${REPLY:10:2}"
# loop through libvirt machines
for vm in $(virsh list --all --name)
do
# Get the MAC address and compare with the magic packet
vmmac=$(virsh dumpxml $vm | grep "mac address" | awk -F\' '{ print $2}')
if [ "$vmmac" = "$mac" ]
then
state=$(virsh list --all|awk -v vm=$vm '{ if ($2 == vm ) print $3 }')
echo "Found $vm with $mac in $state state"
# Dependent on the state, resume or start
[ $state == "paused" ] && virsh -q resume $vm && virsh domtime --domain $vm --now
[ $state == "shut" ] && virsh -q start $vm
fi
done
done
[Unit] Description=Listen virt wake-on-lan Requires=network.target After=network.target [Service] Type=simple ExecStart=/usr/local/bin/listen-virt-wol.sh KillMode=control-group Restart=on-failure User=root Group=root [Install] WantedBy=multi-user.target
$ qemu-system-x86_64 -net nic,model=? Supported NIC models: e1000 e1000-82544gc e1000-82545em e1000e i82550 i82551 i82557a i82557b i82557c i82558a i82558b i82559a i82559b i82559c i82559er i82562 i82801 ne2k_pci pcnet pvrdma rtl8139 tulip virtio-net-pci virtio-net-pci-non-transitional virtio-net-pci-transitional vmxnet3
<interface type='network'>
<mac address='xx:xx:xx:xx:xx:xx'/>
<source network='internal'/>
<model type='virtio'/>
<driver>
<host tso4='off' tso6='off' lro='off' gro='off' ecn='off'/>
<guest tso4='off' tso6='off' lro='off' gro='off' ecn='off'/>
</driver>
<address type='pci' domain='...' bus='...' slot='...' function='...'/>
</interface>
$ sudo ethtool -K eth0 tso off lro off gro off ecn off
=> virtio net driver 일부 발췌. 여기서 VIRTIO_NET_F_GUEST_XXX 가 관여하는 것으로 추정됨. ethtool -k | -K 옵션은 여기서는 애매한 듯 합니다.
...
if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) ||
virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) ||
virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN))
vi->big_packets = true;
...
https://www.linux-kvm.org/
https://libvirt.org/
https://wiki.libvirt.org/page/VirtualNetworking
https://libvirt.org/formatdomain.html
https://libvirt.org/formatnetwork.html
<network>
<name>default6</name>
<bridge name="virbr0"/>
<forward mode="nat"/>
<ip address="192.168.122.1" netmask="255.255.255.0">
<dhcp>
<range start="192.168.122.2" end="192.168.122.254"/>
</dhcp>
</ip>
<ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64">
<dhcp>
<range start="2001:db8:ca2:2:1::10" end="2001:db8:ca2:2:1::ff"/>
</dhcp>
</ip>
</network>
<network>
<name>local6</name>
<bridge name="virbr1"/>
<forward mode="route" dev="eth1"/>
<ip address="192.168.122.1" netmask="255.255.255.0">
<dhcp>
<range start="192.168.122.2" end="192.168.122.254"/>
</dhcp>
</ip>
<ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64">
<dhcp>
<host name="paul" ip="2001:db8:ca2:2:3::1"/>
<host id="0:1:0:1:18:aa:62:fe:0:16:3e:44:55:66" ip="2001:db8:ca2:2:3::2"/>
<host id="0:3:0:1:0:16:3e:11:22:33" name="ralph" ip="2001:db8:ca2:2:3::3"/>
<host id="0:4:7e:7d:f0:7d:a8:bc:c5:d2:13:32:11:ed:16:ea:84:63"
name="badbob" ip="2001:db8:ca2:2:3::4"/>
</dhcp>
</ip>
</network>
<network>
<name>private</name>
<bridge name="virbr2"/>
<ip address="192.168.152.1" netmask="255.255.255.0">
<dhcp>
<range start="192.168.152.2" end="192.168.152.254"/>
</dhcp>
</ip>
<ip family="ipv6" address="2001:db8:ca2:3::1" prefix="64"/>
</network>
<network> <name>host-bridge</name> <forward mode="bridge"/> <bridge name="br0"/> </network>
<network>
<name>direct-macvtap</name>
<forward mode="bridge">
<interface dev="eth20"/>
<interface dev="eth21"/>
<interface dev="eth22"/>
<interface dev="eth23"/>
<interface dev="eth24"/>
</forward>
</network>
https://help.ubuntu.com/community/KVM
https://virt-manager.org/
https://docs.microsoft.com/ko-kr/azure/virtual-machines/linux/classic/remote-desktop
Accelerating QEMU on Windows with HAXM
(https://www.qemu.org/2017/11/22/haxm-usage-windows/)
https://gist.github.com/csullivan/b0fcc67a3ecf5e1f463efabfa23079d8
https://blog.zerosector.io/2018/07/28/kvm-qemu-windows-10-gpu-passthrough/
https://neo-blog.tistory.com/10
https://help.ubuntu.com/community/KVM/VirtManager
http://blog.hkwon.me/ubuntu-18-04-netplan/
https://www.reddit.com/r/VFIO/comments/80p1q7/high_kvmqemu_cpu_utilization_when_windows_10/
<!-- before: this config uses over 15% of a host CPU core -->
<clock offset='localtime'>
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
<timer name='hpet' present='no'/>
<timer name='hypervclock' present='yes'/>
</clock>
<!-- after: this config drops to about 3% of a host CPU core -->
<clock offset='localtime'>
<timer name='hpet' present='yes'/>
<timer name='hypervclock' present='yes'/>
</clock>
https://libvirt.org/formatdomain.html#elementsSysinfo
...
<os>
<smbios mode='sysinfo'/>
...
</os>
<sysinfo type='smbios'>
<bios>
<entry name='vendor'>LENOVO</entry>
</bios>
<system>
<entry name='manufacturer'>Fedora</entry>
<entry name='product'>Virt-Manager</entry>
<entry name='version'>0.9.4</entry>
</system>
<baseBoard>
<entry name='manufacturer'>LENOVO</entry>
<entry name='product'>20BE0061MC</entry>
<entry name='version'>0B98401 Pro</entry>
<entry name='serial'>W1KS427111E</entry>
</baseBoard>
<chassis>
<entry name='manufacturer'>Dell Inc.</entry>
<entry name='version'>2.12</entry>
<entry name='serial'>65X0XF2</entry>
<entry name='asset'>40000101</entry>
<entry name='sku'>Type3Sku1</entry>
</chassis>
<oemStrings>
<entry>myappname:some arbitrary data</entry>
<entry>otherappname:more arbitrary data</entry>
</oemStrings>
</sysinfo>
...
https://www.dell.com/community/Alienware-General-Read-Only/Edit-the-Product-Name-on-Alienware-17-R2-BIOS/td-p/5530304
Name R/W Status Information
------------------------------------------------ --- -------- -------------------
BaseBoardHandle = "0001h" (Type 1)
(/IVN)BIOS vendor name. R Done "Alienware"
(/IV)BIOS version R Done "A02"
(/ID)BIOS release date R Done "02/11/2015"
(/SM)System manufacture R Done "Alienware"
(/SP)System product R Done "Alienware 17 R2"
(/SV)System version R Done "A02"
(/SS)System Serial number R Done "REMOVED"
(/SU)System UUID R Done "REMOVED"
(/SK)System SKU number R Done "Alienware 15"
(/SF)System Family R Done "Alienware 17 R2"
(/BM)Baseboard manufacturer R Done "Alienware"
(/BP)Baseboard product R Done "Alienware 17 R2"
(/BV)Baseboard version R Done "X04"
(/BS)Baseboard Serial number R Done "REMOVED"
(/BT)Baseboard Asset Tag R Done ""
(/BLC)BB. Loc. in Chassis R Done "To Be Filled By O.E.M."
BaseBoardHandle = "0002h" (Type 2)
(/BMH)Baseboard manufacturer R Done "Alienware"
(/BPH)Baseboard product R Done "Alienware 17 R2"
(/BVH)Baseboard version R Done "X04"
(/BSH)Baseboard Serial number R Done "REMOVED"
https://www.spinics.net/lists/kvm/msg60340.html
https://docs.docker.com/install/linux/docker-ce/ubuntu/
https://marcokhan.tistory.com/244
How To Install KVM Hypervisor on Ubuntu 20.04 (Focal Fossa)
(https://computingforgeeks.com/install-kvm-hypervisor-on-ubuntu-focal-fossa/)
https://www.unixtutorial.org/disable-sleep-on-ubuntu-server/
https://www.it-swarm.dev/ko/server/ubuntu-%EC%84%9C%EB%B2%84-%EC%A0%88%EC%A0%84-%EC%B5%9C%EB%8C%80-%EC%A0%88%EC%A0%84-%EB%AA%A8%EB%93%9C%EB%A5%BC-%EB%B0%A9%EC%A7%80%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95/961194942/
https://serverfault.com/questions/948339/networking-between-kvm-vm-and-docker-container-on-same-host
First I created the configuration file /etc/docker/daemon.json as suggested in the documentation with the following content (the iptables line may not even be needed):
>>>
=> virt network 에 대하여 bridge 구성인 경우
{
"bridge": "virbr0",
"iptables": false
}
=> host bridged network 을 공유하는 경우 (fixed-cidr 을 자신의 네트워크에서 사용하지 않는 작은 대역으로 설정할 필요가 있음)
{
"bridge":"br0",
"fixed-cidr":"192.168.0.240/29",
"default-gateway":"192.168.0.254",
"ipv6":false,
"iptables":false
}
https://ubuntu.com/openstack/install
https://docs.openstack.org/liberty/networking-guide/adv-config-sriov.html
https://linux.systemv.pe.kr/tag/kvm/
https://gist.github.com/luk6xff/9f8d2520530a823944355e59343eadc1
http://jake.dothome.co.kr/qemu/
https://kimtinh.gitlab.io/post/tech/2019_05_20_qemu_rpi/#gsc.tab=0
(Run Raspbian with qemu and virt-manager)
https://blog.programster.org/kvm-missing-default-network
http://kris.io/2015/10/01/kvm-network-performance-tso-and-gso-turn-it-off/
https://doc.ubuntu-fr.org/zram
(Ubuntu 에서 zram 사용하는 방법)
$ sudo apt install zram-config $ sudo systemctl enable zram-config $ sudo systemctl start zram-config $ cat /proc/swaps Filename Type Size Used Priority /dev/zram0 partition 857956 0 5 ... => 필요에 따라서 "/etc/fstab" 에 있는 swap 관련 구성은 제거 (유지해도 상관은 없음. 유지하는 경우 priority 를 낮추는 수정을 권장)
https://unix.stackexchange.com/questions/534155/win10-guests-high-kvm-host-cpu-usage
</features>
...
<hyperv>
<relaxed state='on'/>
<vapic state='on'/>
<spinlocks state='on' retries='8191'/>
<synic state='on'/>
<stimer state='on'/>
</hyperv>
...
</features>
<clock offset='localtime'>
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
<timer name='hpet' present='no'/>
<timer name='hypervclock' present='yes'/>
</clock>
</features>
...
<hyperv>
<relaxed state='on'/>
<vpindex state='on'/>
<synic state='on'/>
<stimer state='on'/>
</hyperv>
...
</features>
<clock offset='localtime'>
<timer name='rtc' tickpolicy='catchup'/>
<timer name='pit' tickpolicy='delay'/>
<timer name='hpet' present='no'/>
<timer name='hypervclock' present='yes'/>
</clock>
https://openwrt.org/
https://stackoverflow.com/questions/65443317/libvirt-use-of-hugepages-on-numa-system
<memoryBacking> <hugepages/> <locked/> </memoryBacking>
https://www.codenong.com/cs109525281/
Day-41 iptables
(https://marcokhan.tistory.com/49)
Ubuntu 20.04 에 OSX 가상 머신 설치기
(https://www.boolsee.pe.kr/osx-kvm_on_ubuntu20/)
https://unix.stackexchange.com/questions/235414/libvirt-how-to-pass-qemu-command-line-args
$ virt-xml $DOMAIN --edit --confirm --qemu-commandline '-my-args 1234' $ virt-xml $DOMAIN --edit --confirm --qemu-commandline 'env=MY-ENV=1234'
How to Block IP Addresses from Countries with Geoip Addon in Iptables
(https://codepre.com/how-to-block-ip-addresses-from-countries-with-geoip-addon-in-iptables.html)
http://firewalld.org
http://fedoraproject.org/wiki/FirewallD
https://launchpad.net/~stefanberger/+archive/ubuntu/swtpm-focal
$ sudo add-apt-repository ppa:stefanberger/swtpm-focal $ sudo apt update $ sudo apt install -y swtpm-tools
https://www.smoothnet.org/qemu-tpm/
https://getlabsdone.com/how-to-enable-tpm-and-secure-boot-on-kvm/
qemu-kvm Guest VM(윈도우 10)에서 nvidia GPU path through 사용하기
(https://blog.boxcorea.com/wp/archives/3049)
<features>
<acpi/>
<apic/>
<hyperv>
...
<vendor_id state='on' value='1234567890ab' />
</hyperv>
<kvm>
<hidden state='on' />
</kvm>
<vmport state='off'/>
<ioapic driver='kvm' />
</features>
KVM hidden state 구문 - GPU passthrough
(https://vense.tistory.com/entry/KVM-hidden-state-%EA%B5%AC%EB%AC%B8)
<features>
...
<hyperv>
<vendor_id state='on' value='whatever'/>
</hyperv>
<kvm>
<hidden state='on'/>
</kvm>
...
</features>
PCI passthrough via OVMF
(https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF)
Enable Multi-Queue Support for NICs on KVM
(https://docs.paloaltonetworks.com/vm-series/8-1/vm-series-deployment/set-up-the-vm-series-firewall-on-kvm/performance-tuning-of-the-vm-series-for-kvm/enable-multi-queue-support-for-nics-on-kvm)
<interface type='network'>
<source network='default'/>
<model type='virtio'/>
<driver name='vhost' queues='N'/>
</interface>
Configure NIC multi-queue - alibabacloud
(https://www.alibabacloud.com/help/en/doc-detail/52559.htm)
멀티 큐(Multi-Queue) 사용 시 고려 사항 - 셀키의 블로그
(https://m.blog.naver.com/serkis_/221306589125)
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=kimjohan385&logNo=221398788627
https://wiki.crowncloud.net/?How_to_install_HWE_Kernel_on_Ubuntu_20_04
https://askubuntu.com/questions/1406888/ubuntu-22-04-gpu-passthrough-qemu
Edit /etc/default/grub (Example)
For AMD processor:
amd_iommu=on kvm.ignore_msrs=1
For Intel processor:
intel_iommu=on kvm.ignore_msrs=1
Update GRUB
$ sudo grub-mkconfig -o /boot/grub/grub.cfg
Reboot your system
Check that IOMMU is enabled
$ sudo dmesg | grep -i -e DMAR -e IOMMU
Find your device (PCI ids & driver, If driver need uninstall or add blacklist...)
$ lspci -nnk
...
Create&Edit /etc/modprobe.d/vfio.conf (Example)
blacklist nouveau
blacklist snd_hda_intel
options vfio-pci ids=<comma separated pci ids>
Update the existing initramfs
$ sudo update-initramfs -u
Reboot your system
...
https://azeria-labs.com/emulate-raspberry-pi-with-qemu/
https://gist.github.com/plembo/c4920016312f058209f5765cb9a3a25e
(Emulating a Raspberry Pi with QEMU)
https://www.youtube.com/watch?v=Y-FUvi1z1aU
(Emulating ARM64 Raspberry Pi Image using QEMU - YouTube)
https://codingsmith.tistory.com/entry/Raspberry-Pi-Linux-Kernel%EC%9D%84-Qemu%EC%97%90%EC%84%9C-%EC%8B%A4%ED%96%89
(Raspberry Pi Linux Kernel을 Qemu에서 실행)
https://wiki.ubuntu.com/ARM64/QEMU
https://wiki.ubuntu.com/ARM/RaspberryPi
https://wiki.ubuntu.com/Kernel/Dev/QemuARMVexpress
https://raduzaharia.medium.com/system-emulation-using-qemu-raspberry-pi-3-4973260ffb3e
(System emulation using qemu: Raspberry PI 3)
https://www.phoronix.com/news/IOMMUFD-Linux-6.2
(IOMMUFD Submitted For Linux 6.2 To Overhaul IOMMU Handling)
클라우드 서비스 이해하기 IaaS, PaaS, SaaS
(https://www.whatap.io/ko/blog/9/)
AWS
(https://aws.amazon.com/)
(EC2 는 Xen 기반이고 앞으로도 지속적으로 Xen 기반은 유지될 전망)
(https://aws.amazon.com/ko/ec2/faqs/)
(앞으로 새로운 인트턴스는 (C5 등...) KVM 기반이 도입되지만 Xen 기반도 유지하게 될 것)
(http://www.zdnet.co.kr/view/?no=20171108115328)
KT Cloud
(https://cloud.kt.com/)
공공 KT Cloud (공공 기관용)
(https://gov.ucloudbiz.kt.com/)
Google Cloud
(https://cloud.google.com/)
Azure Cloud
(https://azure.microsoft.com/)
NHN Cloud
(https://www.nhncloud.com/kr)
NHN Cloud (공공 기관용)
(https://gov.toast.com/kr)
Alibaba Cloud
(https://www.alibabacloud.com/)
Openstack
(https://www.openstack.org/)
KVM (Kernel Virtual Machine, for Kernel-based Virtual Machine)
(https://www.linux-kvm.org/page/Main_Page)
QEMU
(https://www.qemu.org/)
VMware
(https://www.vmware.com/)
Hyper-V
(https://docs.microsoft.com/ko-kr/virtualization/hyper-v-on-windows/about/)
Oracle VM VirtualBox
(https://www.virtualbox.org/)
Xen
(https://xenproject.org/)
Xen Hypervisor(Xen 하이퍼바이저) 란?
(https://mangkyu.tistory.com/82)