公有云Windows Docker踩坑详述

2024-03-25 11:46:31 浏览数 (1)

备注:我用的香港服务器,听说海外机器安装docker、拉Windows镜像快一些,其中docker的安装貌似是从onegetcdn.azureedge.net这个站点下载数据的,这个站点在全球没有分布于国内的节点,只有海外节点,所以用国外服务器来搞会快一些。

大前提:

公有云windows不支持linux容器,因为linux容器需配合Hyper-V使用,而公有云不支持Hyper-V二次虚拟化。另外,公有云windows支持windows容器也是有条件的(微软的限制,并非公有云平台的限制),<server2016的低版本windows系统不支持windows容器,server2016需要改造tls(微软弃用<tls1.2的https访问,docker安装过程中会访问https,server2016默认不是≥tls1.2会报错)才能安装windows容器,server2019镜像不需要改造。如果要使用windows容器,建议使用≥server2019系统(请注意,windows容器是纯命令行的那种,不太好用,一般人不建议使用)。

wsl 1由于其本身问题,并不支持linux docker

wsl 2由于需要开启二次虚拟化,而普通云服务器不支持二次虚拟化,因此wsl 2在普通云服务器上也不支持linux docker

总结下就是wsl(无论1还是2)在普通云服务器上不支持linux docker,可参考https://cloud.tencent.com/developer/article/old/2279692

1、Windows Docker分类

windows容器(Windowsfilter )、linux容器(LCOW ,Linux Containers on Windows

Windows Container 分为两大部分: windows container on windows(下文简称Windowsfilter ) 和 linux container on windows(下文简称LCOW ), 我们今天将要用到的是Windowsfilter ,因为云服务器不支持LCOW 。

LCOW (Linux Containers on Windows) :微软拥抱Linux的产物,需配合Hyper-V使用(由于云服务器不支持二次虚拟化,因此不支持LCOW)。It turns out the Linux Containers on Windows (lcow) Server is a preview feature of both Windows Server, version 1709 and Docker EE. It won’t work on Windows Server 2016 of which the version is older than 1709.

腾讯云的2016是1607版本的,即便腾讯云支持二次虚拟化(阿里云等其他云厂商也不支持二次虚拟化),这个1607的2016镜像也不支持LCOW。

2、Windows云服务器不支持linux容器(LCOW ),只支持windows容器(Windowsfilter ),windows容器的使用如下

首先是镜像拉取,拉取的镜像代号指定错了或不匹配host os(服务器自身操作系统)会报错:指定的镜像tag不存在

镜像不兼容本地系统

拉镜像之前先powershell执行[System.Environment]::osversionwinver查清楚本地系统版本,再去微软容器基础镜像网页上去找(一般看前3个,2016看第1个,第2个和第3个里面没有2016能用的)

10.0.14393是Server2016(1607)的版号,14393后面的小版本号没列不影响,选的时候就看大版本号能对得上本地系统就行

10.0.17763是Server2019(1809)的版号,17763后面的小版本号没列不影响,选的时候就看大版本号能对得上本地系统就行

①Windows 容器版本兼容性: 不是什么镜像拉下来都能用的,拉之前先看兼容性列表

②Windows Docker隔离模式:

“支持 Hyper-V隔离”

“支持进程隔离”

关于container Isolation,process isolation特点是和host共享kernel。Hyper-V isolation特点是使用独立kernel。参考:https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/hyperv-container

3、How to enable experimental mode for Docker EE for Windows Server?

https://social.msdn.microsoft.com/Forums/en-US/72f948d2-4f2a-40fc-b65b-88e7ea4f6ed7/how-to-enable-experimental-mode-for-docker-ee-for-windows-server?forum=windowscontainers

powershell运行代码:

$configfile =@" {     "experimental":true } "@ $configfile|Out-File -FilePath c:Programdatadockerconfigdaemon.json -Encoding ascii -Force

restart-Service docker

使用 docker version -f '{{.Server.Experimental}}' 查看experimental是true还是false(默认是false)。从网上查资料,"experimental":true对LCOW有用,对Windowsfilter实测的情况是:true或false都不影响。

4、安装docker注意事项

2016 powershell运行 [Net.ServicePointManager]::SecurityProtocol 查看没有Tls12

目前Tls12(tls1.2,powershell里如果启用了,会显示Tls12)已是主流,IE浏览器不支持低于Tls12的https访问了,不改造直接安装docker会报错。

2016需要按照下面的办法改造,使能安装docker(那些需要二次虚拟化才能安装的方案都不支持云服务器)。

2019的powershell默认已有tls1.2,无需改造就能安装docker。

powershell tls没有1.2安装不了docker

As of April 2020, the PowerShell Gallery no longer supports Transport Layer Security (TLS) versions 1.0 and 1.1. If you are not using TLS 1.2 or higher, you will receive an error when trying to access the PowerShell Gallery. Use the following command to ensure you are using TLS 1.2:

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

For more information, see the announcement in the PowerShell blog.

powershell里执行[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12只是临时办法,关闭powershell下次再打开powershell还是旧的Ssl3, Tls

永久的办法是通过注册表实现,将以下代码另存为dotnet_tls1.2_on.reg,双击点“是”导入后,再打开powershell执行[Net.ServicePointManager]::SecurityProtocol 就会显示SystemDefault,这样后续关闭powershell打开也不会有问题了

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINESOFTWAREMicrosoft.NETFrameworkv4.0.30319]

"SystemDefaultTlsVersions"=dword:00000001

[HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoft.NETFrameworkv4.0.30319]

"SystemDefaultTlsVersions"=dword:00000001

[HKEY_LOCAL_MACHINESOFTWAREMicrosoft.NETFrameworkv2.0.50727]

"SystemDefaultTlsVersions"=dword:00000001

[HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoft.NETFrameworkv2.0.50727]

"SystemDefaultTlsVersions"=dword:00000001

也可以参考https://cloud.tencent.com/developer/article/old/2288081

先检查,

代码语言:javascript复制
[Enum]::GetNames([Net.SecurityProtocolType])
[Enum]::GetNames([Net.SecurityProtocolType]) -contains 'Tls12'
[System.Net.ServicePointManager]::SecurityProtocol.HasFlag([Net.SecurityProtocolType]::Tls12)

主要是看这句命令执行结果是不是True

代码语言:javascript复制
[System.Net.ServicePointManager]::SecurityProtocol.HasFlag([Net.SecurityProtocolType]::Tls12)

不是的话,临时启用tls1.2

代码语言:javascript复制
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
或
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

然后再在当前窗口再次执行上述检查tls1.2的命令

代码语言:javascript复制
[System.Net.ServicePointManager]::SecurityProtocol.HasFlag([Net.SecurityProtocolType]::Tls12)

5、解决了tls1.2的问题后按照微软官网文档安装docker

https://docs.microsoft.com/zh-cn/virtualization/windowscontainers/quick-start/set-up-environment?tabs=Windows-Server

英文链接就是把中文链接里的zh-cn换成en-us

https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/set-up-environment?tabs=Windows-Server

6、安装好以后就不要再看微软官网文档了,对初学者会误导

简单验证环境的话参考这个文档How To run Docker Containers on Windows Server 2019

After starting Docker Engine service, Download the pre-created .NET sample image from the Docker Hub registry:

代码语言:javascript复制
docker pull microsoft/dotnet-samples:dotnetapp-nanoserver-1809

Then deploy a simple container running a .Net Hello World application.

代码语言:javascript复制
docker run microsoft/dotnet-samples:dotnetapp-nanoserver-1809

The container will start, print the hello world message, and then exits.

上面两句微软已经把microsoft/dotnet-samples删了,用这个替换试试

docker pull deepfenceio/dotnet-samples:dotnetapp-nanoserver-1809

docker run deepfenceio/dotnet-samples:dotnetapp-nanoserver-1809

2016的话执行这2句命令就可以验证

docker pull microsoft/dotnet-samples:dotnetapp-nanoserver

docker run microsoft/dotnet-samples:dotnetapp-nanoserver

看到下面这个就代表环境是OK的。

上面两句微软已经把microsoft/dotnet-samples删了,用这个替换试试

docker pull msimons/dotnet-samples:dotnetapp

docker run msimons/dotnet-samples:dotnetapp

上面只是个简单测试,真正使用举例如下

2016:

2019:

run的时候加-it是启动容器时打开命令行,例如

如果不小心关闭了打开的容器命令行,可以执行docker ps -a查看容器的id,然后执行docker attach 容器id来恢复

docker stop 容器id(根据容器id关闭容器)

docker start 容器id(根据容器id启动容器,启动后用docker attach 容器id连到命令行)

0 人点赞