本文讲的是Windows的Docker Beta版本, 【编者的话】本文为Docker Saigon社区于其官方网站中发布的文章Docker For Windows Beta,此文描述了在Windows上的Docker Beta版本的一些功能,并且做了演示。Docker Saigon社区是由越南的Docker社区用户创建的,位于胡志明市。 注释:这篇文章的研究已在Beta客户端完成了,并且技术细节有可能发生变化。 正如之前发布的帖子描述的那样,我们已经在Windows的Hyper-V上使用Docker有一阵子了。听说了新的Windows的Docker客户端是基于Alpine的,并且会专注于Hyper-V,这使得我们很渴望亲眼看一看。 Hyper-V 配置
第一个要克服的问题是当在Windows上使用Hyper-V时缺乏DNS/DHCP和NAT服务。新的Docker客户端为我们接管虚拟交换机的NAT配置并且为DNS与DHCP添加了一个很巧妙的解决方案。 作为安装过程的一部分,将创建一个内部DockerNAT虚拟交换机,并且该Windows主机上的虚拟接口将会为这个虚拟交换机获得一个静态IP: New-VMSwitch -Name "DockerNAT" -SwitchType InternalGet-NetAdapter "vEthernet (DockerNAT)" | New-NetIPAddress -AddressFamily IPv4 ` -IPAddress "10.0.75.1" -PrefixLength 24
同时,也创建了一个为“10.0.75.0/24”子网提供网络地址转换(Network Address Translation)的NAT对象。 New-NetNat –Name $SwitchName `–InternalIPInterfaceAddressPrefix "10.0.75.0/24"
提示: 如果有任何的步骤失败了,须确保名为“DockerNAT”的交换机是被创建的,并且IP已经被分配给了该虚拟接口(Virtual Interface)的。此外通过Get-NetNat命令所显示的NAT是属于正确的子网内的。同时要确保物理网络与现有存在的接口不重叠(我们已经在测试beta版本的时候手动地将这些问题修复了)。 接下来, MobyLinuxVM 虚拟机已经在Hyper-V里建立起来了。MobyLinuxVM使用Alpine bootcd集成的Hyper-V服务,例如 Key-Value Pair Exchange 服务(hv_kvp_daemon)。Hyper-V KVP的守护进程允许Hyper-V和Linux客户机之间通信(例如检索客户IP和发送双向的消息,这我们将在后面看到)。 最终,Docker捆绑了 com.docker.proxy.exe 源代码,它代理了在Windos主机上的MobyLinuxVM端口。在写该文的时候(Docker Beta 7),它已经包含了DNS(TCP/UDP 53),DHCP(UDP 67)和Docker 守护进程(TCP2375)。 如果你一直在为你的Hyper-V配置运行一个替代解决方案,那么需要确保以上所有端口是可用的,如下所示。 查看是否有任何进程在占用53端口: netstat -aon | findstr :53
一旦你发现任何进程号再占用该端口(<pid>),那么先获取进程名: tasklist /SVC | findstr
com.docker.proxy.exe 将会把你笔记本内部网络所有的DNS请求通过Windows主机代理到DNS服务器上,当你移动你的笔记本的时候可以有效地从网络配置上隔离MobyLinuxVM。 为了确保该进程工作正常,docker自动地创建了DockerTcp和DockerUdp防火墙规则,并且可以在我们关闭客户端的时候移除它。 New-NetFirewallRule -Name "DockerTcp" -DisplayName "DockerTcp" `-Program "C:\ \ \com.docker.proxy.exe" -Protocol TCP `-Profile Any -EdgeTraversalPolicy DeferToUser -Enabled TrueNew-NetFirewallRule -Name "DockerUdp" -DisplayName "DockerUdp" `-Program "C:\ \ \com.docker.proxy.exe" -Protocol UDP `-Profile Any -EdgeTraversalPolicy DeferToUser -Enabled True
Docker的守护进程在本地打开,允许你的docker客户端与本地主机通信,可是-它看起来在使用一个命名管道的方案去替代它, 如果该VM被正确地创建, 那么你应该看到连接到其COM口的命名管道。 那么同样也可以看到docker客户端代码在处理 。 Get-VMComPort -VMName MobyLinuxVM | fl | Out-String
如果MobyLiunxVM正常地启动,我们就应该可以确认Hyper-V集成服务是在运行着的。 Get-VMIntegrationService -VMName MobyLinuxVM -Name "Key-Value Pair Exchange"
并且com.docker.proxy.exe的DHCP服务提供了一个到VM的IP,通过该IP我们可以查询Hyper-V集成服务: $(Get-VM MobyLinuxVM).NetworkAdapters[0]
排错
所有的配置都放在%APPDATA%\Docker\文件夹下面,当漫游设置开启的时候,这个文件夹被复制在该主机的企业设置中。 所有日志存放在%LOCALAPPDATA%\Docker\文件夹下面。 可以通过如下PowerShell脚本去监控最新的日志: gc $(gi $env:LocalAppData\Docker\* | sort LastAccessTime -Desc | select -First -1) -Wait
一旦有事件写入日志文件将会被自动刷新。 Docker ToolBox 迁移
在Windows上切换至Hyper-V角色的话将会关闭VirtualBox(其实直到你关闭Hypver-V并重启之前都不可能用Docker ToolBox)。 如果检测到Docker Toolbox已经安装了,那么会提供一个整合路径(基于 qemu-img 方式的)。这将会把 %USERPROFILE%.docker\machine\machines\<machine-name>\disk.vmdk 路径下的磁盘转换成vhdx格式: qemu-img.exe convert -O vhdx -o subformat=dynamic -p "C:\Users\Public\Documents\Hyper-V\Virtual hard disks\MobyLinuxVM.vhdx\"
如果你已经通过Hyper-V使用Docker-Machine和Docker-Compose了,你也可以同时用Docker的Windows客户端这么做一遍。 挂载卷
基于Windows下的Docker的其中一个较大的改进是承诺的卷如何挂载的问题。 一个便利的对话框模式提供了我们所需要的一切。 目前的改进将是共享整个存储(不包括单独的文件夹)。开启共享的时候需要提供凭据。 凭据信息伴随着“Docker Host Filesystem Access” 目标 被存储在了Windows > Control Panel > Credential Manager > Windows Credentials Store路径下,这是通过 System.Security.Cryptography 随着当前用户进行加密的。 如果凭据管理器已经包含了指定的目标凭据,他们将被覆盖。 接下来,可以看到存储器被共享在了Windows主机上: net share C=C:\ /grant: ,FULL /CACHE:None
Samba的共享方式现在将会被挂载到MobyLinuxVM上,并且会通过Hyper-V的 进行自动操作。这里是细节方面的 。 工作方式应该像下面描述的那样:Windows主机将一个 mount authentication token 令牌打包放进了VMBus中的 KvpExchangeDataItem 类里: class Msvm_KvpExchangeDataItem : CIM_ManagedElement{uint16 Source = 0;string Name = "cifsmount";string Data = "authToken";};
认证令牌是包含挂载点和安装选项的序列化的字符串: /c;/C;username= ,password= ,noperm
在Alpine上,是 hv_utils 核心驱动模块通知 hv_kvp_daemon 。这个守护进程把kvp写进了池文件里(/var/lib/hyperv/.kv_pool_**)。 此时,MobyLinuxVM需要构建一个目录,并且从主机上挂载该共享目录-但是这一次写入的时候是失败了的: #for both upper and lower casemount -t cifs //10.0.75.1/C /C -o username= ,password= ,noperm
如果共享是工作正常的,那么我们的docker客户端将会经由 com.docker.proxy.exe 通过开启的端口发送任何卷的挂载信息,该代理会在需要的时候重写该路径:例如C:\Users\test\变成/C/Users/test,这可以让我们把Windows的目录挂载到我们的Docker容器中。 然而,由于SMB协议的原因(缺少inotify和symlinks的支持)使得我们这么做这仍然会有限制,这将会导致实时重置。 排错:我们可以通过以下的PowerShell脚本来验证令牌是否存在: $VmMgmt = Get-WmiObject -Namespace root\virtualization\v2 -Class ` Msvm_VirtualSystemManagementService$vm = Get-WmiObject -Namespace root\virtualization\v2 -Class ` Msvm_ComputerSystem -Filter {ElementName='MobyLinuxVM'}($vm.GetRelated("Msvm_KvpExchangeComponent")[0] ` ).GetRelated("Msvm_KvpExchangeComponentSettingData").HostExchangeItems | % { ` $GuestExchangeItemXml = ([XML]$_).SelectSingleNode(` "/INSTANCE/PROPERTY[@NAME='Name']/VALUE[child::text() = 'cifsmount']") if ($GuestExchangeItemXml -ne $null) { $GuestExchangeItemXml.SelectSingleNode(` "/INSTANCE/PROPERTY[@NAME='Data']/VALUE/child::text()").Value } }
目前为止,我还没有弄清楚在Alpine主机上是由哪个进程去监控 var/lib/hyperv/.kv_pool_0 这个文件的。 私有仓库
现在的Windows Beta版本目前还不支持 DOCKER_OPTS 和TLS证书。 像下面一样,我们可以获得到MobyLinuxVM的根账号访问权限: #get a privileged container with access to Docker daemondocker run --privileged -it --rm -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker alpine sh#run a container with full root access to MobyLinuxVM and no seccomp profile (so you can mount stuff)docker run --net=host --ipc=host --uts=host --pid=host -it --security-opt=seccomp=unconfined --privileged--rm -v /:/host alpine /bin/sh#switch to host FSchroot /host
闲逛该VM的时候发现了下面的一些东西: 这个基于Alpine的VM使用OpenRC作为它的 。 rc-status
显示所有的服务状态的时候,我们会发现一些定义的脚本并没有部署状态,并且显示是“崩溃的”,尽管这些进程看起来其实是运行的(ps -a)。 Docker初始化脚本依赖于 /usr/bin/mobyconfig 脚本。该脚本要求内核伴随着 com.docker.database 标签定义的文件配置的位置启动。如果该标签存在- /Database 使用 Docker for Mac的原始文件系统 挂载。 该 mobyconfig 可以检索网络并且为Docker守护进程取消加密,或者从 /etc/docker/daemon.json 中获取配置文件。一旦全面实施,将会是一个很有前景的解决方案。 由于整个磁盘是一个只有 /var/ 固定挂载点的临时文件的系统是固定存在的(挂载到 /dev/sda2 ),更改的任何脚本在重新引导时不会持续运行。这将可以临时改变Docker选项并且通过 /etc/init.d/docker restart 命令重启守护进程。 总结
许多的改进将会随着基于Windows的Docker客户端而来,我们期待下次在MAC上的Docker客户端的测试。 原文链接: (翻译:薛开成) =========================================== 译者介绍 薛开成 ,趋势科技南京研发中心工程工具服务事业部基础架构高级工程师,负责容器仓库实施及落地。 本文来自云栖社区合作伙伴DockerOne,了解相关信息可以关注DockerOne。
原文标题:Windows的Docker Beta版本