速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

细说 Windows 与 Docker 之间的趣事

  • 2016-08-29
  • 本文字数:2892 字

    阅读完需:约 9 分钟

众所周知,Docker 能打通开发和运维的任督二脉,所谓 DevOps 是也。有朋友说,这符合王阳明的"知行合一"之教。

而 Windows Server 2016 内置的 Windows Docker 亦已经出来一段时间,这里就来和诸公汇报一下测试结果。

Linux 和 Windows,Docker 里各有多少进程

在安装配置 Container Host 的时候,经常报错 Container OS Image 下载失败 (没办法,墙内的缘故)。

什么是 Container OS?顾名思义,是从容器角度看到的 OS。

Container OS 实际是应用所依赖的用户模式 (User mode)OS 组件,对于 Windows 容器来说,例如 ntdll.dll、kernel32.dll 或者 coresystem.dll 之类的 System DLL。主机上的所有容器共享内核模式 (Kernel mode)OS 组件,对于 Windows,就是 ntoskrnl.exe,还有驱动等。

例如对于以下命令,意味着 Windows 系统从 docker 映像中获取 Windows Server Core 的用户模式 OS 组件,并启动 cmd 获得 Shell。

复制代码
docker run -it windowsservercore cmd

Linux 也是一理,如果运行以下命令,意味着从 docker 映像中获取 Ubuntu 的用户模式组件,并且启动 Bash Shell。

复制代码
docker run -it ubuntu /bin/bash

对于以上两个容器,Linux 容器里的进程比较少,可以参考以下截图:

而 Windows 容器,则情况略有不同。

在 Windows 主机上启动 Process Explorer,可以看到这个 Windows 容器的进程相对多一些:

这是因为在 Windows 系统中,需要给应用提供一些用户模式的系统服务,例如 DNS、DHCP、RPC 等服务,这样从容器的角度来看,容器获得了自己独有的服务 (一般是在各自的 svchost 或者其他服务宿主进程里运行),构成了所谓的 Container OS。

我们可以用 PowerShell 命令查看容器内部启动的 Windows 服务,大概有 27 个,参考附图。

很可惜,这个版本的 Windows docker 里,虽然有远程桌面服务,但是目前还不支持远程桌面到容器,所以无法使用容器应用的图形化界面。

容器里的应用,到底应该启动多少 Windows 服务?由于 Windows 服务的具体作用是非文档化的,所以不像 Linux 可以做到最精简。但是由于这些服务几乎不占用什么额外的资源,对于容器性能没有影响。

Windows 容器的进程如何隔离

由于在最新的测试版本里,容器对象的权限设置有了改变,只有 SYSTEM 权限才能查看。所以要查看 Windows 容器的进程隔离,需要用 SYSTEM 权限启动 Winobj。这可以借助 Psexec 来实现:

复制代码
Psexec -i -d -s winobj.exe

可以看到 Windows 对象空间里多了一个 Containers 的节点,其下有若干个 GUID 分支,这些 GUID 代表系统里的容器。其下每个容器有自己独立的 BaseNamedObjects 等命名空间,包括互斥信号量、内存 Section、事件等。

可以用 PowerShell 查看容器的 GUID,参考附图。

每个容器节点下,有自己的 Session 分支,例如该容器,占据了 Windows 系统的 Session 2。如附图所示。

这就是为什么,不管用任务管理器,还是 PowerShell,抑或是 Process Explorer 等工具,我们都在 Windows 主机里看到容器里的所有进程都会标记 Session 为 2。

借助 Process Explorer,我们可以看到容器里的进程,所打开的 Handle,其中就指向先前所看到的 Windows 容器对象命名空间。

同时还能看到,容器进程所在的 WindowStation 并不是 WinSta0,而是 Service-0x0-3e7$,3e7 的 10 进制等于 999,等于九五之尊,这是 SYSTEM 服务所在的窗口站。所以容器进程无法在 Windows 桌面上拥有图形化界面。

还可以查看一个有意义的对象,Windows 容器所挂载的主机目录,类似于 Linux 容器的 Volume。

Windows 容器的文件系统如何隔离

和 Linux 一样,Windows 容器映像采用分层的文件系统,基于映像创建容器后,相当于在只读的分层文件系统上再覆盖一层可读写的文件系统层。如果要修改的文件在最上层的可读写层里没有,则沿着分层的 Layer 找到目标文件后,将其用 COW(Copy on write:写时复制) 复制到可读写层再修改。

让我们进入到 Windows 主机的以下目录:

复制代码
C:\ProgramData\Microsoft\Windows\Hyper-V\Containers

该目录下列出所有通过 PowerShell 命令创建的容器文件。其下有文件夹和文件,都以容器的 GUID 来命名。

其中的 926A300B-ACB7-4B28-9D86-45BF82C1211C.vhdx 就是该容器的最上层的可读写层,是一个 VHDX 文件。

记住该可读写层并不是一个完整的文件系统,它需要和 Image 的现有文件系统组成 Union File System。如果尝试双击该 VHDX(只能尝试挂载停止状态的容器 VHDX),试图挂载到 Windows 系统,会弹出以下报错信息,提示该虚拟硬盘无法挂载。

Image 的文件系统位于以下路径 (Windows Server Core 的 Container OS 文件):

复制代码
C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10586.0\Files

如果用 Process Explorer 查看容器进程访问的 Dll,可以看到其访问的路径为 Container OS 文件。

如果是用 docker 命令创建的进程,道理类似,但是其可读写层文件系统位于以下路径:

复制代码
C:\ProgramData\docker\windowsfilter

Windows 容器还有注册表

和 Linux 不一样,Windows 容器还需要考虑注册表的隔离问题。和文件系统命名空间隔离一样,注册表命名空间隔离也采用类似 Union FS 形式。

下面让我们进入 PowerShell 命令创建的 Windows 容器文件夹内部。

复制代码
C:\ProgramData\Microsoft\Windows\Hyper-V\Containers\926A300B-ACB7-4B28-9D86-45BF82C1211C\Hives

在这个 Hives 文件夹下方,有很多命名为 *_Delta 的文件,这是容器所访问的注册表配置单元文件。

从命名方式中可以看到,容器的注册表和文件系统一样,也采用分层架构,最上层的是可读写的注册表命名空间。而 Image 映像也有只读部分的注册表空间,路径如下。

复制代码
C:\ProgramData\Microsoft\Windows\Images\CN=Microsoft_WindowsServerCore_10.0.10586.0\Hives

在 Process Explorer 里可以看到可读写层、只读层注册表合并后所加载的内容。

Docker 命令所创建的容器,方法类似,位于类似以下路径:

Windows 容器的资源限制

大家知道,Docker 可以调用 CGroup 技术来限制 Linux 容器的 CPU、内存等资源占用。而在 Windows 容器里,内存资源的限制,则是通过 Windows 的 JO(作业对象) 技术来实现。

可以参考以下技术来限定 Windows 容器的 CPU、内存和磁盘 IO。例如可以将容器的内存限定为最大占用为 5GB。

复制代码
https://msdn.microsoft.com/en-us/virtualization/windowscontainers/management/manage_resources?f=255&MSPPError=-2147217396

然后用 Process Explorer 打开任意一个容器进程的属性对话框,切换到 Job 标签页。

可以看到所有容器进程共享一个作业对象,而且该作业对象的内存限额 (Job Memory Limit) 为 5GB。

作者简介

彭爱华 网名盆盆,微软混合云技术顾问。11 届微软最有价值专家 (MVP),微软高级认证讲师。出版过近 20 本技术图书,2005 年创建 ITECN 博客 (09 年全国 IT 博客五十强)。微信公众号 (华来四笑侃 Windows):sysinternal。曾获得微软技术大会 TechEd 最佳讲师、中国首届 IT 管理技术大会 (2009) 最佳讲师的光荣称号。


感谢陈兴璐对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2016-08-29 18:096914

评论

发布
暂无评论
发现更多内容

阴阳怪气的「道歉」背后,是新闻从业者的一次呐喊

TechubNews

需求不明确、没有列基准计划的项目,如何管理项目过程及进度

爱吃小舅的鱼

项目过程

刚入行Java,如何快速成长?

了不起的程序猿

Java 程序员 架构师 java面试 Java进阶

IOC控制反转 DI依赖注入

EchoZhou

nestjs

程序员的副业成功之路:从固定工资到月入26K

陆通

mac免费的ntfs读写工具 NTFSTool 中文版

理理

Agisoft Metashape Professional (3D建模软件)中文破解版-mac/win

理理

非技术人员怎样去协调开发项目进度

爱吃小舅的鱼

项目进度

通义开源语音处理框架 ClearerVoice-Studio;亚马逊 Nova 计划明年发布端到端语音模型丨 RTE 开发者日报

声网

身为一名Java程序员,我们该怎么样去看源码?

开心学Java

Java jdk源码 架构师 java面试 八股文

count(*)、count(1)哪个更快?面试必问:通宵整理的十道经典MySQL必问面试题

EquatorCoco

sql 面试

AI领航 共启出海|易点天下中国创新科技企业出海高峰论坛圆满举办

新消费日报

Observability:使用OpenTelemetry手动检测Go应用程序

百度搜索:蓝易云

基于开源云原生数据仓库 ByConity的23次测试

悟空聊架构

OLAP ETL 悟空聊架构 ByConity

VJ音视频软件 resolume arena 7中文版附安装教程

理理

爱维德AVID Sibelius Ultimate 贝柳斯音乐记谱软件中文激活版

理理

2024年好用的AI工具盘点!办公效率快到飞起!

职场工具箱

人工智能 职场 办公软件 AIGC AI生成PPT

鸿蒙NEXT开发中如何确保使用 PersistentStorage 存储的数据安全?

威哥爱编程

HarmonyOS HarmonyOS NEXT

Mac用户必看!PullTube:一键下载YouTube视频的神器来啦!

理理

API网关的智能化转型:2024年的关键趋势

幂简集成

API api 网关

SpringCache Redis配置与缓存使用-配置过期时间

百度搜索:蓝易云

如果模块请求http改为了https,测试方案应该如何制定和修改?

百度搜索:蓝易云

openstack的port重建流程【neutron port-show中的ip信息】

百度搜索:蓝易云

Joyoshare iPasscode Unlocker:一键破解,重获iPhone自由!

理理

macOS Catalina Patcher(旧mac安装最新Catalina系统工具)

理理

Ae2024中文破解教程 及After Effects 2024安装包

理理

AVTouchBar for mac(触摸栏的音频可视化器)v3.0.7激活版

理理

KubeEdge、ThingsBoard 和 CnosDB:智能物联网平台的完美组合

CnosDB

时序数据库 tsdb 开源社区 大数据 开源 CnosDB

mysql导出表结构到excel

百度搜索:蓝易云

科技掌握一切,智慧引领发展:财务规划技术与思维的碰撞

智达方通

企业管理 财务分析 科技创新 财务规划 预算分析

免费甘特图软件推荐有哪些?这8款工具不可错过

爱吃小舅的鱼

甘特图软件

细说Windows与Docker之间的趣事_Windows_彭爱华_InfoQ精选文章