# Docker-KVM 기반 Windows VM 서버 구축 가이드 ## 📋 목차 1. [시스템 개요](#시스템-개요) 2. [아키텍처 상세 분석](#아키텍처-상세-분석) 3. [기술 스택 및 구성 요소](#기술-스택-및-구성-요소) 4. [설치 및 배포 과정](#설치-및-배포-과정) 5. [네트워크 구성 및 포트 포워딩](#네트워크-구성-및-포트-포워딩) 6. [보안 설정 및 방화벽 구성](#보안-설정-및-방화벽-구성) 7. [문제 해결 및 트러블슈팅](#문제-해결-및-트러블슈팅) 8. [성능 최적화](#성능-최적화) 9. [모니터링 및 유지보수](#모니터링-및-유지보수) ## 🎯 시스템 개요 이 시스템은 **Docker 컨테이너 내부에 KVM(Kernel-based Virtual Machine) 하이퍼바이저를 설치**하고, **Vagrant를 사용하여 Windows 10 가상 머신을 구동**하는 복합적인 가상화 구조입니다. ### 주요 특징 - **3단계 가상화**: Docker → KVM → Windows VM - **원격 접속**: RDP(Remote Desktop Protocol)를 통한 외부 접속 지원 - **자동화된 배포**: Docker Compose를 통한 원클릭 배포 - **네트워크 격리**: 컨테이너 레벨의 네트워크 격리 및 포트 포워딩 ### 사용 사례 - 개발 환경 격리 - Windows 애플리케이션 테스트 - 교육용 가상 머신 제공 - 크로스 플랫폼 개발 환경 ## 🏗️ 아키텍처 상세 분석 ### 전체 시스템 아키텍처 ```mermaid graph TB subgraph "외부 네트워크" A["RDP 클라이언트
192.168.1.100"] B["HTTP 클라이언트
192.168.1.101"] end subgraph "호스트 서버 (Ubuntu 20.04)" C["iptables FORWARD Chain
기본 정책: DROP"] D["Docker 데몬
포트 매핑: 33890→3389"] E["호스트 네트워크
eth0: 192.168.1.10"] end subgraph "Docker 컨테이너 (Ubuntu 20.04)" F["libvirtd 데몬
가상화 관리"] G["Vagrant
VM 오케스트레이션"] H["컨테이너 iptables
NAT 규칙"] I["가상 네트워크
virbr0: 192.168.121.0/24"] end subgraph "KVM 가상 머신" J["Windows 10 Enterprise
IP: 192.168.121.251
RDP: 3389
HTTP: 8090"] K["Chocolatey 패키지 매니저"] L["Java 17 Runtime"] end A -->|RDP:33890| C B -->|HTTP:8081| C C -->|FORWARD 규칙| D D -->|포트 포워딩| H H -->|NAT 변환| J F -->|VM 관리| J G -->|VM 생성/관리| J ``` ### 네트워크 플로우 상세 ```mermaid sequenceDiagram participant Client as RDP 클라이언트 participant Host as 호스트 서버 participant Docker as Docker 데몬 participant Container as 컨테이너 participant VM as Windows VM Client->>Host: RDP 연결 요청 (33890) Host->>Host: iptables PREROUTING 체인 Host->>Docker: DNAT: 33890 → 3389 Docker->>Container: 포트 포워딩 Container->>Container: iptables NAT 규칙 Container->>VM: 최종 전달 (192.168.121.251:3389) VM->>Container: RDP 응답 Container->>Docker: 응답 전달 Docker->>Host: 응답 전달 Host->>Client: RDP 세션 수립 ``` ## 🔧 기술 스택 및 구성 요소 ### 1. 컨테이너 기술 - **Docker**: 애플리케이션 컨테이너화 - **Docker Compose**: 멀티 컨테이너 오케스트레이션 - **Ubuntu 20.04**: 베이스 운영체제 ### 2. 가상화 기술 - **KVM (Kernel-based Virtual Machine)**: 하이퍼바이저 - **QEMU**: 하드웨어 에뮬레이션 - **libvirt**: 가상화 관리 라이브러리 - **Vagrant**: VM 오케스트레이션 도구 ### 3. 네트워크 기술 - **iptables**: 방화벽 및 NAT - **bridge-utils**: 네트워크 브리지 관리 - **virbr0**: libvirt 기본 브리지 네트워크 ### 4. 원격 접속 기술 - **RDP (Remote Desktop Protocol)**: Windows 원격 데스크톱 - **SSH**: 컨테이너 관리 접속 ## 📦 설치 및 배포 과정 ### 1. 사전 요구사항 ```bash # 호스트 서버 요구사항 - Ubuntu 20.04 LTS 이상 - Docker 및 Docker Compose 설치 - KVM 하드웨어 가상화 지원 (Intel VT-x/AMD-V) - 최소 16GB RAM (VM용 8GB + 시스템용 8GB) - 최소 50GB 디스크 공간 ``` ### 2. Docker 이미지 빌드 과정 ```dockerfile # Dockerfile 주요 단계별 분석 # 1단계: 베이스 이미지 설정 FROM ubuntu:20.04 ENV DEBIAN_FRONTEND=noninteractive # 2단계: 가상화 패키지 설치 RUN apt-get install -y qemu-kvm libvirt-daemon-system libvirt-clients \ bridge-utils virt-manager wget unzip gnupg kmod openssh-client net-tools # 3단계: Vagrant 설치 RUN wget https://releases.hashicorp.com/vagrant/2.4.6/vagrant_2.4.6-1_amd64.deb && \ apt-get install -y ./vagrant_2.4.6-1_amd64.deb # 4단계: vagrant-libvirt 플러그인 설치 RUN vagrant plugin install vagrant-libvirt # 5단계: Windows 10 Vagrant Box 다운로드 RUN vagrant box add peru/windows-10-enterprise-x64-eval --provider libvirt ``` ### 3. 컨테이너 실행 설정 ```yaml # docker-compose.yml 주요 설정 분석 services: win10-kvm: build: . privileged: true # KVM 접근 권한 security_opt: - "apparmor:unconfined" # 보안 제한 해제 cap_add: - NET_ADMIN # 네트워크 관리 권한 devices: - /dev/kvm # KVM 디바이스 접근 - /dev/net/tun # TUN 디바이스 접근 ports: - "33890:3389" # RDP 포트 포워딩 - "8081:8090" # HTTP 포트 포워딩 volumes: - /lib/modules:/lib/modules:ro # 커널 모듈 공유 ``` ### 4. VM 구성 설정 ```ruby # Vagrantfile 주요 설정 분석 Vagrant.configure("2") do |config| config.vm.box = "peru/windows-10-enterprise-x64-eval" config.vm.provider "libvirt" do |libvirt| libvirt.memory = 8192 # 8GB 메모리 할당 libvirt.cpus = 4 # 4개 CPU 코어 할당 end # Windows VM 초기 설정 스크립트 config.vm.provision "shell", inline: <<-SHELL # Chocolatey 패키지 매니저 설치 # Java 17 런타임 설치 # 기타 필요한 소프트웨어 설치 SHELL end ``` #### Vagrant 역할 및 동작 방식 **Vagrant**는 이 프로젝트에서 Windows 10 VM의 생성, 구성, 관리를 자동화하는 핵심적인 **오케스트레이션 도구**입니다. 개발자가 코드로 가상 환경을 정의하고, 명령어 하나로 일관된 개발 환경을 구축할 수 있게 해줍니다. - **`Vagrantfile`**: - `Vagrantfile`은 VM을 어떻게 설정할지를 정의하는 **설계도**와 같습니다. 루비(Ruby) 구문으로 작성됩니다. - **`config.vm.box`**: VM을 생성할 때 기반이 되는 "Box" 이미지를 지정합니다. 여기서는 `peru/windows-10-enterprise-x64-eval`를 사용하여 사전 설치된 Windows 10 이미지를 다운로드합니다. - **`config.vm.provider`**: VM을 실행할 가상화 기술(Provider)을 지정합니다. `libvirt`를 명시하여 KVM을 사용하도록 설정합니다. - **자원 할당**: VM에 할당할 메모리(`libvirt.memory`)와 CPU 코어 수(`libvirt.cpus`)를 정의합니다. - **`vagrant-libvirt` 플러그인**: - Vagrant는 플러그인 아키텍처를 통해 VirtualBox, VMware, Hyper-V 등 다양한 가상화 기술을 지원합니다. - 이 프로젝트에서는 `vagrant-libvirt` 플러그인을 사용하여 Vagrant가 `libvirt` API를 통해 KVM/QEMU를 제어할 수 있도록 합니다. 이 플러그인은 `Dockerfile`에서 `vagrant plugin install` 명령어로 설치됩니다. - **프로비저닝 (Provisioning)**: - `config.vm.provision "shell"` 블록은 VM이 처음 생성되고 부팅될 때 **자동으로 실행되는 스크립트**입니다. - 여기서는 PowerShell 스크립트를 인라인으로 전달하여, Windows VM 내부에 **Chocolatey 패키지 매니저**와 **Java 17**을 자동으로 설치합니다. 이를 통해 수동 개입 없이 필요한 소프트웨어가 설치된 환경을 구성할 수 있습니다. - **워크플로우 (`vagrant up`)**: - `startup.sh` 스크립트 내에서 `vagrant up` 명령어가 실행되면, Vagrant는 현재 디렉터리의 `Vagrantfile`을 읽어 다음 작업을 순차적으로 수행합니다. 1. `peru/windows-10-enterprise-x64-eval` Box가 로컬에 없으면 다운로드합니다. 2. `libvirt` 프로바이더를 통해 KVM 상에 새로운 VM을 생성합니다. 3. `Vagrantfile`에 정의된 메모리와 CPU를 할당합니다. 4. VM을 부팅합니다. 5. 부팅이 완료되면 프로비저닝 스크립트를 실행하여 소프트웨어를 설치합니다. ## 🌐 네트워크 구성 및 포트 포워딩 ### 1. 네트워크 주소 변환 (NAT) 구조 ```bash # 1차 NAT (호스트 레벨) 외부 IP:33890 → 컨테이너 IP:3389 외부 IP:8081 → 컨테이너 IP:8090 # 2차 NAT (컨테이너 레벨) 컨테이너 IP:3389 → VM IP:192.168.121.251:3389 컨테이너 IP:8090 → VM IP:192.168.121.251:8090 ``` ### 2. iptables 규칙 상세 분석 ```bash # 컨테이너 내부 NAT 규칙 (startup.sh) iptables -t nat -A PREROUTING -p tcp --dport 3389 -j DNAT --to-destination "$VM_IP":3389 iptables -t nat -A POSTROUTING -j MASQUERADE # FORWARD 체인 규칙 iptables -I FORWARD -d "$VM_IP" -p tcp --dport 3389 -j ACCEPT iptables -I FORWARD -s "$VM_IP" -j ACCEPT ``` ### 3. 네트워크 인터페이스 구성 ```bash # 호스트 네트워크 인터페이스 eth0: 192.168.1.10/24 (외부 네트워크) # 컨테이너 네트워크 인터페이스 docker0: 172.17.0.1/16 (Docker 브리지) eth0: 172.17.0.2/16 (컨테이너 내부) # VM 네트워크 인터페이스 virbr0: 192.168.121.1/24 (libvirt 브리지) vnet1: 192.168.121.251/24 (VM 내부) ``` ## 🔒 보안 설정 및 방화벽 구성 ### 1. 컨테이너 보안 설정 ```yaml # Docker 보안 옵션 security_opt: - "apparmor:unconfined" # AppArmor 프로파일 비활성화 cap_add: - NET_ADMIN # 네트워크 관리 권한 - SYS_ADMIN # 시스템 관리 권한 (필요시) ``` ### 2. 호스트 방화벽 구성 ```bash # 호스트 iptables 규칙 (문제 해결용) iptables -I DOCKER-USER -d 172.17.0.2 -p tcp --dport 3389 -j ACCEPT iptables -I DOCKER-USER -d 172.17.0.2 -p tcp --dport 8090 -j ACCEPT # 규칙 영구 저장 apt-get install iptables-persistent netfilter-persistent save ``` ### 3. 네트워크 격리 및 보안 ```bash # libvirt 네트워크 격리 virsh net-list --all virsh net-info default # VM 네트워크 설정 virsh domifaddr win10_default ``` ## 🛠️ 문제 해결 및 트러블슈팅 ### 1. 일반적인 문제 및 해결책 #### RDP 연결 실패 ```bash # 문제 진단 nmap -p 33890 192.168.1.10 telnet 192.168.1.10 33890 # 해결책: 호스트 방화벽 규칙 추가 iptables -I DOCKER-USER -d 172.17.0.2 -p tcp --dport 3389 -j ACCEPT ``` #### VM 부팅 실패 ```bash # libvirt 로그 확인 virsh list --all virsh domstate win10_default journalctl -u libvirtd # 해결책: KVM 모듈 로드 modprobe kvm modprobe kvm_intel # Intel CPU modprobe kvm_amd # AMD CPU ``` #### 네트워크 연결 문제 ```bash # VM IP 확인 virsh domifaddr win10_default # 네트워크 브리지 확인 brctl show ip addr show virbr0 # 해결책: 네트워크 재시작 virsh net-destroy default virsh net-start default ``` ### 2. 성능 문제 해결 ```bash # CPU 사용률 모니터링 top -p $(pgrep qemu) # 메모리 사용률 확인 free -h virsh dominfo win10_default # 디스크 I/O 모니터링 iostat -x 1 ``` ### 3. 로그 분석 ```bash # Docker 로그 docker logs win10-container # libvirt 로그 tail -f /var/log/libvirt/libvirtd.log # VM 콘솔 접속 virsh console win10_default ``` ## ⚡ 성능 최적화 ### 1. VM 성능 최적화 ```ruby # Vagrantfile 성능 설정 config.vm.provider "libvirt" do |libvirt| libvirt.memory = 8192 libvirt.cpus = 4 libvirt.cpu_mode = "host-passthrough" # CPU 패스스루 libvirt.disk_bus = "virtio" # VirtIO 디스크 libvirt.nic_model_type = "virtio" # VirtIO 네트워크 end ``` ### 2. 호스트 시스템 최적화 ```bash # CPU 성능 모드 설정 cpupower frequency-set -g performance # 메모리 스왑 비활성화 swapoff -a # I/O 스케줄러 최적화 echo 'ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/scheduler}="none"' > /etc/udev/rules.d/60-ioschedulers.rules ``` ### 3. 네트워크 성능 최적화 ```bash # 네트워크 버퍼 크기 증가 echo 'net.core.rmem_max = 16777216' >> /etc/sysctl.conf echo 'net.core.wmem_max = 16777216' >> /etc/sysctl.conf sysctl -p ``` ## 📊 모니터링 및 유지보수 ### 1. 시스템 모니터링 ```bash # 리소스 사용률 모니터링 스크립트 #!/bin/bash echo "=== System Resources ===" echo "CPU Usage: $(top -bn1 | grep "Cpu(s)" | awk '{print $2}')" echo "Memory Usage: $(free -h | grep Mem | awk '{print $3"/"$2}')" echo "Disk Usage: $(df -h / | tail -1 | awk '{print $5}')" echo "=== VM Status ===" virsh list --all virsh dominfo win10_default ``` ### 2. 백업 및 복구 ```bash # VM 스냅샷 생성 virsh snapshot-create-as win10_default backup-$(date +%Y%m%d) # VM 스냅샷 복원 virsh snapshot-revert win10_default backup-20231201 # 전체 VM 백업 virsh dumpxml win10_default > win10_backup.xml ``` ### 3. 정기 유지보수 ```bash # 주간 유지보수 스크립트 #!/bin/bash # 1. 시스템 업데이트 apt-get update && apt-get upgrade -y # 2. Docker 이미지 정리 docker system prune -f # 3. VM 상태 확인 virsh list --all # 4. 로그 파일 정리 find /var/log -name "*.log" -mtime +7 -delete ``` ## 📝 결론 이 Docker-KVM 기반 Windows VM 시스템은 **복잡한 가상화 계층**을 통해 격리된 Windows 환경을 제공합니다. ### 주요 성과 - ✅ **완전한 격리**: Docker 컨테이너 내부에서 Windows VM 실행 - ✅ **자동화된 배포**: Docker Compose를 통한 원클릭 배포 - ✅ **원격 접속**: RDP를 통한 외부 접속 지원 - ✅ **네트워크 격리**: 다단계 NAT를 통한 보안 강화 ### 기술적 도전과 해결 - 🔧 **복합 가상화**: Docker + KVM + Windows VM의 3단계 구조 - 🔧 **네트워크 복잡성**: 다단계 NAT 및 방화벽 규칙 관리 - 🔧 **성능 최적화**: 가상화 오버헤드 최소화 ### 향후 개선 방향 - 🚀 **GPU 패스스루**: CUDA/OpenCL 지원 - 🚀 **스냅샷 관리**: 자동화된 백업 및 복구 - 🚀 **모니터링 대시보드**: 실시간 리소스 모니터링 - 🚀 **멀티 VM 지원**: 여러 Windows VM 동시 실행 이 시스템은 **현대적인 가상화 기술의 집약체**로서, 개발 환경 격리부터 교육용 플랫폼까지 다양한 용도로 활용할 수 있는 강력한 솔루션입니다.