6

使用原生的 Windows Docker 容器

 2 years ago
source link: https://yanbin.blog/windows-native-docker-container/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

使用原生的 Windows Docker 容器

2022-02-25 — Yanbin

一谈到 Docker 容器,按照以往的惯性思维,那就是 Linux 容器(LXC),和 Windows 没多大关系,顶多也就是在 Windows 的 Linux 虚拟机中跑 Docker 容器。

不过自从 Windows Server 2016 开始,出现了 Windows 原生的 Docker 容器,它再也不只是 Linux 下的专利了。Docker 容器中可以运行 Windows 系统了, 每个 Windows 容器共享宿主机的 Windows 内核(--isolation=process,),或使用一个高度优化虚拟机中的 Windows 内核(--isolation=hyperv)。

我们说自 Windows Server 2016 开始,包括现在的 Windows Server 2019, Windows Server 2022, 还有桌面系统的 Windows 10 和  11 上 借助于 Docker Desktop 也能跑 Windows 容器。

原本在 Windows 桌面版上安装 Docker Desktop 就能用来运行 Linux 容器,由此可知在 Windows 桌面版上(如 Windows 7, 10, 11) 可运行两种类型的容器

  1. Linux 容器: 每个容器运行的是 Linux 实例,用 cgcroups 命名空间隔离资源。默认的,使用 Docker Desktop 的 LinuxEngine
  2. Windows 容器:容器中运行的是 Windows 实例,进程隔离模式是容器共享主 机的 Windows 内核,Hyper-V 隔离模式是容器使用高度优化虚拟机的内核。需启用 Windows 的 Hyper-V 特性,并切换 Docker Desktop 使用 WindowsEngine

由于在传统的 LXC 的概念上加入了 Windows 容器,所以 Docker 的架构变成下面这样了

windows-docker-1.png

关于 Windows Docker 容器的知识可参考微软的官方文档 Containers on Windows Documentation

Windows 的最基础的镜像有以下四种,按重量级由重到轻排列:

  1. Windows: 包含全套 Windows API 和系统服务(但不含 Server 相关的),比如 Windows 10 镜像 20H2。
  2. Windows Server: 包含全套 Windows API 和系统服务,允许使用多数服务特性,需要 GPU 加速就用它。
  3. Windows Server Core: 只包括主要用以支持 .NET 框架的 Windows Server API 子集。也包含多数服务(如 Fax 服务就没有)。
  4. Nano Server: 最轻量级 Windows Server 镜像,仅包含支持 .NET Core API 一些服务。

我们构建自己的镜像可选择以上基础镜像,更快捷的方式是选择别人已添加有我们需要的软件包的镜像。比如要用 Windows 下运行 Python 可选择 3.10.2-windowsservercore-ltsc2022; .net sdk4.8 的 https://mcr.microsoft.com/dotnet/framework/sdk:4.8。

粗略对比一下各版本镜像文件大小(因版本而有很大的差异),以下是用 docker images 列出的镜像大小

  1. mcr.microsoft.com/windows:20H2 大小 16.2G
  2. mcr.microsoft.com/windows/server:ltsc2022 大小 11.4 G
  3. mcr.microsoft.com/windows/servercore:ltsc2022 大小 4.96 G, mcr.microsoft.com/windows/servercore:ltsc2016 却有 12G
  4. mcr.microsoft.com/windows/nanoserver:ltsc2022 大小 295 M,像是一个嵌入式系统

只能在 Windows 平台下 pull/run/build Windows 镜像,并且要求当前 Windows 平台与镜像的版本要兼容,不像 Linux 容器对当前平台没有任何要求。我们会在后面详细了解到。

Windows Server(包括目前的 Windows 2016, 2019, 2022) 安装 Docker,在 PowerShell 中执行

Install-Module -Name DockerMsftProvider -Repository PSGallery -Force

如提示要安装 NuGet 的话,选择 Y。如果上面命令要求 TLS 的话,请先执行

[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;

最后安装  Docker

Install-Package -Name docker -ProviderName DockerMsftProvider

Windows 10 或 11 下要安装 Docker Desktop

接下来以 Windows 10(同样适用于 Windows 11) 为例, 看两种容器类型(Linux/Windows)的不同,为此还专门安装了一个干净的系统, 以下是测试机器的软硬件环境

  1. CPU: Intel i7-7700 @3.60GHz
  2. 内存:48 GB
  3. Windows 10 Pro, 21H1, OS Version: 10.0.19043
  4. Docker Desktop 4.5.1 (74721), 并其要求的 WSL 2
  5. 还未开启额外的 Windows 特性,如 Containers, Hyper-V, Windows Hypervisor Platform, 但发现默认开启了 Virtual Machine Platform

Windows 下的 Linux 容器

在刚安装完 Windows 10 Pro + Docker Desktop, 默认情况下,是用的 LinuxEngine,所以只能支持 Linux 容器,运行 docker version 查看 server/client 的版本

C:\Users\yanbin>docker version
Client:
Cloud integration: v1.0.22
Version:           20.10.12
API version:       1.41
Go version:        go1.16.12
Git commit:        e91ed57
Built:             Mon Dec 13 11:44:07 2021
OS/Arch:           windows/amd64
Context:           default
Experimental:      true
Server: Docker Desktop 4.5.1 (74721)
Engine:
  Version:          20.10.12
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.16.12
  Git commit:       459d0df
  Built:            Mon Dec 13 11:43:56 2021
  OS/Arch:          linux/amd64
  Experimental:     false
containerd:
  Version:          1.4.12
  GitCommit:        7b11cfaabd73bb80907dd23182b9347b4245eb5d
runc:
  Version:          1.0.2
  GitCommit:        v1.0.2-0-g52b36a2
docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

我们看到上面的  Server Engine OS/Arch: linux/amd64。 Server 的 linux/amd64 表示 Docker 只能运行 Linux 容器。

这时候我们可以运行

docker pull busybox
docker run busybox echo hello world!

也能构建 Linux 镜像,如 Dockerfile 内容

FROM ubuntu:20.04
CMD echo hello world!

docker build -t test .
docker run test

如果此时试图去 pull 或 run 一个 Windows 容器是非法的

C:\Users\yanbin> docker pull mcr.microsoft.com/windows/nanoserver:20H2
20H2: Pulling from windows/nanoserver
no matching manifest for linux/amd64 in the manifest list entries

当然 run/build Windows 镜像也不行,因为在 run/build 之前都要 pull Windows 镜像。原因为与当前的 linux/amd64 不匹配。

探究 Windows 下的 Docker Desktop LinuxEngine

还是用 理解 Docker Client/Server 架构, 找寻 Docker Desktop 替代品 中的老办法,揭一揭 Docker Desktop 的小底

c:\Users\yabqi>docker context ls
NAME                TYPE                DESCRIPTION                               DOCKER ENDPOINT                             KUBERNETES ENDPOINT   ORCHESTRATOR
default *           moby                Current DOCKER_HOST based configuration   npipe:////./pipe/docker_engine                                    swarm
desktop-linux       moby                                                          npipe:////./pipe/dockerDesktopLinuxEngine

进到 Docker 的宿主机

c:\Users\yanbin>docker run --net=host --ipc=host --uts=host --pid=host -it --security-opt=seccomp=unconfined --privileged --rm -v /:/host alpine chroot /host
root@docker-desktop:/# uname -a
Linux docker-desktop 5.10.16.3-microsoft-standard-WSL2 #1 SMP Fri Apr 2 22:23:49 UTC 2021 x86_64 GNU/Linux
root@docker-desktop:/# free
               total        used        free      shared  buff/cache   available
Mem:        39336428      586016    37845116      377180      905296    37951412
Swap:       10485760           0    10485760
root@docker-desktop:/# cat /proc/cpuinfo | grep processor
processor       : 0
processor       : 1
processor       : 2
processor       : 3
processor       : 4
processor       : 5
processor       : 6
processor       : 7

物理内存为 48G, Docker 宿主机可使用最大 39G 的内存,CPU 也可用所有的 8 个内核。这与 Mac OS X 下 Docker Desktop 默认分配置 2G 内存,CPU 总内核数一半数量是不同的。

注意,到目前为止 Windows 10 的 Hyper-V 是未启用的,用命令查看

PS C:\Windows\system32> Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V
FeatureName      : Microsoft-Hyper-V
DisplayName      : Hyper-V Platform
Description      : Provides the services that you can use to create and manage virtual machines and their resources.
RestartRequired  : Possible
State            : Disabled
CustomProperties :

切换到使用 Windows 容器

如果要在 Windows 10 中使用 Windows 容器,先对 Docker Desktop 进行切换到  Windows containers,点开系统栏上的 Docker Desktop, 进入它的上下文菜单

windows-container-1.png

或者用 DockerCli 命令来切换

"c:\Program Files\Docker\Docker\DockerCli.exe" -SwitchWindowsEngine

如果要从 WindowsEngine 切换回到 LinuxEngine 的话,参数就是 -SwitchLinuxEngine

或者用 -SwitchDaemon 参数在 LinuxEngine 与 WindowsEngine 之间来回切换

"c:\Program Files\Docker\Docker\DockerCli.exe" -SwitchDaemon

不过,现在无论是通过 UI 还是命令试图切换到 WindowsEngine 都会弹出一个错误容器

windows-container-2-800x315.png

原因就是 Hyper-V 没开启,可用 Turn Windows features on or off 界面中操作

windows-container-3-800x696.png

或用前面提示的 PowerShell 指令

Enable-WindowsOptionalFeature -Online -FeatureName $("Microsoft-Hyper-V", "Containers") -All

开启 Hyper-V 后 Windows 会自动重启。完后再执行上一步操作就能成功切换 Docker Desktop 到 Window containers 模式,此时再查看 docker version

C:\Users\yanbin>docker version
Client:
Cloud integration: v1.0.22
Version:           20.10.12
API version:       1.41
Go version:        go1.16.12
Git commit:        e91ed57
Built:             Mon Dec 13 11:44:07 2021
OS/Arch:           windows/amd64
Context:           default
Experimental:      true
Server: Docker Desktop 4.5.1 (74721)
Engine:
  Version:          20.10.12
  API version:      1.41 (minimum version 1.24)
  Go version:       go1.16.12
  Git commit:       459d0df
  Built:            Mon Dec 13 11:42:13 2021
  OS/Arch:          windows/amd64
  Experimental:     false

版本信息显示的更简单些,我们看到 Server / OS/Arch 变成了 windows/amd64。

如果此时试图运行 Linux 容器也是不行的

C:\Users\yanbin>docker run busybox
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
docker: no matching manifest for windows/amd64 10.0.19043 in the manifest list entries.
See 'docker run --help'.

构建运行 Windows 镜像/容器

C:\Users\yanbin>docker run mcr.microsoft.com/windows:20H2 cmd /c "echo hello world!"
hello world!

构建 Windows 镜像,Dockerfile 内容为

FROM mcr.microsoft.com/windows/servercore:ltsc2016
CMD echo hello world!

C:\Users\yanbin>docker build -t test .
C:\Users\yanbin>docker run test
hello world!

WindowsEngine 下的 Docker Desktop

切换到 WindowsEngine 后看下 docker context

C:\Users\yanbin>docker context ls
NAME                TYPE                DESCRIPTION                               DOCKER ENDPOINT                               KUBERNETES ENDPOINT   ORCHESTRATOR
default *           moby                Current DOCKER_HOST based configuration   npipe:////./pipe/docker_engine                                      swarm
desktop-windows     moby                                                          npipe:////./pipe/dockerDesktopWindowsEngine

出现了一个 desktop-windows,而不是先前的 desktop-linux

至于 Windows 容器的宿主机就和隔离模式有关了,有两种,分别是进程隔离和 Hyper-V 隔离

它与 Linux 容器的 cgroups 命名隔离类似的,所有容器共享当前系统内核,容器其实就是一个当前系统下的进程。当前系统为 Windows 容器的宿主机,这时候要求所运行的容器与当前操作系统一致的版本,否则无法共享内核,也就会出现下面的错误

C:\Users\yanbin>docker run -it --isolation=process mcr.microsoft.com/windows/servercore:ltsc2016 ping localhost -t
docker: Error response from daemon: hcsshim::CreateComputeSystem 2cc0e4e8ce8c0f7e8c82bef76df4a9dbf0672d6ffe29776814891ce27c6bb3fe: The container operating system does not match the host operating system.

和 Linux 的容器类似,如果用 --isolation=process 启动的进程可用 Get-Process 命令列出来

Hyper-V 隔离

docker 运行时的 --isolation 的默认值为 hyperv, 此时容器会运行在一个高度优化的虚拟机当中,容器进程也不会出现在当前系统中,而是被包裹在一个个的 vmwp 虚拟机进程当中。也就是说那个虚拟机才是 Windows 容器的宿主机。但哪里能查看到那个所谓高度优化的虚拟机呢?在 Hyper-V Manager 中没有,用 Get-VM 命令看列不出来,优化的太有高度了。

学习到 Windows 容器的两种隔离模式,这或许可用来解释为什么 docker run -p 80:8080 ... 映射端口时不通的原因,默认 hyperv 隔离时 80 开到了那个高度优化的虚拟机中了,而不是当前操作系统,应该用 --isolation=process 尝试下,只是必须保证当前系统版本与容器中系统版本要高度一致。----- 经验证,即使用 --isolation=process -p 80:8080, 端口还是无法映射出来。

还有启动容器的速度也许与选择的隔离模式有关,再高度优化的虚拟机也应该比进程隔离方式启动容器要慢,因为进程隔离本质上就是本地的一个进程。----- 实际测试好像差不了多少,反正都比 Linux 容器慢多了,至少一个数量级的差异。

在某一个特定的 Windows 操作系统上,并不是所有 Windows 镜像都支持进程隔离,Hyper-V 隔离都是支持的,参考 Windows 容器版本兼容性列表 Windows container version compatibility

Windows 系统与容器版本兼容性

了解这方面的内容可指导我们选择什么版本的 Windows 来构建镜像,在什么版本的 Windows 系统上运行容器。这对 Linux 容器根本不是问题,因为基本上只要是一个能运行 docker 命令的 Linux 系统就能自由的构建/运行任何 Linux 发行版的镜像。而首次接触到 Windows 容器时,选择一个 Windows 机器,并且能以 WindowsEngine 方式运行 docker 命令, 想要 pull, run 或 build 一个镜像时,头脑中仍然保有 Linux 容器的思维定式,很容易遭受挫折。

比如在 Windows 2016 上 pull mcr.microsoft.com/windows/servercore:ltsc2022 的镜像

PS C:\docker> docker pull mcr.microsoft.com/windows/servercore:ltsc2022
ltsc2022: Pulling from windows/servercore
8f616e6e9eec: Extracting [==================================================>] 1.252 GB/1.252 GB
898469748ff6: Download complete
failed to register layer: re-exec error: exit status 1: output: ProcessUtilityVMImage C:\ProgramData\docker\windowsfilter\ce66a282a87a379aca443a594025eee342160907305a3f4323f2baaa38d89937\Util
ityVM: The system cannot find the path specified.

但 pull mcr.microsoft.com/windows/servercore:ltsc2016 是没问题的。docker run/build 基于不兼容的镜像版本也是一样的问题,因为 rub/build 之前需要先 pull。

PS C:\> docker run mcr.microsoft.com/windows/servercore:ltsc2016 cmd /c "echo hello"
docker: Error response from daemon: hcsshim::CreateComputeSystem a9c5b39283e525ca8cbf688f95d7aaabfdd1eb7dd21914d9e587144a455125ca: The container operating system does not match the host operating system.

因此,清楚的了解 Windows 系统与容器版本兼容性也不至于一接触 Windows 容器就可能令我们垂头丧气,甚至有些抓狂。

Windows 系统与 Windows 镜像版本的对应,以及是否支持 Hyper-V 或进程隔离请参考这个列表 Windows container version compatibility。基本上是新版本兼容旧版本,如 Windows Server 2019 下可运行 Windows Server 2019 和 Windows Server 2016, Windows Server 2022 就能运行从 Windows 2016 到 Windows 2022 之间所有的版本。但支持进程隔离的话,必须是平台与容器的版本一致,如 Windows Server 2019 以进程隔离方式运行 Windows 容器就只能支持 Windows Server 2019。

同样的,在用 docker pull 或 build 时也要遵行前面这个兼容性表格。构建时使用高版本操作系统平台更具广泛的兼容性,但要用到 --isolation=process 的好处运行容器时就要完全一致的版本。

这种 Windows 镜像版本与 Windows 宿主机的严格的匹配并系破坏了运行 Linux 容器的初衷,我们在一个 Linux 宿主机中运行其他的 Linux 容器根本都不用在乎是什么内核版本或发行版本。这有点像当初 Windows 对 Java 掺一手搞出个 Visual J++ 直接破坏了 Java 所号称的一次编写到处运行的口号。

AWS 对 Windows 容器的支持

之前一直在 ECS 中使用 Linux 容器服务,因为定义 Task 时必须指定镜像,而那时对 Windows 容器不是一片黑,一直觉得 ECS 根本就不支持 Windows 容器。最近才注意到 AWS 早已提供了很多的优化了的 Windows Server ECS AMI 用来跑 docker Windows 容器, 如

Windows_Server-2016-English-Core-Containers-*
Windows_Server-2016-English-Full-ECS_Optimized-*
Windows_Server-2019-English-Core-Containers
Windows_Server-2019-English-Full-ECS_Optimized-*
Windows_Server-2022-English-Core-Containers-*
Windows_Server-2022-English-Full-ECS_Optimized-*
Windows_Server-20H2-English-Core-Containers
Windows_Server-20H2-Core-ECS_Optimized-*

Windows 的版本可以通过 ver, systeminfo 命令获得

在选择的 Windows_Server-2016-English-Core-Containers-2016  上试图用 docker run --isolation=hyperv 时却提示没有 hypervisor

PS C:\docker> docker run --isolation=hyperv mcr.microsoft.com/windows/servercore:ltsc2016 cmd /c "echo hello"
C:\Program Files\Docker\docker.exe: Error response from daemon: container fba5ff713c0e9a4fc439747c6792251855c06dfcb1649c3e58d72280b9d62a23 encountered an error during CreateContainer: failure
in a Windows system call: No hypervisor is present on this system. (0xc0351000) extra info.......................

虽然 ECS 支持 Windows 容器,但 Windows 镜像身躯十分巨大,动不动 10G 起步,相比 Linux 的 100-200M 左右的镜像,可称是个巨兽,这会严重影响构建,推送,拉取镜像的速度。且镜像下载后启动一个 Windows 容器也比较慢。所以对于 Windows 应用程序或许要跑过 ECS, 而让  ELB 直接连向 EC2 Target Group。

启动速度测试

对于同一个镜像还无法进行不同隔离模式下启动速度的测试,因为在 Windows Server 上不能用 --isolation=hyperv 隔离级别。

Windows 容器不同隔离模式

在 Windows Server 2016 上分别以进程隔离和 Hyper-V 隔离测试启动 Windows 容器的速度

PS C:\docker> Measure-Command {docker run --isolation=process mcr.microsoft.com/windows/servercore:ltsc2016 cmd /c "echo hello" | Out-Host} | findStr TotalSeconds
TotalSeconds      : 6.1539651

平均耗时 6.15 秒。

这与在 Linux 下启动一个 Linux 容器是无法比拟的

$ time docker run ubuntu:20.04 echo hello
real    0m0.361s
user    0m0.019s
sys 0m0.005s

在 Windows 10 下启动一个 ubuntu:20.04 的时间为

PS C:\Windows\system32> Measure-Command {docker run ubuntu:20.04 echo hello | Out-Host} | findStr TotalSeconds
TotalSeconds      : 1.7179686

刚开始用到 Windows 容器时头脑中总是延续着 Linux 容器的思维,哪知其实几乎是进入了另外一个世界,本来一个十分趁手的 Docker 容器在 Windows 那边却被压缩的会四处碰壁。Windows 容器不光是个头大,而且 Windows 容器启动明显示的缓慢。 

至今仍有一个问题有待解决,就是用 -p 端口映射时无法在执行 docker 命令的机器上启动相应的端口。

所以还是能用 Linux 的地方坚决拥护 Linux,像 C# 的代码如果能用 .NET Core 解决的话一定是件幸事。


端口映射的问题(已解决)[2022-03-02]

运行 Windows  Server Docker container

docker run --name aspnet_sample --rm -it -p 8080:80 mcr.microsoft.com/dotnet/framework/samples:aspnetapp

之前依旧的按照 Linux 容器的惯性,先用 docker ps 验证端口映射是否已设置(下面只显示 Name 和 Ports)

PS C:\Windows\system32> docker ps --format "{{.Names}}: {{.Ports}}"
aspnet_sample: 0.0.0.0:8080->80/tcp

端口映射没问题,从宿主机的 8080 到容器的  80

先用类似于 Linux 的 netstat -na|grep 8080 检查一下在宿主机上是否开启了 8080 端口

PS C:\Windows\system32> netstat -na|findstr 8080
PS C:\Windows\system32>

发现什么都没有,再加上 telnet 双重验证

PS C:\Windows\system32> telnet localhost 8080
Connecting To localhost...Could not open connection to the host, on port 8080: Connect failed

这时候查看容器的 IP 和端口号

PS C:\Windows\system32> docker exec aspnet_sample ipconfig
Ethernet adapter vEthernet (Container NIC 91439e0f):
    Connection-specific DNS Suffix  . : ec2.internal
    Link-local IPv6 Address . . . . . : fe80::e878:9772:931:e2cd%19
    IPv4 Address. . . . . . . . . . . : 172.25.8.94
    Subnet Mask . . . . . . . . . . . : 255.255.240.0
    Default Gateway . . . . . . . . . : 172.25.0.1
PS C:\Windows\system32> docker exec  aspnet_sample netstat -na|findstr 80
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING
TCP [::]:80 [::]:0 LISTENING

容器内启动的 80 端口是没问题的, 所以通过容器 IP 访问 http://172.25.8.94:80 是没问题的,有些地方却介绍访问 http://172.25.8.94:8080 来访问(此路不通)。而且一个理由是在更早的版本要用容器 IP,哪个更早又没说清楚。

After the application starts, navigate to http://localhost:8080 in your web browser. You need to navigate to the application via IP address instead of localhost for earlier Windows versions
https://hub.docker.com/_/microsoft-dotnet-framework-samples/?tab=description

看到上面的景象后,基本就气馁了 -- 1) localhost 的 8080 没有打开, 2) 容器的 80 端口确实是打开了,但外部不知道容器的 IP 一般也无法直接访问容器,即使能直接访问容器(设置不同的网络类型),那所谓的 -p 8080:80 端口映射根本就没必要的,因为不管有无 -p 参数,容器内的 80 端口都会开启。

前几天我就一直被这种假象所困扰,由 netstat -na 看到不主机的 8080 端口,且 telnet localhost 8080 也不通,本能的认为 Windows Server 容器的端口映射没戏,进一步用它来做 ECS 的端口映射也势将无法成功。其实这只是一个显示 Bug, 见 Open issue: [Windows] Port binding is not visible with 'netstat' but works correctly. #30300

这种情况下,端口映射其实是成功的,只是不能用 localhost:8080 来访问,用 ipconfig 找到主机 IP, 然后访问 主机 IP:8080 是能通的

PS C:\Windows\system32> ipconfig
........
Ethernet adapter Ethernet:
   Connection-specific DNS Suffix  . : ec2.internal
   Link-local IPv6 Address . . . . . : fe80::64ea:22d5:4620:79a8%4
   IPv4 Address. . . . . . . . . . . : 10.255.60.241
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 10.255.60.1

telnet 10.255.60.241 8080

也没问题的,也就是从远程访问 http://10.255.60.241:8080 是通的,自然作为 ECS 的端口映射也不是个问题

windows-container-4-1.png

netstat -na 是个假象,localhost:8080 确实也不通,127.0.0.1:8080 也不行,也就是说启动 Windows 容器时的 docker -p 8080:80 只会在网卡的 8080 端口上监听,只对 netstat -na, 甚至是 PowerShell 命令 Get-NetTCPConnection 都不可见。不过再来一个 -p 8080:80 就能暴露问题了

PS C:\Windows\system32> docker run -p 8080:80 mcr.microsoft.com/dotnet/framework/samples:aspnetapp
C:\Program Files\Docker\docker.exe: Error response from daemon: failed to create endpoint dazzling_clarke on network nat: HNS failed with error : The object already exists.

端口 8080 已被占用,证明 8080 已在某个我们所看不到的地方已绑定了。

自此,在 ECS 中使用 Windows 容器值得进一步去实践,下面的任务大约就是如何控制 Windows Docker 镜像的大小,放到网速快的 Docker Registry 中。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK