在前面的章节中我们都是创建的镜像和容器都是使用 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 容器,可以通过右键 Docker 图标进行切换,如下图:
13-1
这是告诉 Docker,我需要使用 Windows 容器。然后 windows 容器会重新启动,你如果出现切换的情况,大多数情况下重启电脑可以解决这个问题。
当切换成功后,你输入docker image ls
会发现没有镜像返回,说明当前已经为 Windows 环境了,因为 Linux 虚拟环境下,我们拥有镜像。同样不用担心 Linux 的基础镜像不会丢失。
创建 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
在本例中,通过该命令设置了一个环境变量,环境变量 ASPNETCORE_URLS 的值,表示配置 Kestrel 服务器来监听 80 端口,这确保了我们可以使用相同的 Docker 命令来创建和使用 Windows 容器。
同样在前面的章节中,我也在 Linux 容器中也配置了监听 80 端口。
创建 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 的输出记录信息。
我们可以尝试通过以下几种方式来测试容器是否可以正常被访问:
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"
是一个比较特殊的地址,通过访问它。我们同样可以的得到浏览器呈现的具体内容。
同样的使用 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 是如何处理应用程序的数据存储问题,以及如何使用它定义网络将多个容器连接在一起使用。
[1]
发布Docker镜像到阿里云容器仓库: https://www.bilibili.com/video/BV17T4y1u78y/
[2]
Youtube(需科学上网): https://youtu.be/tUqYgsi0Yn8
[3]
发布Docker镜像到Azure容器仓库: https://www.bilibili.com/video/BV1zt4y117tg/
[4]
Youtube(需科学上网): https://youtu.be/y_LUq2SKJMY