本篇文章谈谈怎样在Docker里运行Windows操作系统,WindowsinDockerContainer(WinD)。
写在上面
我日常使用macOS和Ubuntu来学习和工作,而且经常会有Windows使用的场景,不论是运行某个指定的软件,还是要做一些跨平台软件的功能验证。
在今年开源soulteary/docker-chatgpt[1]之前,还折腾过将Chrome容器化,提供有界面服务能力容器的事情,假如当时有这个方案,其实折腾过程能更简单一些。
环境打算
我们仍然是先从环境打算开始。想要使用这个方案linux vi,我们须要打算的东西有三个:安装了Docker的操作系统(我使用Ubuntu)、Windows操作系统的安装光碟(从WinXP~Win11都行)、开源项目dockur/windows[2]的Docker镜像。
安装Ubuntu操作系统和Docker
这套方案中采用了KVM加速,所以体验最好的方案是使用或则安装一个Linux环境,假如你本身就在使用Ubuntu之类的支持KVM十分便捷的操作系统的话,这么只须要安装Docker就好啦。
假如你确实须要在容器中运行Windows,想从零开始,可以参考之前的文章《在电脑上搭建高性价比的Linux学习环境:基础篇[3]》的方式来进行实践。安装Ubuntu的流程和往年并没有太大不同,仍然是老生常谈的三步曲:下载镜像、制作启动盘、安装系统。
假如你早已有了可以使用的Linux环境,可以参考前面文章中的“更简单的Docker安装”章节,完成基础环境的打算。
完成操作系统和Docker的打算后,我们还须要检测操作系统是否支持KVM,须要先安装cpu-checker。
sudo apt install cpu-checker -y
之后,执行kvm-ok,顺利的话,将还能见到类似下边的日志输出:
# sudo kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used
获取WIndows操作系统光碟
尽管开源项目dockur/windows[4]会依据用户指令,从、,以及谷歌官网手动下载合适的中文版系统镜像,但假如你想更快的完成系统的安装,或则想快速的启动多个WindowsDocker容器,这么自动下载Windows光碟还是十分有必要的。
开源项目包含了一些手动安装的预设配置docker windows容器,不过,这须要使用中文版的操作系统,你可以从这儿下载[5]。
其实,假如你须要使用英文版的操作系统,同样可以从官方下载[6],在初始化操作系统的时侯,相比日文操作系统你须要额外点一些“下一步”。
获取WindowsinDocker容器镜像
获取在Docker中运行Windows的容器镜像很简单:
docker pull dockurr/windows
其实,假若不能否直接下载linux是什么系统,也可以选择本地建立:
git clone https://github.com/dockur/windows.git
cd windows
docker build -t dockurr/windows .
这个镜像主要依赖了几项技术:
•qemus/qemu-docker[7],在容器中使用QEMU,还能提供接近本机速率的虚拟机的网路、IO速率等。•christgau/wsdd[8],让容器中的Windows才能出现在局域网中的其他设备的共享设备中。(Windows10的1511版本后,默认开始禁用SMBv1,NetBIOS设备发觉功能失效,造成其他设备不能对其进行服务发觉)。•qemus/virtiso[9],精简到27MB的KVM/QEMUVirtio驱动程序,才能让Windows在Docker环境中正常使用。•krallin/tini[10],正确启动Docker中QEMU,以及确保进程异常才能被正确处理,或正确的中止容器进程。
好了,打算工作就绪后,我们就可以开始使用这个有趣的技术方案啦。
基础使用
我们先谈谈最简单的使用方案,启动一个“无状态”的临时的Windows操作系统,容器会手动下载我们所须要的镜像:
version: "3"
services:
windows:
image: dockurr/windows
container_name: windows
devices:
- /dev/kvm
cap_add:
- NET_ADMIN
ports:
- 8006:8006
- 3389:3389/tcp
- 3389:3389/udp
stop_grace_period: 2m
restart: on-failure
将里面的配置保存为docker-compose.yml,之后使用dockercomposeup或dockercompose-d启动服务。
由于我们没有指定本地的镜像,所以假如你的网路环境访问谷歌CDN不够快的话,启动过程须要等待一些时间。
# docker compose up
[+] Running 2/1
✔ Network win_default Created 0.1s
✔ Container windows Created 0.1s
Attaching to windows
windows | ❯ Starting Windows for Docker v2.04...
windows | ❯ For support visit https://github.com/dockur/windows
windows |
windows |
windows | ❯ Downloading Windows 11...
windows | [i] Downloading Windows media from official Microsoft servers...
windows | [i] Downloading Windows 11...
windows | [+] Got latest ISO download link (valid for 24 hours): https://software.download.prss.microsoft.com/dbazure/Win11_23H2_English_x64v2.iso?t=c603adeb-c6d7-4bb9-b084-875f3beabfc2&P1=1710146067&P2=601&P3=2&P4=ynPQkgNxZoZxQkmfORJRE5yaf94m7ONuLVngMtHmDfsYTooFKSXiAdWXTKJ8dpoF2WuDkUZ4fkP1u%2bhwAh%2brAdghU%2f1ssngioKg2aLDe2UXOG3ESUAGTyRk1q515ONoXIvyJby2xPoKBVoj%2bsNp6ECqosBjx9HllmF3saRvQFPQox6v8kuhtMxyuNiXT%2fYgKppSZOifx34t6YQb0Hpo6gTkLjxlxiFBF42jLt%2blVhf1HW7ELEtvVUW7eAn9UGfs9HF6yC3p1ep7ouKYNrY0Ek0fo%2bn2v%2by3bTGbqg8lHfXjxb6bPHGE6HWP3sSZDZw4JmPt53hr1uQl%2fmjT50p504Q%3
windows | #=#=#
windows | #=#=#
0.0%
0.1%
0.2%
0.3%
...
####################################################################### 99.7%
####################################################################### 99.8%
####################################################################### 100.0%
######################################################################## 100.0%
windows |
windows | [+] Successfully downloaded Windows image!
windows |
windows | ❯ Extracting Windows 11 image...
windows | ❯ Adding XML file for automatic installation...
windows | ❯ Building Windows 11 image...
windows | ❯ Creating a 64G growable disk image in raw format...
windows | ❯ Booting Windows using QEMU emulator version 8.2.1 ...
windows |
...
当一切就绪后,我们可以使用两个方法来访问这个运行在Docker中的Windows。
第一种方式,是使用浏览器访问容器所在主机的IP地址:8006。
在容器中手动布署的Windows
容器启动后,会手动下载、部署Windows,稍等片刻docker windows容器,就能否在浏览器中正常使用它啦:
在浏览器中访问Windows
第二种方式,是使用支持RDP远程访问功能的软件,在软件服务器地址和端口内容中分别填写IP地址和3389,在用户名栏填写docker,密码保持空白即可。
在RDP顾客端中访问Windows加速使用Windows容器
默认情况,每次启动都须要看到它
其实,假如你的网路环境不是这么好,或则你不想每次启动容器都要等待许久,可以使用下边的技巧。
让布署使用加速,主要和两个细节有关:是否进行了容器内容的持久化,是否提供了高性能的安装镜像下载形式。
例如,我们在前面的打算工作中,我们预先下载好Windows的安装镜像,之后将文件重命名为win11x64.iso,接着将文件放置在目录的./iso子目录中。这么,利用Nginx,可以让整个安装布署过程变的飞快。
version: "3"
services:
windows:
image: dockurr/windows
container_name: windows
devices:
- /dev/kvm
cap_add:
- NET_ADMIN
ports:
- 8006:8006
- 3389:3389/tcp
- 3389:3389/udp
stop_grace_period: 2m
restart: on-failure
environment:
VERSION: "http://winiso/win11x64.iso"
MANUAL: "N"
volumes:
- ./win:/storage
depends_on:
- winiso
winiso:
image: nginx:alpine
container_name: winiso
restart: on-failure
volumes:
- ./iso:/usr/share/nginx/html
在前面的配置中,我们降低了一个拿来将本地的Windows安装文件转换为dockurr/windows快速可安装的在线地址的容器。
将配置文件保存为docker-compose.yml,之后使用dockercomposeup或则dockercomposeup-d启动配置,我们将见到类似下边的日志:
windows | .
windows | .
winiso | 172.20.2.3 - - [11/Mar/2024:03:54:47 +0000] "GET /win11x64.iso HTTP/1.1" 200 6813366272 "-" "Wget/1.21.4" "-"
windows | . 99% 1.59G 0s
windows |
windows | 6651904K .
windows |
windows | 100% 1.95G
windows | =3.7s
windows |
windows |
windows | ❯ Extracting downloaded ISO image...
windows | ❯ Detecting Windows version from ISO image...
windows | ❯ Detected: Windows 11
windows | ❯ Adding XML file for automatic installation...
windows | ❯ Building Windows 11 image...
windows | ❯ Creating a 64G growable disk image in raw format...
windows | ❯ Booting Windows using QEMU emulator version 8.2.1 ...
下载镜像的速率马上从几MB、几十MB降低到了接近每秒2GB,不到4s才能完成镜像的下载和处理。
由于在配置中降低了volumes卷的持久化(-./win:/storage),所以我们可以放心的停止或则重新启动容器,而毋须害怕每次都要重新初始化“一台”新的WindowsDocker容器。
使用方法
谈谈其他的使用方法。
更换Windows版本(不提早打算镜像)
假如你的网路环境极其棒,不须要提早下载安装镜像,或则直接使用云主机进行项目布署,这么可以考虑直接调整配置文件中的内容为合适的数值:
environment:
VERSION: "win11"
支持我们调整使用的值包含:win11、win10、ltsc10、win81、win7、vista、winxp、2022、2019、2016、2012、2008。
调整Windows容器资源配置
默认情况下,这个Windows容器会使用vCPUx2、4GB显存、64G的c盘空间,来满足Win11的最低安装需求。我们可以按照自己的实际需求,来动态的调整容器的硬件资源限制。
environment:
RAM_SIZE: "8G"
CPU_CORES: "4"
DISK_SIZE: "256G"
例如,在前面的配置中,我们调整CPU核心数到4,显存到8GB,c盘到256GB。
为容器分配独立的IP地址
默认情况下,Docker会共享宿主机的IP,假如我们想要让容器拥有独立的IP地址,须要先创建一个macvlan网路:
docker network create -d macvlan
--subnet=192.168.0.0/24
--gateway=192.168.0.1
--ip-range=192.168.0.100/28
-o parent=eth0 vlan
创建完网卡后,调整里面使用的容器配置,按照自己的需求指定容器IP即可:
services:
windows:
container_name: windows
..<snip>..
networks:
vlan:
ipv4_address: 192.168.0.100
networks:
vlan:
external: true
使用一整块c盘
假如你的主机上有多块c盘,或则想将某一块c盘完整的分配给Windows,可以采用下边的方式,其中DEVICE将作为你的主c盘:
environment:
DEVICE: "/dev/sda"
DEVICE2: "/dev/sdb"
devices:
- /dev/sda
- /dev/sdb
在Docker中的Windows使用USB设备
我们首先须要使用lsusb来获取USB设备的VendorID和ProductID,之后将这种信息添加到配置中:
environment:
ARGUMENTS: "-device usb-host,vendorid=0x1234,productid=0x1234"
devices:
- /dev/bus/usb
最后