讲了不少虚拟机,container,模拟器等,大部分都是运行在Linux上。我想微软认识到了Linux支持的重要性,特别是在开发应用中,比如Android开发,Linux的开发者用户群很大,所以一年多前微软就通过Windows 10的Insider/Creators program (WSL, Windows Subsystem for Linux )引人Ubuntu的支持,可以在Windows console下运行Ubuntu命令:如 bash, ssh, git, apt等等。现在这一feature已经正式出现在Windows App Store: https://www.microsoft.com/en-us/p/ubuntu/9nblggh4msv6,甚至可以在旧版Windows 10 (如1709)上运行。从微软网站摘录的:
Note that Windows 10 S does not support running this app.
Before installing Ubuntu on Windows or before the first run please open
the Control Panel, visit Programs and Features' submenu Turn Windows
features on or off and select Windows Subsystem for Linux. Click OK,
reboot, and then your system is ready to run this app.
Instead of the above steps You can set up your system by executing the
following command in the Administrator PowerShell prompt:
Enable-WindowsOptionalFeature -Online -FeatureName
Microsoft-Windows-Subsystem-Linux
When your system is ready simply start "ubuntu" in cmd.exe or launch
Ubuntu from the start menu.
Monday, February 11, 2019
Running Linux on Windows
Linux上的VM
Linux有很好的VM support,如Kernel Virtual Machine (KVM), 由kernel module提供支持。QEMU (https://www.qemu.org, 一个开源的machine emulator and virtualizer)包含KVM的userspace component。如果你做过Android开发,用过Android的虚拟机AVD,那就是用QEMU实现的。KVM和QEMU是基于Linux内核的,所有有很小的footprint,效率却很高。When used as a virtualizer, QEMU achieves near native performance by executing the guest code directly on the host CPU. QEMU supports virtualization when executing under the Xen hypervisor or using the KVM kernel module in Linux. When using KVM, QEMU can virtualize x86, server and embedded PowerPC, 64-bit POWER, S390, 32-bit and 64-bit ARM, and MIPS guests.
KVM vs VirtualBox
Running Windows program on Linux and MacOS: Wine
因为很多原因我工作之外更喜欢使用Linux/Ubuntu操作系统。我在家的常用计算机是双操作系统,Windows10 + Ubuntu。Boot来boot去的到也很快,但还是不很痛快。比如,Linux可以access Windows的硬盘分区,可是Windows不支持Linux的ext4分区。又如Google Drive App只有Windows和Mac版,没有Linux版(很奇怪)。有时我会玩老游戏如微软的帝国时代和红警,感谢开源Wine (Wine Is Not Emulator) enables Linux, Mac, FreeBSD, and Solaris users to run Windows applications without a copy of Microsoft Windows. Wine is free software under constant development. Other platforms may benefit as well.
https://wiki.winehq.org/Ubuntu 提供了源程序和binary,很容易安装。wine FAQ 提及At present there are some significant bugs that prevent many 32 bit applications from working in a 64 bit wineprefix。很多Windows程序都是32位的,所以需要32位Linux support:

安装完后,在home folder的.wine目录下,可以找到drive_c,就是mapped的C drive。运行的程序并不必须copy到这个目录下。在这个.wine目录下运行winecfg会自动安装.net等package。之后可以运行wine notepad来确认wine设置成功。
因为我的游戏是中文汉化版,为了中文支持,首先需要在Host OS上加中午支持。Allow the window manager to control the windows
Emulate a virtual desktop 和 Desktop size
当这两项都没有选取时,游戏显示是正常的,在游戏中改变分辨率,游戏的显示还是正常,但是游戏的快捷键可能不起作用。如果只选第3项,键盘工作正常,但切换游戏分辨率后,一部分屏幕可能不能正常刷新。我相信应该有办法tweak wine解决这个问题,不过最简单的办法就是把3和4都选上,显示是virtual的,而不是全屏的,看起来画面更细致。
On MacOS, refer to https://wiki.winehq.org/MacOS
如上述链接所说的,需要先确保Xquartz已安装。Xquartz也是一个开源软件: https://www.xquartz.org/, an open-source effort to develop a version of the X.Org X Window System that runs on OS X. 在MacOS上32bit wine是基本安装, 64bit 是可选项。设置运行和Linux /Ubuntu基本一样。
总的来说,WINE的solution与VM和container完全不同。 VM是在指令一层simulate,container则必须运行在同种OS,而WINE是把Windows API calls 转换成POSIX API calls on-the-fly,各有千秋。
Update in 2020: 参见winetricks: A useful tool for using common workarounds to current deficiencies in Wine,很方便用来安装runtime support。
Wednesday, February 6, 2019
学习舵轮(kubernetes)和埠(docker) - 创建NodeJS+MongoDB docker image
讲了很多概念,下面是一些docker的源代码,用来创建前面讲的NodeJS+MongoDB的应用。DockerHub提供很多常用的container image,包括NodeJS image。如下的Dockerfile就会载入最新的NodeJS container,并运行npm(Node Package Manager)根据用户提供的package.json文件来安装需要的Node package。
FROM node:latest
docker-compose -f my-compose.yml up
就会创建和运行一个提供NodeJS+MongoDB的container。打开localhost:8080就可以测试。
这是基于alpine image,安装NodeJS,并运行app.js script。app.js的内容如下:
docker image build -t my_project:v0.1 .
运行结果是web server 不work,查看log就会发现,虽然NodeJS和MongoDB都安装了,但Node的Mongo package没有安装,JS code 就没办法talk to MongoDB。所以需要更新Dockerfile的‘RUN’这一行:
重新build会看到message:
Step 5/7 : RUN npm install mongodb
Refer this for starting mongod: mongod --port 27017 --dbpath /app/ --fork --logpath /var/log/mongodb.log
to specify which IP addresses it should serve responses from, or with --bind_ip_all to bind to all interfaces. If this behavior is desired, start the server with --bind_ip 127.0.0.1 to disable this warning.
不要在Dockerfile里加上RUN上面的启动mongod daemon 的 command line, 那样做会造成生成的significantly size increase of docker container image, from 207M to 508M. It’s a little complex to get the service setup properly (rc-update add mongodb default, may need to setup environment for mongo), 所以我把 mongod cmdline and nodejs cmdline 放在一个 shell script, 然后把run这个shell script 的 CMD line 加到 dockerfile。这样创建的docker image只有208M左右。
常用的MongoDB命令:
把database 数据文件存到另外mount的volume上: use a separate volume for db, run: docker volume create mongo_db, update Dockerfile with VOLUME /data and set --dbpath /data/ in mongod cmdline. Then start container like this: docker container run -d -p8080:3000 --mount type=volume,source=mongo_db,destination=/data my_project:v0.2

