.NET8应用迁移后Kestrel在AKS环境无法启动求助
.NET 3.1迁移至.NET 8后AKS环境下Kestrel无法启动排查
将应用从.NET 3.1迁移到.NET 8后,本地开发机及Docker环境运行正常,但部署到托管Kubernetes服务(AKS)后,Kestrel始终无法启动。已在Appsettings.json中配置Kestrel,且AppSettings.Staging.json无相关覆盖配置,同时开启了全跟踪日志用于排查。
相关配置内容
Appsettings.json
{ "Logging": { "LogLevel": { "*": "Trace" } }, "Kestrel": { "EndPoints": { "Http": { "Url": "http://0.0.0.0:80" }, "gRPC": { "Url": "http://0.0.0.0:81", "Protocols": "Http2" } } }, "AllowedHosts": "*" }
Program.cs
public class Program{ public static readonly string Namespace = typeof(Startup).Namespace!; public static readonly string AppName = Namespace[(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1)..]; protected Program(){} public static async Task<int> Main(string[] args) { ILogger<Program> logger = null; try { var host = CreateWebHostBuilder(args).Build(); logger = host.Services.GetRequiredService<ILogger<Program>>(); logger.LogInformation("Starting web host ({ApplicationContext})...", Program.AppName); await host.RunAsync(); return 0; } catch (Exception ex) { logger?.LogError(ex, "Program terminated unexpectedly ({ApplicationContext})!", Program.AppName); return 1; } } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .CaptureStartupErrors(false) .UseStartup<Startup>() .ConfigureLogging((context, builder) => { builder.AddSerilog(); }); }
Startup.Configure方法
public void Configure( IApplicationBuilder app, IWebHostEnvironment env, IApiVersionDescriptionProvider provider, VeredasDbContext dbContext, IAuditInjector auditInjector) { app.UseCors(builder => { builder.AllowAnyOrigin(); builder.AllowAnyMethod(); builder.AllowAnyHeader(); builder.WithExposedHeaders("X-Authorization-Token"); }); app.UseWhen( context => !context.Request.Path.StartsWithSegments("/hc"), appBuilder => { appBuilder.UseApiLogMiddleware(); appBuilder.UseRenewableAuthTokenMiddleware(); }); if (!env.IsEnvironment("IntegrationTest")) { app.UseSwaggerConfig(provider, env); // Apply migration if necessary using var scope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope(); dbContext.ApplyMigrations(); auditInjector.Inject(dbContext).GetAwaiter().GetResult(); } app.UseStaticFiles(); app.UseRouting(); app.UseJwt(); app.ConfigureLocalization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapGrpcService<GrpcServices.ProcessService>(); endpoints.MapGrpcService<GrpcServices.FundService>(); if (!CurrentEnvironment.IsEnvironment("IntegrationTest")) { endpoints.MapHealthChecks("/hc", new HealthCheckOptions() { Predicate = _ => true, ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse, }); endpoints.MapHealthChecks("/readiness", new HealthCheckOptions { Predicate = r => r.Name.Contains("self"), }); } }); this.Logger.LogInformation("Done"); }
应用启动日志
info: MyApp.Api.Startup[0] Done dbug: Microsoft.EntityFrameworkCore.Infrastructure[10407] 'MyDbContext' disposed. dbug: Microsoft.EntityFrameworkCore.Database.Connection[20007] Disposing connection to database 'db_staging' on server ''. dbug: Microsoft.EntityFrameworkCore.Database.Connection[20008] Disposed connection to database 'db_staging' on server '' (0ms). warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60] Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed. info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[62] User profile is available. Using '/root/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.
问题现象
从日志可见,应用已执行到Configure方法末尾的"Done"日志,但始终未出现Kestrel正常启动时的监听日志:
Hosting environment: Staging Content root path: /app Now listening on: http://0.0.0.0:81 Now listening on: http://0.0.0.0:80
排查方向
- 检查AKS Pod资源限制:查看Pod的CPU/内存配额是否不足,导致Kestrel启动被阻塞。通过
kubectl describe pod <pod-name>查看资源使用和事件。 - 验证Kestrel配置加载:在
Program.Main中添加日志,输出Configuration.GetSection("Kestrel").Value,确认配置是否被正确读取。 - 排查端口占用:进入Pod内部执行
netstat -tulpn,检查80/81端口是否被其他进程占用。 - 修复同步调用异步代码:
Configure方法中auditInjector.Inject(dbContext).GetAwaiter().GetResult()属于同步阻塞异步操作,在.NET 8环境下可能引发死锁,建议改为异步启动流程(将Configure改为ConfigureAsync,并调整启动逻辑)。 - 检查Serilog过滤规则:确认Serilog未过滤Kestrel相关日志(
Microsoft.AspNetCore.Server.Kestrel),即使appsettings中设置了*:Trace,Serilog可能有单独的过滤器配置。 - 查看Pod终止事件:确认Pod是否被Kubernetes重启,比如OOMKilled(内存溢出)等情况,通过
kubectl get events或Pod描述信息查看。
内容的提问来源于stack exchange,提问作者Bruno Warmling
相关产品推荐
相关产品推荐

