2009/05/07

가상화와 윈도우즈 게스트의 네트웍 성능

1.Type 2 하이퍼바이저의 게스트 운영체제를 위한 네트웍 구성
오픈솔라리스 (opensolaris)에서 버추얼 박스를 통한 Type 2 가상화 시스템을 운영하고 있습니다. 3개의 윈도우즈 XP Pro guest 와 1개의 Opensolaris guest, 1개의 Ubuntu guest를 구성해놓은 상태에서 3개의 windows XP는 상시 운영하고 있습니다.

Type 1의 가상화인 xvm이나 vmware와는 달리 Type 2의 경우에는 가상화된 영역내의 네트웍 카드를 가상화 시스템인 Type 2 하이퍼바이저로부터 부여 받게 됩니다. 저의 경우에는 '버투얼박스'에 의해서 네트웍 카드를 가상화 게스트에 할당하게 됩니다.

이때 구성할 수 있는 네트웍 카드는 AMD PCNET Family PCI Ethernet Card가 기본으로 잡히고 Intel EtherPro Desktop 100Mb 네트웍 카드도 잡을 수 있습니다. 사실 하이퍼 바이저의 입장에서는 다른 네트웍 디바이스를 프리젠트하면서, 게스트 운영체제의 디바이스 드라이버로부 서로 다르게 받아지는 명령어들을 에뮬레이션 하는 부분에서의 성능 차이가 매우 클 것입니다만 이 이야기는 여기서 언급할 내용은 아닙니다. 기회가 되면 이부분을 언급해 보겠습니다.

하이퍼바이저에서 사용할 네트웍 카드를 선정하게 되면, 게스트에게 가상 네트웍 카드를 사용하는 방식을 결정해야 하는데, 이 방식에 따라서 게스트 운영체제가 IP 주소를 설정하는 방식이 변경되게 됩니다.

가장 기본적인 방식인 NAT 방식을 설정하면 게스트 운영체제는 하이퍼바이저가 제공하는 사설 IP 주소를 DHCP 방식으로 부여받게 되고, 하이퍼 바이저는 내장된 NAT 기능을 통해 자체적으로 default gateway 역할을 함과 동시에 외부 운영체제(하이버바이저가 실행되고 있는 운영체제)로 게스트의 패킷들을 포워딩하게 됩니다. 이후 시스템 운영체제가 패킷을 적당히 포워딩하게 됩니다.

NAT 방식과는 달리 게스트 운영체제에 '호스트 인터페이스(Host Interface)' 방식을 설정할 수 도 있습니다. 이 방식을 선택하게 되면, 게스트 설정시 사용할 실제 네트웍카드로 선택을 해야 하는데, 게스트에 나타나는 가상화된 네트웍 카드를 마치 서버의 실제 네트웍 카드인것처럼 동작하도록 합니다. 즉, 게스트 운영체제는 실제로 실제 연결된 네트웍 카드를 통해 외부 네트웍에 직접 연결되어 있는 형태를 가지게 됩니다. 이때의 경우에는 게스트 운영체제가 해당 네트웍카드에서 DHCP 클라이언트를 운영하여 IP를 받을 수 있음은 물론, 정적 IP를 임의로 설정할 수도 있게 됩니다.

브로드컴 네트웍 카드(bge0)카드에 192.168.x.x 정적 주소를 가진 서버가 한대 있다고 합시다. 이 서버에 버추얼 박스를 설치 실행해서 설정된 게스트 중 NAT 방식은 게스트가 10.x.x.x 대의 IP를 받게되고 하이퍼바이저의 패킷 포워딩에 따라서 패킷이 움직이는 반면, 'Host Interface' 방식은 서버의 bge0 에 설정된 192.168.x.x와 같은 네트웍 단의 주소를 정적으로 설정하거나 DHCP로 받을 수 있게 됩니다.

이 두방식은 용도와 목적에 따라서 장단점이 있습니다. 일반 기업에서 서비스를 올리기 위해서는 '호스트 인터페이스'가 나은 면이 있고, 개발자들의 용도라면 NAT가 편리합니다. 기업내 네트웍을 담당하는 부서에 요청할 필요가 없기 때문이죠.

그런데, NAT 를 사용하게 되면 이미 언급된 대로 하이퍼 바이저를 통해서 패킷에 헤드 비트들이 추가적으로 붙게 되므로 직접 붙는 경우와 달리 패킷당 크기가 변하게 됩니다. 윈도우즈 게스트들은 기본적으로 단위 전송 크기(MTU)를 1500으로 고정을 하게 된 상태로 운영하는데 이렇게 되면 게스트에서는 단일 패킷이지만, 버추얼박스에서 추가된 비트들로 인해 두 패킷으로 분리되어 두개로 나가게 되는 경우가 생기게 됩니다. 이렇게 되면 버추얼 박스가 한번 보내면 될 것을 두번 보내야 하므로 CPU를 더 쓰게 되고, 게스트 입장에서 볼때는 성능이 더 떨어지게 됩니다. 하이퍼 바이저가 두번처리하는 것을 기다려야 하기 때문이죠.

따라서, 이와 같이 Type 2 기반의 가상화를 하는 경우에는 게스트 운영체제에 Ethernet MTU 크기를 변경함으로써 하이퍼바이저가 두번할일을 최소화 시킴으로써 시스템이 느려지는 것을 최대한 막아볼 수 있습니다.(역으로 얘기하자면, 기본 구성 대비 성능이 좋아지는 셈이죠)

2. MTU 변경을 통한 성능 개선
2.1 윈도우즈 게스트 튜닝
일단, 현재 구성된 상황에서 MTU가 문제가 없는 지 확인을 하기 위해서는 Windows Guest 내에서 도스 명령어 창을 실행합니다. "시작 -> 실행 -> cmd 입력"
여기에서 외부 인터넷의 한 사이트의 IP 주소를 설정하고 어떤 패킷의 크기가 적합한 지를 검사해봅니다.
여기에서는 www.google.com 의 한 IP 주소를 사용했습니다. 참고로, 제가 테스트하는 네트웍은 미국의 화이어월을 통해서 패킷이 나가는 경우이므로 나라와 상황에 따라 다를 수 있으므로 적절한 사이트의 주소를 선택하실 필요가 있습니다.

만약 www.google.com이 아닌 www.naver.com의 IP 주소 를 획득하고 싶다면, 도스 창에서 다음과 같이 실행하면 여러개의 IP를 얻을 수 있습니다.

>nslookup www.naver.com

테스트용 주소를 결정했으면 (여기서는 64.233.189.104) 다음과 같이 실행해서 MTU 길이에 따른 문제가 있는 지를 확인해봅니다.

>ping 64.233.189.104 -f -l 1500
C:\>ping 64.233.189.104 -f -l 1500
Pinging 64.233.189.104 with 1500 bytes of data:
Packet needs to be fragmented but DF set.

Packet needs to be fragmented but DF set.
Packet needs to be fragmented but DF set.
Packet needs to be fragmented but DF set.
Ping statistics for 64.233.189.104:

Packets: Sent = 4, Received = 0, Lost = 4 (100% loss)

위와 같은 메세지가 나오면 위 명령어에서 1500부터 10씩 빼가면서 테스트를 해봅니다.
C:\>ping 64.233.189.104 -f -l 1480
Pinging 64.233.189.104 with 1480 bytes of data:
Packet needs to be fragmented but DF set.

Packet needs to be fragmented but DF set.
Packet needs to be fragmented but DF set.
Packet needs to be fragmented but DF set.
Ping statistics for 64.233.189.104: Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),

C:\>ping 64.233.189.104 -f -l 1470
Pinging 64.233.189.104 with 1470 bytes of data:
Reply from 64.233.189.104: bytes=56 (sent 1470) time=113ms TTL=127

Reply from 64.233.189.104: bytes=56 (sent 1470) time=109ms TTL=127
Reply from 64.233.189.104: bytes=56 (sent 1470) time=105ms TTL=127
Reply from 64.233.189.104: bytes=56 (sent 1470) time=111ms TTL=127
Ping statistics for 64.233.189.104: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),



1470 bytes에서 "Packet needs to be fragmented but DF set" 없이 작동되고 있음을 알 수 있습니다. 단단위의 튜닝을 좀 더 해볼 수도 있습니다.
그렇게 해서 최적의 MTU가 나왔다면 (예를 들어, 1472) 이제는 레지스트리에 저장을 해야 합니다. 레지스트리를 수정하는 자제하는 방법은 여기를 참고하십시요. 쉽게 얘기하면
"시작버튼->실행->regedit" 을 실행합니다. 좌측 트리에서 다음과 같이 순서를 찾습니다.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\
네트웍 인터페이스가 너무 많아서 어떤 것인지 모르겠으면 죄다 설정하십시요.
좌측 트리에서 각 ID 위에 마우스를 두고 우측 버튼을 누르면 'New..'가 나타납니다. 여기서 DWORD 값을 추가하면 우측 화면에 키 이름을 넣으라고 나옵니다. 여기에서 MTU 라고 입력하시고, MTU에서 마우스 우측 버튼을 누르면 'Modify Key' 가 나옵니다. 선택하시고 값을 입력하시는 데 우측 아래에서 십진수(Decimal)을 선택하신후 1472를 입력합니다.

같은 방법으로 모든 네트웍 카드에 대해서 설정하시고, regedit을 종료한 후에, 게스트 운영 체제를 재부팅합니다.