.NET Core 3.1 WebAPI容器化后无法访问,需确认配置修改要求
一、清理冗余的端口监听配置
.NET Core 端口配置优先级为:命令行参数 > 环境变量 > appsettings.json > launchsettings.json,你目前在多处重复配置端口容易引发冲突,按以下规则清理即可:
- 删掉
appsettings.json里的Kestrel监听节点配置 - 删掉
launchsettings.json文件,该文件仅用于本地开发调试,发布后不会生效,无需打包到镜像 - 删掉Dockerfile ENTRYPOINT指令后的
--server.urls参数,仅保留ENV层的ASPNETCORE_URLS=http://0.0.0.0:80配置即可 - 删掉
web.config文件,该文件是IIS托管场景专用,容器内用Kestrel托管完全不依赖该文件的配置
二、修复日志无法输出的问题
你当前Program.cs里的日志配置清空了所有输出提供器,所以不会生成任何日志:
// 现有代码清空了所有日志输出通道 logging.ClearProviders();
修改日志配置添加控制台输出,容器环境默认会采集控制台日志,无需单独写文件:
.ConfigureLogging(logging => { logging.ClearProviders(); // 新增以下两行开启控制台日志输出 logging.AddConsole(); logging.AddDebug(); logging.SetMinimumLevel(LogLevel.Trace); })
修改后重新打包镜像,即可通过kubectl logs <POD名称>直接查看应用启动日志,确认是否存在启动报错。
三、解决404访问错误
从你本地curl的返回结果可以确认Kestrel服务已经正常启动,404是路由匹配问题导致的:
3.1 验证基础路由是否正常
先在POD内直接请求不带前缀的swagger地址验证服务可用性:
curl http://localhost:80/swagger/index.html
如果该地址可以正常返回,说明你对外访问的https://<host.company.com>/app/swagger/index.html多了/app路径前缀,需要在Startup.cs的Configure方法最开头添加全局路径前缀配置:
app.UsePathBase("/app");
3.2 检查Swagger启用条件
.NET Core 3.1默认项目模板的Swagger仅在开发环境启用,确认Startup.cs里的Swagger配置是否被环境判断包裹:
// 仅开发环境启用Swagger的默认配置 if (env.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); }
如果需要非开发环境也能访问Swagger,把这两行代码移到if判断外部即可。
3.3 HTTPS访问报错说明
你请求https://localhost:80报错是正常现象,你当前仅配置了80端口的HTTP监听,没有配置HTTPS证书,无法在80端口响应HTTPS请求。如果需要HTTPS访问,建议由上层Ingress/网关统一做HTTPS卸载,转发到容器的80 HTTP端口即可。
四、Dockerfile优化建议
你当前是本地发布后拷贝二进制到镜像,容易出现本地SDK版本和镜像运行时版本不一致的问题,推荐使用多阶段构建:
# 构建阶段 FROM mcr.microsoft.com/dotnet/sdk:3.1-nanoserver-1809 AS build WORKDIR /src COPY . . RUN dotnet publish "app.WebApi/app.WebApi.csproj" -c Release -o /app/publish # 运行阶段 FROM mcr.microsoft.com/dotnet/aspnet:3.1-nanoserver-1809 AS base WORKDIR /app ENV ASPNETCORE_ENVIRONMENT=Development ENV DOTNET_RUNNING_IN_CONTAINER=true ENV ASPNETCORE_URLS=http://0.0.0.0:80 EXPOSE 80 COPY --from=build /app/publish . ENTRYPOINT ["dotnet", "app.WebApi.dll"]
内容的提问来源于stack exchange,提问作者Muralidharan

