前置阅读:建议先阅读 Docker 详解:容器化技术的核心概念与实战入门 与 Docker 存储驱动与 OverlayFS 深度解析。
关键概念:Linux 容器与宿主机共享 Linux 内核;而 Windows 容器由于 Windows 内核机制不同,存在两种隔离——进程隔离(共享 Windows 内核,速度快)与 Hyper-V 隔离(每个容器一个轻量虚拟机,独立内核,更强隔离)。理解这两条隔离路线,加上基础镜像选型(Nano Server/Server Core),是 Windows 容器落地的前提。
1. Windows 容器基础
1.1 与 Linux 容器的根本差异
Linux 容器:所有容器共享宿主 Linux 内核
- 镜像层 = 文件系统差异(OverlayFS CoW)
- 隔离 = namespaces + cgroups
Windows 容器:容器与宿主共享 Windows 内核(进程隔离)
- 镜像基于 Windows OS 组件(System + 服务层)
- 隔离 = Job Objects + 命名空间(Windows 的进程与内核隔离)
- 或 Hyper-V 隔离:每个容器跑在独立轻量 VM 上(独立内核)
| 维度 | Linux 容器 | Windows 容器(进程隔离) | Windows 容器(Hyper-V 隔离) |
|---|---|---|---|
| 内核 | 共享宿主 Linux 内核 | 共享宿主 Windows 内核 | 每个容器独立 Windows 内核 |
| 隔离强度 | 中(namespaces) | 中 | 高(轻量 VM) |
| 启动速度 | 毫秒级 | 秒级 | 秒级(需引导内核,略慢) |
| 镜像兼容 | 宿主内核版本可低于镜像 | 镜像版本须 ≤ 宿主版本 | 镜像版本须 ≤ 宿主版本 |
| 适用 | 大多数服务 | 内网可信服务 | 多租户/高安全场景 |
1.2 重要限制:镜像与宿主版本匹配
Windows 容器镜像只能在版本号等于或低于宿主 OS 的 Windows 上运行(NT versioning 约束):
宿主 Windows Server 2022(10.0.20348):
- 可运行 2022、2019、2016(LTSB)的容器镜像
- 不能运行 2025 的镜像(版本更高,拒绝加载)
宿主 Windows Server 2025(10.0.26100):
- 可运行 2025 及以下所有历史镜像
# 查看宿主 OS 版本(决定可用的基础镜像版本)
[System.Environment]::OSVersion.Version
# Docker 检测 Windows 容器模式
docker info --format "{{.OSType}} {{.OperatingSystem}}"
2. 进程隔离与 Hyper-V 隔离
2.1 如何选择隔离模式
--isolation 参数控制两种模式:
# 进程隔离(默认,需 Windows 容器模式)
docker run --isolation=process -d mcr.microsoft.com/windows/servercore:ltsc2022
# Hyper-V 隔离(每个容器一个轻量 VM)
docker run --isolation=hyperv -d mcr.microsoft.com/windows/servercore:ltsc2022
# 查看当前模式
docker info --format "{{.Isolation}}"
| 场景 | 推荐隔离 | 理由 |
|---|---|---|
| 内部工具/开发测试 | process | 快、省资源 |
| 多租户 / 边界不清 | hyperv | 独立内核,逃逸面小 |
| 运行不兼容内核组件 | hyperv | 可运行需内核补丁的旧镜像 |
| 合规/审计要求 | hyperv | 更强的租户隔离证据 |
2.2 Hyper-V 隔离的启动细节
Hyper-V 隔离 = 每个容器配一个精简 VM
- 有独立 Windows 内核(从镜像中引导)
- 有独立的内存分配(VM 内存,非共享)
- 启动时间与 VM 引导相关,通常 2-10 秒
对比进程隔离:
进程隔离共享宿主内核,快但隔离薄
"Windows 容器和 Linux 容器一样都跑在轻量 VM" 是常见误读:
只有 Hyper-V 隔离才如此,进程隔离不是
一句话:把 Hyper-V 隔离当成"每个容器一台微型 Windows 虚拟机",把进程隔离当成"Windows 版的 namespace + cgroup"——两条路线按安全与性能权衡选。
3. 基础镜像选型:Nano Server 与 Server Core
3.1 两类官方基础镜像
| 镜像 | 大小 | 包含 | 适用 |
|---|---|---|---|
| Nano Server | 约 100-180MB | 最小 .NET Core/现代 API 运行环境 | 云原生、新应用(首选) |
| Server Core | 约 2-8GB | 较完整 Windows Server 用户态 | 传统 .NET Framework 应用 |
| Windows | 约 8-15GB+ | 完整 GUI 桌面/完整服务器 | 几乎不用于容器 |
# Nano Server + .NET 8(推荐新应用)
FROM mcr.microsoft.com/dotnet/aspnet:8.0-nanoserver-ltsc2022
WORKDIR /app
COPY --from=build /app/out .
ENTRYPOINT ["dotnet", "MyApp.dll"]
# Server Core + 传统 .NET Framework(旧应用迁移)
FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2022
WORKDIR /inetpub/wwwroot
COPY --from=build /app/_PublishedWebsites/MyApp ./MyApp
3.2 选型决策表
| 你的应用 | 建议基础镜像 | 理由 |
|---|---|---|
| .NET Core/ASP.NET Core/现代栈 | Nano Server + dotnet/aspnet | 最小、启动快 |
| .NET Framework 4.x / WCF / 传统 IIS | Server Core + framework/aspnet | 需要完整 .NET Framework 运行时 |
| 纯 PowerShell 脚本任务 | Nano Server(带 PS) | 轻量即可 |
| 需要 AD/IIS 全功能 | Server Core | Nano 缺部分组件 |
| 需要中文语言包等系统组件 | 按需加对应 SDK 镜像 | 避免自定义组装 |
一句话:新应用一律 Nano Server;只有脱离不开 .NET Framework 的遗留应用才用 Server Core——镜像越小,攻击面越小、拉取越快。
4. LCOW 与 WSL2:跨平台的演进
4.1 Linux Containers on Windows(LCOW)
LCOW(Linux Containers on Windows)让单个 Windows 宿主机直接运行 Linux 容器:每个 Linux 容器放入一个精简的 Linux VM(用 Linux 内核引导),复用 Docker 的 Linux 镜像生态。
LCOW 架构:
Windows Docker Engine
└── Moby Linux VM(运行 Linux 容器) ← 每个 Linux 容器共享此 VM
└── Windows 容器(进程/Hyper-V 隔离)
现状:LCOW 曾长期 experimental,官方已转向 WSL2 方案
4.2 WSL2:当前 Windows 上跑 Docker 的主流方式
WSL2 = Windows Subsystem for Linux 2
- 真正的 Linux 内核(微软维护的 WSL2 内核)运行在轻量 VM 中
- Docker Desktop 基于 WSL2 跑完整 Linux Docker Engine
- 宿主与 Linux 之间通过 /mnt/wsl 与 localhost 互通
好处:
- 与生产 Linux Docker 完全一致的镜像/命令
- 文件 IO 大幅快于旧 Hyper-V WSL1
- 支持 Docker Compose、Buildx 等完整功能
# 启用 WSL2(管理员 PowerShell)
wsl --install -d Ubuntu-24.04
wsl --set-default-version 2
# 安装后验证
wsl -l -v
# NAME STATE VERSION
# Ubuntu-24.04 Running 2
4.3 何时用 LCOW,何时用 WSL2
| 需求 | 推荐方案 |
|---|---|
| 开发机上跑 Linux 容器 | WSL2 + Docker Desktop |
| Windows 服务器上混合跑 Linux+Windows 容器 | LCOW(若仍受支持)或分节点 |
| 只跑 Windows 容器 | 进程/Hyper-V 隔离即可 |
| CI Runner 需要双平台 | 独立 Windows Runner + Linux Runner |
一句话:WSL2 已成为"Windows 上体验 Linux 容器"的标准;LCOW 更多是历史演进,生产混合场景通常还是"Windows 节点跑 Windows 容器、Linux 节点跑 Linux 容器"的分节点架构。
5. 跨平台镜像仓库注意事项
5.1 平台标签与 digest
Windows 容器镜像在仓库中靠 OS/arch 清单区分,拉取时必须匹配宿主:
# 查看镜像的 OS 平台
docker manifest inspect mcr.microsoft.com/windows/servercore:ltsc2022 \
| jq -r '.manifests[].platform | "\(.os)/\(.architecture)/\(.variant)"'
# 强制拉取指定平台
docker pull --platform windows/amd64 mcr.microsoft.com/dotnet/aspnet:8.0
# 当前引擎的平台信息
docker info --format "{{.OSType}} {{.Architecture}}"
5.2 仓库管理与 CI 的注意点
□ 同一 tag 可承载多平台(manifest list),确保含 windows/amd64 条目
□ Harbor/ECR 的复制策略按平台区分,别把 Windows 镜像复制给 Linux 节点
□ 扫描工具:Trivy 支持 Windows 镜像,但漏洞库覆盖需留意
□ CI 中 Windows 镜像构建需 Windows Runner,别在 Linux Runner 上 build
# GitHub Actions 用 windows runner 构建 Windows 镜像
jobs:
build-windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: 构建 Windows 容器镜像
run: docker build -t registry.example.com/app:$env:GITHUB_SHA .
- name: 推送
run: docker push registry.example.com/app:$env:GITHUB_SHA
一句话:镜像仓库是"按平台分清单"的——Windows 镜像与 Linux 镜像同 tag 不同 manifest,拉取端(Windows/Linux 节点)各取所需,别在复制策略里混了平台。
6. Windows 容器运维
6.1 守护进程与基础运维命令
# 启动 Docker(Windows 容器模式)
Start-Service docker
docker info --format "{{.OSType}}" # 应为 windows
# 切换 Linux/Windows 容器模式(旧版 Docker EE 用 -SwitchDaemon)
# Docker Desktop:托盘图标切换;Server 上用 dockerd 配置
# 常见运维
docker ps
docker stats
docker logs <cid>
docker system prune -f
6.2 Windows 容器的存储与日志
Windows 容器存储:
- 默认层存储位于 C:\ProgramData\Docker
- 层叠文件系统用 Windows 的 differ(非 OverlayFS)
- Hyper-V 隔离:层存于虚拟磁盘(VHDX)
日志:
- 默认与 Docker 一致(json-file / ETW)
- 生产建议统一走 Fluentd/Loki 等日志驱动
# 给容器配置日志轮转(与 Linux 一致)
docker run -d --log-opt max-size=10m --log-opt max-file=3 myapp
6.3 资源限制在 Windows 上的表达
# Windows 容器支持内存与 CPU 限制(--cpus/--memory 同样适用)
docker run -d --cpus=2 --memory=2g --isolation=hyperv myapp
# 查看容器实际资源占用
docker stats
7. Windows 容器排障
7.1 常见问题速查
| 症状 | 根因 | 对策 |
|---|---|---|
no matching manifest for windows/amd64 | 镜像不含 Windows 平台 | 检查镜像 OS/arch / 拉 nano 镜像 |
| 容器启动失败且报内核不兼容 | 镜像版本 > 宿主版本 | 用 ≤ 宿主版本的基础镜像 |
| 进程隔离下容器内服务无法启动 | 依赖未包含在镜像 | Server Core 全量运行时 |
| Hyper-V 隔离启动超时 | VM 引导慢 | 加大 –stop-timeout、观察事件日志 |
| 文件权限/身份问题 | Windows 令牌与 ACL | 用 Process Isolation 的 gMSA 或按需配置 |
7.2 排障命令与事件日志
# 查看容器最近事件(Windows 事件日志)
Get-WinEvent -LogName Microsoft-Windows-Docker-* | Select-Object -First 10
# 容器退出码与详情
docker inspect -f "{{.State.ExitCode}} {{.State.Error}}" <cid>
# 进入容器诊断(Server Core 内可用 powershell)
docker exec -it <cid> powershell -Command "Get-Process"
# 宿主侧检查容器进程(job object)
Get-Process -Id (docker inspect -f "{{.State.Pid}}" <cid>)
7.3 与 Linux 容器排障的差异
□ 无 nsenter / /proc 查看 cgroup——用 Windows 工具与事件日志
□ exec 默认进 powershell(非 bash),命令语法不同
□ 网络排查:Windows 容器默认 NAT,用 docker network ls 与 ipconfig
□ 抓包:容器内可用 pktmon(Windows 内置),而非 tcpdump
# Windows 容器内网络排查
docker exec -it <cid> powershell -Command "ipconfig /all"
docker exec -it <cid> powershell -Command "Test-NetConnection -ComputerName 10.0.0.5 -Port 5432"
8. 混合部署:Windows + Linux 并存
8.1 三种混合架构
| 架构 | 说明 | 适用 |
|---|---|---|
| 分节点混合 | Windows 节点跑 Windows 容器,Linux 节点跑 Linux 容器,由 K8s/Swarm 统一调度 | 主流、稳定 |
| 同一主机双引擎 | 一台宿主上 Linux Docker + Windows Docker 并存 | 开发/测试 |
| LCOW | Windows 主机直接跑 Linux 容器 | 已边缘化 |
8.2 混合 K8s 集群示例
# Windows 节点(nodeSelector 约束到 Windows 工作负载)
apiVersion: apps/v1
kind: Deployment
metadata:
name: legacy-iis
spec:
replicas: 2
selector:
matchLabels: { app: legacy-iis }
template:
metadata:
labels: { app: legacy-iis }
spec:
nodeSelector:
kubernetes.io/os: windows
containers:
- name: legacy
image: mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2022
# Linux 工作负载走默认调度(无需 nodeSelector)
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 3
selector:
matchLabels: { app: api }
template:
metadata:
labels: { app: api }
spec:
containers:
- name: api
image: registry.example.com/api:1.4.2
8.3 混合部署最佳实践
□ 明确节点角色:Windows 节点只跑 Windows 镜像(污点/节点选择器锁定)
□ 网络:Windows 容器走 overlay/VXLAN 需确认 CNI 支持(calico/flannel 均支持)
□ 服务发现:两种容器统一用 DNS/K8s Service,跨 OS 也可互通
□ 监控:cAdvisor/Windows Exporter 分别采集,统一进 Prometheus
□ 存储:Windows 容器用 Windows 卷(NTFS),别期望 ext4 语义
9. 总结
| 主题 | 关键结论 | 一句话记忆 |
|---|---|---|
| 隔离模型 | 进程隔离共享内核、Hyper-V 隔离独立内核 | 重安全选 Hyper-V |
| 基础镜像 | 新应用 Nano Server,遗留 .NET 用 Server Core | 越小越好 |
| 版本匹配 | 镜像版本 ≤ 宿主 Windows 版本 | 版本只降不升 |
| 跨平台 | WSL2 是开发机上跑 Linux 容器的标准 | WSL2 优先 |
| 镜像仓库 | 平台清单区分 Windows/Linux manifest | 按平台分发 |
| 混合部署 | 分节点 + nodeSelector,避免 LCOW 依赖 | 分而治之 |
Windows 容器不是"换个镜像的 Linux 容器"——它有一套独立的内核交互、隔离模式与版本契约。落地要点:先按安全需求定进程/Hyper-V 隔离,再按应用选 Nano/Server Core,并严守镜像版本 ≤ 宿主版本的匹配规则;生产混合环境走"Windows 节点跑 Windows 容器、Linux 节点跑 Linux 容器"的分节点架构,配好 nodeSelector 与统一监控。当 Windows 容器不再是团队里的"黑匣子",你的容器平台才算真正打通了双生态。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。