赞
踩
出品丨Docker公司(ID:docker-cn)
编译丨小东
每周一、三、五晚6点10分 与您不见不散!
说在前面
目前,有大量的应用程序以 Docker 容器的形式运行在 Windows Server 2016 上,但 Windows 容器一直与 Linux 容器在性能方面存在着一些细小的差距。但是,在已经到来的 Windows Server 2019 中,它弥补了大部分的性能差距,因此现在的 Windows Docker 容器几乎与 Linux 容器旗鼓相当。
接下来,我将介绍它主要的新功能。演示中所有的 Docker 镜像都来自我在 GitHub 上的 dockerfiles-windows repo 中,您可以点击文尾处“阅读原文”查看详情。
&
Windows Server 2019 使用的是 1809 版本的操作系统,Windows 10 的更新正在进行中,它将把这个内核添加到 Windows 10 中。所以,您可以在 Windows Server 2019 或者 Windows 10 的1809版本或更高版本上使用这些镜像。
发布的端口可以在 localhost 上访问
Windows 容器可以让您以常用的方式来发布端口,因此当网络流量在特定端口上进入您的计算机时,Docker 会将其定向到要处理的容器。但是在 Windows Server 2016 上,您只能从外部访问端口,而不能在计算机上使用 localhost。
Windows 10 上的 Docker Desktop 已经解决了这一问题。所以,您可以在桌面上使用 localhost,但网络的相关问题是发生在 Docker Desktop 中而不是操作系统层(不能进行“loopback”操作)。
现在,在 Windows Server 2019 中,操作系统中的网络堆栈已经可以进行“loopback”操作了。所以,您可以这样做:
PS> docker container run -d -p 8041:80 sixeyed/nginx:windowsservercore-1809
103b486d29818e02bd0da8ab42d854c42179de3e116bf4bd38c1840adca9cde9
PS> iwr -useb -method Head http://localhost:8041
StatusCode : 200
如果您在 VM 中开发,或者在 CI 过程中使用 Docker,那么这将变得非常方便。在 Windows Server 2016 上,您必须先获取容器的 IP 地址才能从主机访问它,但现在您可以直接从 localhost 中使用已发布的端口来进行访问。
命名管道可以与 Docker API 结合使用
在许多情况下,您希望在容器中运行软件,该容器可以在运行它的主机上访问 Docker API。 CI 是一个很好的例子,如果您使用的是多阶段构建这种方法来构建您的应用程序,那么您可以从容器内的源代码进行编译,而无需使用一大堆的工具来设置 CI 服务器。
相反,您可以在容器中运行 Jenkins,并使用 docker 或 docker-compose 命令进行构建。在构建步骤中,您只需在桌面上运行的相同 Docker 命令即可。
但是在 Windows Server 2016 中,您必须通过 TCP / IP 来访问 Docker API,这意味着您必须公开 Docker API 并使用 TLS 证书来保护它。然后,您还需对构建命令转换为参数化,以便传入 Docker API 配置:
& docker $dockerConfig image build $buildArg -t $fullTag .
构建时,在调用构建脚本之前,您需要在 $ dockerConfig 变量中设置 Docker API 的配置来完成将证书存储为 Jenkins 中的机密文件:
$dockerConfig = '--host', 'tcp://192.168.160.1:2376', '--tlsverify', `
'--tlscacert', $env:DOCKER_CA,'--tlscert', $env:DOCKER_CERT, '--tlskey', $env:DOCKER_KEY
代码看起来很难看,而且这意味着您还需要知道运行容器的机器的 IP 地址或主机名。 当在 Swarm 模式下运行时,这会变得更加困难。
现在,在Windows Server 2019中,您可以将 Docker API 的命名管道作为卷来安装。管道是 Docker CLI 访问在同一台机器上运行的 Docker API 的默认端点,它也适用于在运行它们的机器上访问 Docker API 的容器:
docker container run -d `
-p 8080:8080 `
-v C:\jenkins:C:\data `
-v \\.\pipe\docker_engine:\\.\pipe\docker_engine `
sixeyed/jenkins-sample:windowsservercore-1809
现在,您可以使用普通的 docker 和 docker-compose 命令而无需进行其他配置,因为容器内的 Docker CLI 可以从命名管道到达主机 API。这使得您的 Jenkins 工作步骤变得非常简单。
您不再需要通过 TCP / IP 来公开 Docker API 了,这意味着您不需要创建、应用和循环 TLS 证书,并且容器内的客户端也不需要知道运行它的主机的详细信息。
Swarm 模式支持Ingress网络
Docker Swarm 模式是一个非常简单但功能非常强大的容器编排工具。您可以将运行 Docker 的多个服务器连接到一个集群中,然后通过将应用栈部署到群集来管理您的工作负载。
Windows Server 2019 也可能是第一个支持 Kubernetes 与 Windows 节点的版本。
Docker Swarm 负责调度容器来在 Swarm 中的节点上运行,并维护您请求的服务级别。如果您指定一个 Web 应用程序应该运行10个容器来进行 HA 和扩展,那么 Docker 将在整个 Swarm 中启动10个容器,如果关闭了一个带有3个容器的服务器,那么 Docker 将在其余服务器上启动替代容器。
您还可以使用 Docker 入口网络的路由网为跨容器的传入流量进行负载均衡。这可以让您做两件非常有用的事情:
您可以配置过度的服务,这将让运行它的容器多于您集群中的节点。部分或全部节点将运行服务容器的多个副本。
您可以配置不足的服务,这将让运行服务的容器少于您集群中的节点。 部分节点将运行服务的零个副本,其他节点将运行单个副本。
入口网络意味着流量可以进入集群的任何节点,Docker 将其路由到监听容器。如果在收到请求的节点上运行的副本数为零,则会以静默的方式将其重定向到运行容器的另一个节点。如果有多个副本,Docker 将负责负载平衡。
这是一个很棒的功能,但 Server 2016 中的 Windows 容器不支持它。您必须使用主机模式发布,这意味着如果您想拥有公共可访问的端口,则每个服务器只能运行一个容器。(实际上,人们将 Windows 工作负载作为全局服务运行,或者使用在混合集群中的 Linux 容器上运行的反向代理来运行它们。)
现在 Windows Server 2019 支持 Docker 的入口模式,因此您可以使用所需的服务级别运行容器,并且可以增加或减少服务器,Docker 会自动引导和负载均衡流量。
您可以切换到 Swarm 模式并运行我提供的简单案例来验证这一点:
案例代码地址:https://github.com/sixeyed/dockerfiles-windows/tree/master/whoami-dotnet
docker swarm init --advertise-addr 127.0.0.1
docker service create `
--publish 8070:80 `
--replicas 5 `
sixeyed/whoami-dotnet:nanoserver-1809
您会看到这样的输出,并且还可以看到所有副本都在运行:
overall progress: 5 out of 5 tasks
1/5: running [==================================================>]
2/5: running [==================================================>]
3/5: running [==================================================>]
4/5: running [==================================================>]
5/5: running [==================================================>]
verify: Service converged
在 Swarm 模式下,您无法使用 localhost 来访问已发布的端口。您需要从外部发送通信以使其到达入口网络。
在另一台计算机上,您可以向集群发出客户端请求,并查看来自不同容器的响应,即使它们都是在单个服务器上运行的:
$ hostname
DESKTOP-BBD7UUM
$
$ for ((i=1;i<=5;i++)); do curl http://win2019:8070; printf "\n"; done
I'm fccdf0ecea5b running on Microsoft Windows 10.0.17763
I'm b00baa697176 running on Microsoft Windows 10.0.17763
I'm 60a2be72474e running on Microsoft Windows 10.0.17763
I'm 30edb8b1b302 running on Microsoft Windows 10.0.17763
I'm 45c110bc5d34 running on Microsoft Windows 10.0.17763
点击下列标题,阅读更多干货
如果本文对你有帮助,欢迎分享到朋友圈!获取更多Docker实用技巧,扫描下图二维码!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。