Windows docker 容器使用问题及解决

最近我注册了微软 Azure 账户,对于新用户可以免费使用 Linux 虚拟机(VM,下同)和 Windows VM各一台,因对 Azure 的好奇以及体验,遂将原本运行于腾讯云的本博客迁移到了 Azure 免费试用版上。刚开始时仅开通一台免费 Linux VM, 将本站博客应用的 Docker 容器以及数据库部署在该服务器上,由于是免费试用版,一段时间过后,发现本站经常无法打开,甚至远程连接都无法进入。经查询分析,才知道是系统资源(1C1G)耗尽,佩服 Azure 管控的同时,得出该免费版无法同时满足部署博客应用以及数据库的结论。

于是,我就有了开通 Windows VM 的想法,将本站应用和数据库分开部署,在 Windows VM 上部署本站应用 Docker 容器。也因为免费版本配置(1C1G)的限制,我选择了 Windows Nano Server 作为操作系统,除了运行系统所需资源外,还剩下近 400M 的内存供本站应用运行。这里需要补充说明一点, Windows Nano Server 是除了 cmd 命令行窗口外,没任何其它界面的,类似于 Linux 系统。对于经常使用 Windows 界面的人来说,这一点会极不习惯。

由于是 Nano Server 是无界面的,自然想到的是使用容器技术部署运行应用。好在开通 Windows VM 后,系统默认安装了 docker,顿时有一种莫名的兴奋,因为本站(pzy.io)应用原本就是基于 Docker 部署运行,看起来只要拉取镜像,再运行起来就算迁移成功了。但事实上却是状况不断,下文一一叙述。

1、执行 docker 命令出错

要使用 docker 容器,首先得拉取应用相应的镜像,当我执行docker pull xxx:tag后,出现以下错误:

error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.35/info: open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuration on Windows, the docker client must be run elevated to connect. This error may also indicate that the docker daemon is not running.

然后我尝试执行docker images,还是报上述错误。是不是因为 docker 没安装?执行docker -v却是正常的。于是搜索这个问题的原因及解决方法,在 github 找到了相关信息,其中大多数人赞成以下解决方法:

cd "C:\Program Files\Docker\Docker" 
./DockerCli.exe -SwitchDaemon

按照上述方法尝试多次,但仍然无法解决,因为 Windows VM 不存在DockerCli.exe这个文件。经过不断地思考和尝试,终于找到该问题的原因了——Windows 上 docker 是以 Windows 服务运行的。这是个常识问题,我开始为何没想到,值得反思。

那么解决方法也就很简单了,使用net start docker启动 docker 服务,如果要重启或停止服务则可以使用net restart/stop docker

2、无法拉取 Linux Docker 镜像

docker 的问题解决了,便拉取原本基于 Linux 系统制作的 docker 镜像,却出现“该镜像基于 Linux,无法适用于本平台”的提示。这里我犯了一个认知错误的问题,以为某个 docker 镜像适用于所有操作系统平台。因之前的 docker 是基于 Linux 平台生成,不适用于 Windows容器 。对于 Windows 容器来说,需要生成基于 Windows 平台的 docker 镜像。

3、Windows docker 镜像仍不可运行

原以为生成基于 Windows 平台的 docker 镜像,只需要在 Docker desktop 上切换为 Windows  容器,即Switch to Windows containers,然后使用原 Dockerfile 文件生成镜像即可。事实上执行生成命令时出错了, 因为原 Dockerfile 中依赖的镜像是基于 Linux 的平台,不能用于Windows 镜像生成。这里就涉及到 Windows 依赖包平台选择的问题了。

由于本站主要是基于 .NET Core 3.x 开发,使用的镜像依赖运行时和 SDK 包由微软官方提供,微软对于这些依赖镜像区别了 Linux 和 Windows 平台版本。并且对自身的 Windows Server Core 还有更细微的版本区分,也就是不同的操作系统内核版本对应不同的镜像版本。下图摘自于 Docker Hub Windows Server Core 官方镜像说明:

Windows docker 镜像
Windows docker 镜像

上表中,Tags 列指 Docker 镜像版本,OsVersion 指操作系统版本,它们存在一一对应的关系。所以,在生成 Windows 镜像前,需要首先知道当前服务器系统版本,然后根据系统版本对应到运行的镜像版本,基于该镜像版本生成对应镜像。由于我当前的操作系统版本是10.0.17763,依照上图,我选择了1809这个版本的镜像,即mcr.microsoft.com/windows/servercore:1809

4、Linux 容器与 Windows 容器异同

首先要明确一点,不要认为同一 Docker 镜像可以同时运行于 Liunx 和 Windows 平台上,不同平台还是需要制作不同的 docker image。根据我短暂使用经历,简短总结以下异同点。

 相同点:都是基于 Dockerfile 生成容器镜像,并且生成镜像命令相同 ,而且运行容器命令类似。

不同点:Windows 下不能像 Linux 一样使用--net=host启动参数映射容器和宿主机网络,目前只知道使用端口映射的方式使用网络。另外进入容器内部的命令也不同,Linux下是:

docker exec -it [container_id] bash

Windows下:

docker exec -it [container_id] cmd

全文完,欢迎与我交流,与有问题请及时提出。

《Windows docker 容器使用问题及解决》的相关评论

发表评论

必填项已用 * 标记,邮箱地址不会被公开。