Windows自带容器支持,你用过没

Author Image
admin Monday, June 1, 2020 阅读数: 98

[YoYoMooc]Windows自带容器支持,你用过没

推荐内容:

  1. 发布Docker镜像到阿里云容器仓库|Youtube(需科学上网)
  2. 发布Docker镜像到Azure容器仓库|Youtube(需科学上网)

13-1

在前面的章节中我们都是创建的镜像和容器都是使用Linux作为运行平台。

如果你使用的是Linux系统,作为开发机器,示例中的容器项目会使用你操作系统中的Linux 容器功能。 而对于 Windows 或 macOS,Docker 会安装一个 Linux 虚拟机,用于执行容器。

这使得容器和虚拟机之间的界限模糊了,使得我们可以在windows和Macos下运行和使用大量的Linux下才有的大型容器化应用,而这些镜像我们可以通过Docker Hub平台找到他们。

但是,Linux并不是唯一支持容器的操作系统。最新版本的Windows 10 和 Windows Server 2016 也提供了容器支持,同样可以隔离和运行Windows下的容器化应用程序。

从ASP.NET Core 开发者的角度上来看,当发生以下情况的时候会非常有用, 比如你使用的是IIS(互联网信息服务)部署你的应用程序,或者你的应用程序中有依赖于windows的组件,无法在Linux上运行。这个时候就很有用了。

在接下来的章节中,我将解释如何创建和测试一个Windows容器。创建一个Windows 容器的ASP.NET Core MVC应用程序需要一个类似于Linux等效的过程,但是需要进行一些重要的配置更改。

注意:Windows容器只能使用Windows操作系统来创建,并且只可以部署到Windows Server 2016及以上的系统中。Linux 容器的支持比较广泛,基础镜像也比较多,当你在生产环境中的时候,你应该使用 Linux 容器,除非你有一些特别的需求。

切换到Windows容器

首先我们需要将当前的容器环境切换为Windows容器,可以通过右键Docker图标进行切换,如下图:

13-1

这是告诉Docker,我需要使用Windows容器。然后windows 容器会重新启动,你如果出现切换的情况,大多数情况下重启电脑可以解决这个问题。

当切换成功后,你输入docker image ls会发现没有镜像返回,说明当前已经为Windows环境了,因为Linux 虚拟环境下,我们拥有镜像。同样不用担心Linux 的基础镜像不会丢失。

创建一个.NET Core Windows镜像

创建windows镜像我们之前的dockerfile文件就不能用了,我们创建一个新的Dockerfile文件。打开项目的根目录创建一个Dockerfile.windows文件。

输入以下内容

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-nanoserver-1903 

COPY dist /app
WORKDIR /app
EXPOSE 80

ENV ASPNETCORE_URLS http://+:80

ENTRYPOINT ["dotnet", "YoYoMooc.ExampleApp.dll"]

两个Dockerfile的文件,一个是服务于Linux系统下运行,一个是服务于Windows环境下运行。所以我们可以看到两个Dockerfile文件的基础镜像是不同的。

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-nanoserver-1903 

mcr.microsoft.com/dotnet/core/ 是微软的官方镜像库,在之前的章节中我们已经谈论过它了,它提供了很多不同的标记版本,用于在不同环境下运行。

目前我们选择的3.1-nanoserver-1903的版本,3.1表示ASP.NET Core的版本号,后面跟随的nanoserver-1903表示的是windows Nano server,这是一个Windows的最小安装版本。

前往Dockerhub,可以获取最新的aspnet的镜像地址:https://hub.docker.com/_/microsoft-dotnet-core-aspnet/

ENV ASPNETCORE_URLS http://+:80
  • ENV 命令表示在容器中设置一个环境变量。

在本例中,通过该命令设置了一个环境变量,环境变量 ASPNETCORE_URLS 的值,表示配置 Kestrel 服务器来监听80端口,这确保了我们可以使用相同的Docker命令来创建和使用Windows容器。

同样在前面的章节中,我也在Linux容器中也配置了监听80端口。

创建Windows本地镜像和容器

创建Windows的镜像和容器的过程与Linux是相同的,我们首先需要在YoYoMooc.ExampleApp根目录中,打开终端运行以下命令:

dotnet restore ##还原包
dotnet publish --framework netcoreapp3.1 --configuration Release --output dist



docker build . -t yoyomooc/exampleapp:windows -f Dockerfile.windows

在这里为了区别与Linux容器的区别,我们将镜像名称命名为yoyomooc/exampleapp:windows,添加一个Windows标记,通过参数-f 指定docker 生成的镜像文件为Dockerfile.windows

我们可以通过docker image ls命令来查看当前的镜像,结果如下:

REPOSITORY TAG IMAGE ID CREATED SIZE
yoyomooc/exampleapp windows e253023b2197 3 minutes ago 373MB
mcr.microsoft.com/dotnet/core/aspnet 3.1-nanoserver-1903 d533dfc81672 7 weeks ago 346MB

我们打开终端工具,启动一个windows容器,如果你在启动过程中遇到了blob开头的错误,这应该是你在Linux 容器中启动了Windows的容器,请切换容器环境为Windows。

输入以下命令:


docker run -p 7000:80 --name exampleAppWin yoyomooc/exampleapp:windows

访问浏览器URL地址:http://localhost:7000/ ,得到以下结果:

13-1

然后我们输入 Control+C 来退出当前容器,当前收到的消息是Kestrel的输出记录信息。

检查windows容器

我们可以尝试通过以下几种方式来测试容器是否可以正常被访问:

  • 通过localhoost:7000 来请求
  • 当前同一个局域网的ip地址加端口号的形式如:192.168.1.120:7000请求
  • 直接访问容器所在的虚拟网卡地址

那么问题来了容器所在的虚拟网卡地址,我们如何获取呢?

请输入以下命令:

docker inspect exampleAppWin

该命令会输出当前容器的所有详细内容,包括网卡和ip地址,稍微仔细查看可以找到如下内容:


## 其他内容

"Networks": {
               "nat": {
                   "IPAMConfig": null,
                   "Links": null,
                   "Aliases": null,
                   "NetworkID": "59daf61e798b5a387a5da87464c9777ffcb26a851bc27bdf0c7699184db91796",
                   "EndpointID": "f4885c05998b3c16ad9595dbaaf784dc6f1cb1766be9bc779b7e88f158d35f4e",
                   "Gateway": "172.30.224.1",
                   "IPAddress": "172.30.229.59",
                   "IPPrefixLen": 16,
                   "IPv6Gateway": "",
                   "GlobalIPv6Address": "",
                   "GlobalIPv6PrefixLen": 0,
                   "MacAddress": "00:15:5d:53:79:1a",
                   "DriverOpts": null
               }
           }


## 其他内容

上方输出内容显示了,当前容器所在的网卡地址和网卡信息,以及它的ip信息。 我们可以看到"IPAddress": "172.30.229.59" 是一个比较特殊的地址,通过访问它。我们同样可以的得到浏览器呈现的具体内容。

在Window容器中执行命令

同样的使用Windows容器,也可以像Linux容器一样,进行容器内部操作。

请输入以下命令:

docker exec -it exampleAppWin cmd


进入容器内容,这里我们使用的工具的cmd,我们当前选择的基础镜像不支持powershell,所以无法做更多复杂的操作,如果你要使用powershell工具,可以去寻找对应的镜像库。

然后输入命令:

type appsettings.Development.json

会返回以下内容:


 
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

type参数是cmd中查看文本文件内容是用的命令,将我们的配置信息打印出来。

如果你需要进行更多的操作,需要会使用CMD的相关命令,当然本视频不是一门CMD操作命令的书,故此就不展开讲解了。

小结

这几节课中,我们主要学习了如何创建和管理Docker镜像和容器。展示了如何创建Windows和Linux容器,如何修改容器并使用修改后的容器来创建新的容器和镜像,以及将对应的镜像发布到Docker Hub,阿里云及Azure。在后面的章节中,我将说明Docker是如何处理应用程序的数据存储问题,以及如何使用它定义网络将多个容器连接在一起使用。