Ubuntu20.04 Server LTS 기준으로 가상머신 서버환경을 구축하는 방법을 소개합니다.
영문버젼으로 기본설치한 경우를 기준으로 설명합니다.
필자는 "xfce4", "xrdp", "libvirt-bin","virt-manager"설치 조합을 권장드린다는 점 먼저 말씀드리며 윈도우 PC에 모두 있는 "원격 데스크톱 연결" 프로그램으로 가상머신 서버에 접속해서 "Virtual Machine Manager" UI를 통해서 KVM을 제어한다는 구성이라는 설명과 함께 읽어주시면 좋겠습니다.
먼저Ubuntu20.04 Server LTS 배포판을 설치합니다. (본 문서는 20.04 기준으로 작성되었으나 14.04, 16.04, 18.04 에서도 설치되는 것을 확인했습니다.)
설치 직후 최신 패키지 업그레이드를 반영합니다. (권장사항)
$ sudo apt-get update
$ sudo apt-get upgrade
systemd 기반의 배포판의 경우 경우에 따라서 일정시간 경과 후 최대 절전모드로 진입할 수 있습니다. 이것을 원치 않는다면 다음과 같이 설정합니다. (권장사항)
$ 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
최소한의 설치를 위해서 불필요한 패키지(Package)들은 모두 제거(Uninstall) 합니다. (필요에 의해서 삭제를 원치 않는 경우 적절히 생략하시고 진행하세요)
nano 편집기 (선택사항, 필요 없는 경우 삭제합니다. vim 사용법을 잘 모르신다면 이 부분은 건너뛰세요.)
$ sudo apt-get remove nano --purge
vim tiny 편집기를 제거하고 vim original을 설치 (선택사항, vim-basic 이 있기 때문에 vim-tiny 는 삭제해도 됩니다. vim을 보다 전문적으로 사용하기 위한다면 권장합니다.)
=> swap을 비활성화 (메모리가 충분히 큰 경우만)
/etc/fstab 에서 swap 설저부분을 모두 주석처리하고 "sudo swapoff -a" 명령으로 비활성화 합니다.
=> swap 비율을 낮추는 설정 (메모리가 충분치는 않아서 swap을 비활성화하기 어려운 경우)
"/etc/sysctl.conf" 에 "vm.swappiness" 값을 50 ~ 60 사이로 추가합니다. 50에 가까울수록 swap 비율을 낮추게 됩니다. (필자는 55정도로 설정)
=> ZRAM을 사용할 경우 필자의 경우 가상머신이 실행중에 매우 낮은 확률로 오류 (압축된 스왑을 풀 수 없다는 오류) 가 발생되는 경우가 있었습니다. (최신 배포판에서는 해소된것으로 보임)
apt-repository 를 활성화 합니다. (선택사항, 반드시 필요한 사항은 아닙니다.)
server 0.asia.pool.ntp.org
server 1.asia.pool.ntp.org
server 2.asia.pool.ntp.org
server 3.asia.pool.ntp.org
timezone 설정 (대한민국 시간대로 설정)
$ sudo timedatectl set-timezone Asia/Seoul
또는
$ sudo dpkg-reconfigure tzdata
이후 재부팅시 그래픽 로그인창 (부팅시 X-Window/Gnome/KDE등이 구동될 필요가 없다는 것을 의미) 환경이 나오는 것을 원치 않으신다면 다음과 같이 graphical.target 을 multi-user.target 으로 바꾸어줍니다. (권장사항, 불필요한 그래픽처리 부하를 줄이는 효과.)
원격데스크탑(rdp, TCP/3389) 서버 설치 (권장사항, 일반 Microsoft Windows 의 "원격 데스크톱 연결"을 통해서 UI접속을 하실 수 있게 됩니다.)
Windows Manager(Gnome, KDE 등) 가 설치되어 있는 경우
$ sudo apt-get install xrdp
Windows Manager가 설치되어 있지 않고 최소한으로만 설치하고자 하는 경우
$ 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
설치 과정에서 "display manager"를 선택하라고 나올 수 있습니다. 이 경우 "lightdm" 을 선택하는 것을 기준으로 설명합니다. (선택 사항)
설치 완료 후 "/etc/xrdp/startwm.sh" 를 수정합니다. => 마지막 부분의 Xsession을 실행(exec)하는 부분은 모두 주석처리 또는 제거하시고 대신 그 위치에 "exec xfce4-session" 을 추가 (원격 접속이 잘 안되는 경우만 하시면 됩니다)
>>>
exec 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
$ 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" 명령이 실행될 수 있도록 추가해주세요.
또 다른 한글 입력기 (선택사항, fcitx, 한글 입력을 원하는 경우 ibus 말고 또 다른 방법 중 하나)
$ sudo apt-get install fcitx fcitx-hangul
=> 설치 후 /etc/default/im-config 를 편집기로 열어서 IM_CONFIG_DEFAULT_MODE 항목의 값을 auto 에서 fcitx 로 변경 후 저장하고 재부팅
FireFox 브라우져 (선택사항 : 브라우저 환경이 필요한 경우)
$ sudo apt-get install firefox
크롬브라우져(chromium browser) (선택사항 : 브라우저 환경이 필요한 경우)
$ sudo apt-get install chromium-browser
[PNG 그림 (33.49 KB)]
putty 사용법 ( xming X11 포워딩 )
에스타롯사 2019. 5. 27. 21:33
안녕하세요 롯사입니다.
이번 시간엔 리눅스 서버에 ssh 접속 시 사용하는 putty와 오픈소스 프리웨어 xming 이용하여 x11 forwarding
환경을 구성해보겠습니다.
기본적으로 x11 forwarding이라 함은 리눅스에 설치되어있는 프로그램을 내가 ssh 접속을 시도하는 windows
기반의 환경에 gui 형태로 프로그램을 출력해주는 기능을 말합니다. 그러기 위해선 기본적으로 forwarding 해서
gui 형태로 출력해주는 프로그램이 필요한데 그때 필요한 것이 바로 xming xserver입니다.
오프소스의 무료 버전이기 때문에 누구나 가볍고 심플하게 사용이 가능한 장점이 있고 사용법도 간단하기 때문에
유용하게 사용하실 수 있습니다.
그럼 본론으로 들어가서 windows 기반의 pc 나 서버에 xming xserver를 설치하고 putty의 x11 forwarding 기능을
xming 실행 옵션에 -ac를 추가하여 xhost +와 같은 효과를 주어 실행하도록한다.
display 설정 후 에도 다음과 같은 오류를 만나는걸 방지한다.
--------------------------------------------
connection to "remotehost:0.0"
No protocol specified
Can't open display: remotehost
--------------------------------------------
2. XLaunch 실행
3. Putty 설정 및 접속
1) 설정
Connection > SSH > X11 : Enable X11 forwarding 선택
X display location : localhost:0 입력
2) 접속
[root@rac1 ~]# xhost + access control disabled, clients can connect from any host [root@rac1 ~]# [root@rac1 ~]# su - oracle [oracle@rac1 ~]$ export DISPLAY=192.168.80.1:0.0
[oracle@rac1 ~]$ echo $DISPLAY 192.168.80.1:0.0 [oracle@rac1 ~]$ xclock Warning: Missing charsets in String to FontSet conversion
설치 진행 과정 중 바탕화면에 아이콘 생성 없이 설치를 진행하였지만 편의를 위해서 바탕화면에 아이콘을
추가하였습니다.
XLaunch을 눌러서 설정에 들어갑니다.
gui를 출력했을 때 나오는 type으로 취양에 맞게 선택하시면 됩니다.
저는 default 선택을 하고 다음으로 넘어가겠습니다.
default "Start no client" 선택하고 넘어갑니다.
default 다음
마침을 눌러서 설정을 마무리합니다.
설정을 마무리하고 나오면 오른쪽 하단에 xming 아이콘 표시와 함께 실행 상태가 표시됩니다.
putty gui 실행
putty를 실행하고 SSH의 X11 항목에서 X11 forwarding 항목을 체크합니다.
서버에 접속할 때 X11 기능을 활성화한다는 의미로 생각하시면 되겠습니다.
Session 항목에서 host의 ip 주소를 입력하고 접속합니다.
실제 putty에 접속해서 리눅스 기반의 firefox 웹브라우저를 띄어놓은 화면입니다.
firefox & ( firefox 실행 command )
사용하시는 프로그램마다 실행하는 command가 다르기 때문에 사전에 확인하시고 사용하시기 바랍니다.
KVM + QEMU 가상서버 설치
KVM + QEMU 및 기반유틸 설치
Ubuntu 18.04 이하인 경우
$ sudo apt-get install qemu-kvm libvirt-bin ovmf ubuntu-vm-builder bridge-utils
Ubuntu 20.04 이상인 경우
$ sudo apt install qemu-kvm ovmf bridge-utils libvirt-daemon-system
추가적으로 다음의 패키지 설치를 권장합니다. (권장사항, 만약 문제가 발생되고 이를 이해하기 어렵거나 스스로 해결하기 어렵다면 설치를 우선은 생략하세요.)
$ sudo apt install firewalld dnsmasq
$ sudo systemctl enable --now firewalld
$ sudo systemctl restart libvirtd
firewalld 의 firewall-cmd 명령에 대한 개략적인 사용법
=> 특정 인터페이스를 zone 에 합류 시키려면 : firewall-cmd [--permanent] [--zone=] --add-interface=
=> 특정 서비스를 zone 에 허용하려면 : firewall-cmd [--permanent] [--zone=] --add-service=
=> 특정 포트를 zone 에 허용하려면 : firewall-cmd [--permanent] [--zone=] --add-port=[-]/
=> IKE/NAT-T 허용 : firewall-cmd [--permanent] [--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=] --add-rich-rule='rule protocol value="esp" accept'
=> AH 프로토콜 허용 : firewall-cmd [--permanent] [--zone=] --add-rich-rule='rule protocol value="ah" accept'
=> IPCOMP 프로토콜 허용 : firewall-cmd [--permanent] [--zone=] --add-rich-rule='rule protocol value="ipcomp" accept'
=> IPEncap 프로토콜 허용 : firewall-cmd [--permanent] [--zone=] --add-rich-rule='rule protocol value="ipencap" accept'
=> 특정 출발지 대역 거부 : firewall-cmd [--permanent] [--zone=] --add-rich-rule='rule family="ipv4" source address="
/" drop' => 특정 목적지 대역 거부 : firewall-cmd [--permanent] [--zone=] --add-rich-rule='rule family="ipv4" destination address="/" drop' => 특정 목적지 대역과 포트를 거부 : firewall-cmd [--permanent] [--zone=] --add-rich-rule='rule family="ipv4" destination address="/" port="23" protocol="tcp" drop' => 특정 포트 개방 (DNAT) : firewall-cmd [--permanent] [--zone=] --add-forward-port='port=:proto=:toport=:toaddr=' => Masquerade 허용 : firewall-cmd [--permanent] [--zone=] --add-masquerade => 특정 출발지 대역만 masquerade : firewall-cmd [--permanent] [--zone=] --add-rich-rule='rule family="ipv4" source address="/" masquerade' => 기본 정책을 REJECT가 아닌 DROP으로 처리하는 경우 : firewall-cmd [--permanent] [--zone=] --add-rich-rule='rule priority="32767" drop' GeoIP DB를 사용하여 특정 국가별 차단등을 관리하고자 한다면 다음과 같이 설치 및 몇가지 제반사항을 진행해야 합니다. (선택적 권고사항, [^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 $ firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -m geoip --src-cc CN,RU,KP -j DROP 추가적으로 ARM archtecture에 대한 에뮬레이션을 원하신다면 다음과 같이 추가로 QEMU arm 지원을 추가할 수 있습니다. (선택사항, Android나 Raspberry pi 등을 ARM archtecture 로 에뮬레이션하고 싶다면 설치하세요.) $ sudo apt install qemu-user-static qemu-system-arm qemu-efi
특정 계정에게 사용권한을 할당하려면 다음과 같이 libvirtd group에 userid 를 추가해줍니다. (만약 현재 로그인한 계정에서 추가했다면 다시 로그인해야 권한이 반영됩니다.)
$ sudo adduser `id -un` libvirtd
Adding user '<username>' to group 'libvirtd' ...
KVM + QEMU 설치 확인
Intel VT-x 와 AMD-V 중에서 H/W 가속이 지원 가능한 경우 0보다 큰 값이 출력됩니다.
$ egrep -c '(vmx|svm)' /proc/cpuinfo
KVM+QEMU 관리 UI 프로그램인 virt-manager 설치 (강력추천, 윈도우상의 "시스템" 메뉴에 보시면 "Virtual Machine Manager"가 설치되며 이를 실행하여 손쉽게 가상환경을 다루실 수 있습니다.)
$ sudo apt-get install virt-manager
올바르게 설치되었다면 다음과 같이 나올겁니다.
$ virsh list --all
Id Name State
----------------------------------
$
virt-manager 에서 원격지의 KVM+QEMU 서버를 SSH를 경유하여 관리하고자 한다면 하기와 같이 ssh-askpass-gnome package를 추가로 설치합니다.
$ sudo apt-get install ssh-askpass-gnome
만약 설치에 문제가 있다면 다음과 비슷하게 나올겁니다.
$ virsh list --all
libvir: Remote error : Permission denied
error: failed to connect to the hypervisor
$
VirtualBox 설치 (선택사항, 실제 사용계획이 있는 경우만 설치하세요.)
$ sudo apt-get install virtualbox
Docker 설치 (선택사항, 만약 libvirt와 firewalld 가 운영중인 환경에 docker 를 운영하기 위해서는 몇가지 네트워크에 대한 전문적인 구성이 필요하므로 잘 다룰 수 없다면 생략하세요.)
$ sudo apt-get install docker.io
$ sudo apt-get install docker-compose
자신의 계정을 docker 사용 group에 추가하려면 다음과 같이 실행합니다.
$ sudo usermod -a -G docker $(whoami)
추가적으로 multi architecture/platform docker build 환경 (docker buildx) 을 위해서 다음과 같이 추가적인 설치과정이 필요합니다. 결국 하기 명령은 docker 의 CLI plugin 으로 buildx 를 추가하는 것으로 이해하시면 됩니다. (선택사항)
$ 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' 로 확인 후 적절히 추가 옵션을 주어 사용하실 수 있습니다. */
docker buildx 가 일부 문제(bug)가 있을 경우 다음과 같은 조치가 되어야 할 수 있습니다. 이 명령은 default 대신 새로운 빌더를 추가하여 사용하게 되는 명령입니다. (선택사항, 특정 architecture/platform 빌드시에만 문제가 발생하는 경우 시도해볼만 합니다.)
$ 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 로 Dockerfile 은 다음과 같이 build 및 push를 할 수 있습니다. (선택사항, 참고, platform은 자신의 구성환경 및 목표에 맞게 지정하여 빌드)
$ docker buildx build --push --platform linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/riscv64,linux/s390x --tag "" .
=> 참고) "/etc/docker/daemon.json" 을 적절히 아래와 같이 수정하여 firewalld/iptables 등을 고려할 필요가 있을 수 있음. (아래의 설정내용은 예시이며 각 환경에 따라서 전문적으로 수정할 필요성 있음)
{
"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
{
"bip": "198.18.1.1/24",
"userland-proxy": false
}
OR
{
"bip":"198.18.1.1/24",
"iptables":false,
"ip-forward":false,
"ip-masq":false,
"userland-proxy":true
}
passthrough 란 KVM+QEMU 서버에서 해당 PCI 장치를 사용하지 않고 가상화 호스트에서 이 장치를 단독으로 사용할 수 있게 하는 방법입니다. (PCI 장치를 가상화 호스트에 PCI장치로 인식하고 단독으로 사용)보통은 그래픽 장치나 오디오등의 미디어 장치, 그리고 Ethernet 장치등을 이렇게 사용합니다.
먼저 필수적으로 BIOS 설정에서 "VT-d (Intel)" 또는 "AMD IOMMU (AMD)" 관련 옵션이 있으면 활성(Enable)해주세요.
>>> grub 파일을 수정합니다. (Intel CPU 인 경우는 "intel_iommu=on", AMD CPU 인경우는 "amd_iommu=on")
>>> 기본적인 옵션은 "intel_iommu=on iommu=pt" 이고 추가적으로 자신의 장비에 상황에 따라서 참고하여 아래의 옵션을 추가로 사용합니다. (혹시 장치가 동작하지 않는다면 "iommu=pt" 옵션을 빼보고 해볼 필요가 있습니다. 성능 측면에서는 pt 가 있는게 좋습니다.)
>>> "rd.driver.pre=vfio-pci" 옵션은 ramdisk 로부터 vfio-pci module 을 올리도록 합니다. (Ubuntu 기반 배포판의 경우 꼭 추가해주어야 합니다.)
>>> "vfio_iommu_type1.allow_unsafe_interrupts=1" MSR 을 허용해주는 것으로 우선 이 옵션을 빼고 해보시고 MSR관련 오류가 나온다면 이 옵션을 추가해주시면 됩니다. (단, 이 옵션은 실행하는 가상호스트가 신뢰할 수 있을 때만 사용하셔야 합니다. 신뢰할 수 없는 가상호스트인 경우 이 옵션을 사용하지 않는게 좋습니다.)
$ sudo vi /etc/default/grub
GRUB_CMDLINE_LINUX="intel_iommu=on iommu=pt rd.driver.pre=vfio-pci vfio_iommu_type1.allow_unsafe_interrupts=1"
>>> nVidia인 경우 하기와 같이 blacklist 로 추가합니다. (즉, passthrough 할 장치와 관련성이 있는 driver/module이 불필요하게 올리지 않도록 각자의 passthrough 장치에 따라서 조치가 필요합니다.)
$ sudo vi /etc/modprobe.d/blacklist-nouveau.conf
blacklist nouveau
options nouveau modeset=0
>>> grub 설정의 변경사항을 반영합니다.
>>> 하기 명령 또는 "sudo grub-mkconfig -o /boot/grub/grub.cfg"
$ sudo update-grub
>>> PCI 목록에서 passthrough 할 장치의 ID를 확인해둡니다.
>>> 저의 경우는 Quadro FX1800 이 있는 장비는 passthrough 할 그래픽 카드의 PCI ID 가 "10de:0638" 이네요.
$ sudo lspci -nn | grep -i nvidia
07:00.0 VGA compatible controller [0300]: NVIDIA Corporation G94GL [Quadro FX 1800] [10de:0638] (rev a1)
>>> 저의 경우는 GT730 이 있는 장비는 passthrough 할 그래픽 카드의 PCI ID 가 "10de:1287"과 "10de:0e0f" (Audio) 이네요.
$ sudo lspci -nn | grep -i nvidia
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)
>>> 저의 경우는 GT1030 이 있는 장비는 passthrough 할 그래픽 카드의 PCI ID 가 "10de:1d01"과 "10de:0fb8" (Audio) 이네요.
$ sudo lspci -nn | grep -i nvidia
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)
>>> passthrough 할 PCI 장치의 ID를 vfio.conf 파일을 만들어서 ids의 값으로 편집합니다.
>>> 만약 장치가 여러개라면 PCI 장치의 ID를 콤마(,)로 구분하여 쭉 넣어줍니다.
>>> Quadro FX1800 가 있는 장비의 경우
$ sudo vi /etc/modprobe.d/vfio.conf
options vfio-pci ids=10de:0638
options vfio-pci disable_vga=1
>>> GT730 이 있는 장비의 경우
$ sudo vi /etc/modprobe.d/vfio.conf
options vfio-pci ids=10de:1287,10de:0e0f
options vfio-pci disable_vga=1
>>> GT1030 이 있는 장비의 경우
$ sudo vi /etc/modprobe.d/vfio.conf
options vfio-pci ids=10de:1d01,10de:0fb8
options vfio-pci disable_vga=1
>>> vfio-pci 모듈 설정 활성화
$ sudo -i
$ echo 'vfio-pci' > /etc/modules-load.d/vfio-pci.conf
>>> initramfs 갱신 (부팅에서 initramfs 기반 배포판이 아닌 경우이거나 Ubuntu가 아닌 배포판의 경우는 이 과정이 다를 수 있습니다.)
$ sudo update-initramfs -u
>>> 재부팅 필요
$ sudo reboot
>>> 재부팅 된 후 부팅메세지(dmsg)를 보시면 "DMAR" 또는 "IOMMU" 라는 문자열을 포함한 메세지가 확인된다면 준비된 것입니다. (이제 해당 PCI 장치는 가상머신에게 모든 권한을 위임할 준비가 된 자원이 됩니다. 환경에 따라서 약간 다른 메세지로 보일 수 있습니다.)
$ sudo dmesg | grep -E "DMAR|IOMMU"
[ 0.000000] ACPI: DMAR 0x00000000BF77E0C0 000100 (v01 AMI OEMDMAR 00000001 MSFT 00000097)
[ 0.000000] DMAR: IOMMU enabled
[ 0.000000] DMAR-IR: This system BIOS has enabled interrupt remapping
[ 1.271828] DMAR: Host address width 40
[ 1.271916] DMAR: DRHD base: 0x000000fbffe000 flags: 0x1
[ 1.272041] DMAR: dmar0: reg_base_addr fbffe000 ver 1:0 cap c90780106f0462 ecap f020f6
[ 1.272167] DMAR: RMRR base: 0x000000000ed000 end: 0x000000000effff
[ 1.272262] DMAR: RMRR base: 0x000000bf7ed000 end: 0x000000bf7fffff
[ 1.272356] DMAR: ATSR flags: 0x0
[ 1.272756] DMAR: dmar0: Using Queued invalidation
[ 1.272860] DMAR: Setting RMRR:
[ 1.273164] DMAR: Setting identity map for device 0000:00:1a.0 [0xbf7ed000 - 0xbf7fffff]
[ 1.273537] DMAR: Setting identity map for device 0000:00:1a.7 [0xbf7ed000 - 0xbf7fffff]
[ 1.273895] DMAR: Setting identity map for device 0000:00:1d.0 [0xbf7ed000 - 0xbf7fffff]
[ 1.274257] DMAR: Setting identity map for device 0000:00:1d.1 [0xbf7ed000 - 0xbf7fffff]
[ 1.274618] DMAR: Setting identity map for device 0000:00:1d.2 [0xbf7ed000 - 0xbf7fffff]
[ 1.275036] DMAR: Setting identity map for device 0000:00:1d.7 [0xbf7ed000 - 0xbf7fffff]
[ 1.275179] DMAR: Setting identity map for device 0000:00:1a.0 [0xed000 - 0xeffff]
[ 1.275315] DMAR: Setting identity map for device 0000:00:1a.7 [0xed000 - 0xeffff]
[ 1.275450] DMAR: Setting identity map for device 0000:00:1d.0 [0xed000 - 0xeffff]
[ 1.275585] DMAR: Setting identity map for device 0000:00:1d.1 [0xed000 - 0xeffff]
[ 1.275720] DMAR: Setting identity map for device 0000:00:1d.2 [0xed000 - 0xeffff]
[ 1.275855] DMAR: Setting identity map for device 0000:00:1d.7 [0xed000 - 0xeffff]
[ 1.275992] DMAR: Prepare 0-16MiB unity mapping for LPC
[ 1.276402] DMAR: Setting identity map for device 0000:00:1f.0 [0x0 - 0xffffff]
[ 1.276713] DMAR: Intel(R) Virtualization Technology for Directed I/O
>>> 또한 vfio-pci 모듈이 잘 활성화(Enabled) 되었는지 확인하면 됩니다. (이 메세지는 실제 가상화 호스트가 구동되어 해당 장치가 passthrough활성화 될 때 확인가능합니다. 가상화 호스트 구동하지 않으면 안나옵니다.)
$ 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)
아래 화면은 제 그래픽 카드를 passthrough 설정하여 가상머신에서 사용하도록 설정하는 화면입니다.
# 사용법 : 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
가상환경의 console 접속 (console 정의가 설정된 가상환경과 해당사항을 지원하는 OS인 경우에 대한 제한적 사용)
$ virsh console <Name>
아무것도 하지 않는데도 불구하고 가상머신의 CPU 부하가 큰 경우 (또는 운영체제 부팅과정에서 Timer 관련 오류등이 있는 경우 시도해볼만한 설정, 권장)
$ 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>
<<<
<!-- 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>
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"
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
}
disk swap 보다 월등히 빠른 압축 메모리 기법의 swap기능인 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 를 낮추는 수정을 권장)
위 사항에 추가적으로 pit 를 'delay' 가 아닌 'discard'로 설정하는 것을 시도해볼만합니다.
hypervisor를 kvm을 지원하는 Guest OS인 경우 kvmclock을, Hyper-V를 지원하는 Guest OS인 경우 hypervclock을 'yes'로 설정하면 됩니다. (Hypervisor clock을 지원한다면 pit 와 hpet는 비활성화하여도 됩니다.)
virsh list --all Id Name State ---------------------------------------------------- 3 ubuntu01 running virsh destory ubuntu01 //ubuntu01 종료하기 virsh edit ubuntu01 //ubuntu01 XML 수정하기 virsh start ubuntu01 //ubuntu01 시작하기 virsh-viewer 4//virt-viewer통해서 화면 보기
ubuntu01에 랜카드 하나 추가시키기KVM1 terminal에서 다음 명령어를 입력한다.
virsh net-list Name State Autostart Persistent ---------------------------------------------------------- default active yes yes test1 active yes yes virsh list Id Name State ---------------------------------------------------- 4 ubuntu01 running virsh attach-interface --domain ubuntu01 --source test1 --model virtio --config --live --type network
오늘 진행한 KVM는 하이퍼바이저 유형 1이다. 언뜻 보기에는 유형 2처럼 보이지만, OS의 도움을 받아 KVM이 Kernel을 구축하여 VM과 물리자원을 연결하는 역할을 한다. 반면 VMware ESI는 단일적으로 OS역할(boot영역)까지 담당하여 확실하게 유형 1이라는 것을 알 수 있다.