乘风破浪,遇见最佳跨平台跨终端框架.Net Core/.Net生态 - 再谈.Net Core添加Docker支持
背景
很多话题都值得过一段时间再拿出来说说,因为整个.Net生态和社区都在飞速前进,也许你以前知道的,放到如今已经不适用了,需要与时俱进。
这篇重温下给.Net Core项目添加Docker支持并部署运行。
背景:
- Visual Studio 2022已经成为主流了。
- .Net 6 LTS已经成为主流了。
- Docker && K8S已经成为主流了。
什么是Docker
Docker是一种开源项目,用于将应用程序自动部署为可在云或本地运行的便携式独立容器。Docker也是一家公司,它与云、Linux和Windows供应商(包括Microsoft)协作,致力于推广和发展这项技术。
Docker在混合云的所有层部署容器
开发人员可以在Windows、Linux或macOS上使用开发环境。在开发计算机上,开发人员运行部署了Docker映像(包括应用及其依赖项)的Docker主机。在Linux或Mac上进行开发的开发人员使用基于Linux的Docker主机,并且他们可以仅为Linux容器创建映像。在Windows上进行开发的开发人员可以为Linux或Windows容器创建映像。
为了在开发环境中承载容器,并提供其他开发人员工具,Docker为Windows或macOS提供了Docker Desktop。这些产品安装了承载容器所需的VM(Docker主机)。
比较传统虚拟机与Docker容器
对于VM,主机服务器中有三个基本层。从下到上依次为:基础结构、主机操作系统和虚拟机监控程序。毕竟,每个VM都有自己的操作系统和所有必需的库。另一方面,对于Docker,主机服务器仅具有基础结构和操作系统。在此基础上,容器引擎会使容器保持隔离,但允许它们共享单个基本操作系统的服务。
由于容器所需的资源要少得多(例如,它们不需要一个完整的OS),所以它们易于部署且可快速启动。这使你能够具有更高的密度,也就是说,这允许你在同一硬件单元上运行更多服务,从而降低了成本。
在同一内核上运行的副作用是,你获得的隔离比VM要少。
映像的主要目标是确保在不同部署的同一环境(依赖项)。也就是说,可以在计算机上调试它,然后将其部署到保证具有相同环境的另一台计算机上。
借助容器映像,可打包应用或服务并采用可靠且可重现的方式对其进行部署。可以说Docker不只是一种技术,还是一种原理和过程。
在使用Docker时,你不会听到开发人员说:“为什么它能在我的计算机上使用却不能用在生产中?”他们只需说“它在Docker上运行”,因为打包的Docker应用程序可在任何支持的Docker环境上执行,而且它在所有部署目标(例如开发、QA、暂存和生产)上都按预期运行。
基础实战
创建解决方案和项目
通过Visual Studio 2022创建新项目,选择C#
语言-Windows
平台-WebAPI
类型,找到ASP.NET Core Web API
项目模板。
创建名为HelloNetCoreApi
的解决方案和项目。
其他信息版块,框架选.Net 6.0(长期支持)
、勾选配置HTTPS
、勾选启用Docker
,选择Docker OS为Linux
,默认勾选使用控制器
、勾选启用OpenAPI
,然后点击创建即可。
创建成功。
创建Docker镜像
创建项目的时候,我们勾选了启用Docker
,所以项目根目录下会多出一个Dockerfile
的文件(无后缀格式),其内容是:
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["HelloNetCoreApi/HelloNetCoreApi.csproj", "HelloNetCoreApi/"]
RUN dotnet restore "HelloNetCoreApi/HelloNetCoreApi.csproj"
COPY . .
WORKDIR "/src/HelloNetCoreApi"
RUN dotnet build "HelloNetCoreApi.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "HelloNetCoreApi.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "HelloNetCoreApi.dll"]
我们通过Windows Terminal切换到解决方案的目录,输入如下命令来生成镜像:
docker build -t hellonetcoreapi:1.0.0 -f .\HelloNetCoreApi\Dockerfile .
注意,这里-t
即--tag
后面跟这个镜像的名字,一般需要全小写英文 + :
+ 标记值,这里虽然可以省去Tag值,但是建议养成好奇怪,不要省;这里-f
即--file
后面跟Dockerfile这个文件的相对路径,最后一个.
指代当前目录。
不出意外,这个镜像就构建成功了,我们可以通过命令来查看。
docker images
运行Docker镜像
有了上面的Docker镜像之后,我们可以来运行它。
docker run --name=sunnycontainer -p 5000:80 -d hellonetcoreapi:1.0.0
上诉命令是指,--name
用来指定创建后的容器名称;-p
即--port
是容器外部和内部映射端口,一般是外部端口在前,中间用:
相隔,紧接内部端口在后;-d
代表后台运行容器,并返回容器ID;
-d
后台运行的好处就是,断开之后,它还会持续运行,但是不会重启自动运行。
docker run --name=snowcontainer -p 5010:80 -it hellonetcoreapi:1.0.0 /bin/bash
上诉命令是指,--name
用来指定创建后的容器名称;-p
即--port
是容器外部和内部映射端口,一般是外部端口在前,中间用:
相隔,紧接内部端口在后;-i
代表以交互模式运行容器、-t
代表为容器重新分配一个伪输入终端,这两者一般一起使用。
-it
前台运行的好处就是,运行后直接在当前上下文输出。但是退出后容器也会跟着关闭,适用于临时需求。
从Docker for Windows客户端中也可以看到这两个容器实例。
通过命令可以查询已运行的容器实例:
docker ps -a
通过命令可以查看容器实例IP信息:
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' snowcontainer
通过命令可以查看容器实例的输出:
docker logs snowcontainer
通过命令可以进入到容器实例内部:
docker exec -it snowcontainer /bin/bash
访问容器中服务
以sunnycontainer
容器为例,在创建容器实例的时候,我们将外部端口5000
映射给了它内部的80
端口,那么我们就可以通过:
来访问。
实际结果可能会令你震惊,别慌。这只是因为路径不对。对于默认项目模板来说,预设的Api路径是/WeatherForecast
你可能发现了,命名代码中有Swagger
的影子,为什么无法访问。
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
从代码可以看出,是因为没有定义环境变量,环境变量我们可以通过Docker创建命令进行设置:
docker run --name=sunnycontainer -p 5000:80 -d -e ASPNETCORE_ENVIRONMENT=Development hellonetcoreapi:1.0.0
这时候就可以顺利访问Swagger
了
参考
- 如何在Visual Studio中自定义Docker容器
- dotnet/dotnet-docker
- ASP.NET Core的Docker映像
- 教程:使.NET应用容器化
- 了解Docker
- Docker build命令
- Docker logs命令
- Docker run命令
- Docker exec命令
- Docker 命令大全
- 三步实现.NET6部署到Docker
- 六、.net core (.NET 6)程序部署到Docker上
- 使用.NET 6开发TodoList应用(30)——实现Docker打包和部署
- Use Visual Studio 2022 Create .net core 6.0 web api,Can't access api on docker
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步