如何使用 dotnet 核心应用程序终止 docker 容器

How to terminate docker container with dotnet core application

我有一个 dotnet Core 3.1 应用程序,在 Program.cs

中创建了以下主机
     public static async Task Main(string[] args)
    {
        var configuration = ConfigurationFactory.CreateConfiguration();
        var appName = configuration.GetAppName();
        Log.Logger = configuration.CreateSerilogLogger();
        try
        {
            Log.Information("Configuring console host ({ApplicationContext})...", appName);

            var host = Host.CreateDefaultBuilder(args)
                .UseConsoleLifetime(opts => opts.SuppressStatusMessages = true)
                .ConfigureServices((hostContext, services) =>
                {
                    services
                    .AddHostedService<EventRehydratorService>()
                }).Build();


            Log.Information("Starting console host ({ApplicationContext})...", appName);
            await host.StartAsync();
            await host.StopAsync();

        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", appName);
            Environment.Exit(-1);
        }
        finally
        {
            Log.CloseAndFlush();  
        }
        Environment.Exit(1);
    }

EventRehydatorService 实现 IHostedService

 internal class EventRehydratorService : IHostedService
{
    private readonly IHostApplicationLifetime appLifetime;
    private readonly IConfiguration configuration;

    public IEventSourceService EventSourceService { get; }
    public IDocumentStore Store { get; }

    public EventRehydratorService(
        IHostApplicationLifetime appLifetime,
        IEventSourceService eventSourceService,
        IDocumentStore store,
        IConfiguration configuration)
    {
        this.appLifetime = appLifetime;
        EventSourceService = eventSourceService;
        Store = store;
        this.configuration = configuration;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        appLifetime.ApplicationStopping.Register(OnStopping);
        appLifetime.ApplicationStopped.Register(OnStopped);        

        return Task.CompletedTask;
    }

    private void OnStopping()
    {
        Log.Information("OnStopping has been called.");
    }

    private void OnStopped()
    {
        Log.Information("OnStopped has been called.");
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        appLifetime.StopApplication();
        return Task.CompletedTask;

    }
}

}

Docker 文件:

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["Shophattan.EventRehydrator/EventRehydrator.csproj", "Shophattan.EventRehydrator/"]
COPY ["Common/Shophattan.Common/Shophattan.Common.csproj", "Common/Shophattan.Common/"]
COPY ["RavenDB.DependencyInjection/RavenDB.DependencyInjection.csproj", "RavenDB.DependencyInjection/"]
RUN dotnet restore "Shophattan.EventRehydrator/EventRehydrator.csproj"
COPY . .
WORKDIR "/src/Shophattan.EventRehydrator"
RUN dotnet build "EventRehydrator.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "EventRehydrator.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "EventRehydrator.dll"]

调用了所有事件,但容器仍然存在 运行。这是 Kubernetes CronJob 的一个问题,因为作业永远不会完成。我试图终止当前进程,在 OnStopped 方法中抛出异常 Environment.Exit() 但 docker 从未完成。不确定我做错了什么?

想通了 - 简单到以零退出。出于某种原因,我认为它应该是一个正数。

Environment.Exit(0); 

现在作业成功完成:

NAME                             COMPLETIONS   DURATION   AGE
dev-eventrehydrator-1586018400   1/1           3s         15m