在Kubernetes中实现ASP.NET Core 6优雅关闭

jrcvhitl  于 2023-08-03  发布在  Kubernetes
关注(0)|答案(1)|浏览(126)

我需要为我的容器(ASP.NETCore6,在AlpineLinux上运行)实现GracefulShutdown。我已经添加了下面的代码。当我运行容器时,它会显示以下日志消息。

LifetimeEventsHostedService has been called.
StartAsync has been called.
OnStarted has been called.

字符串
但是,当我发送“kubectl delete pod my-pod-xyz -n mynamespace"”或重新启动容器时,现有的pod将被终止并启动一个新的pod。但容器日志消息中不显示任何内容。
我希望看到已添加到OnStoping方法中的日志消息“OnStoping已被调用”。但什么也没发生。
可能是什么错误?当我重新启动或发送删除pod命令时,如何确保我的代码正常工作?

程序.cs

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
                webBuilder.ConfigureKestrel(options =>
                {
                    options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(60);
                });
            }).ConfigureServices(services =>
            {
                services.AddHostedService<LifetimeEventsHostedService>();
                services.Configure<HostOptions>(option =>
                {
                    option.ShutdownTimeout = TimeSpan.FromSeconds(15);
                });
            });
}

终身活动主机服务.cs

internal class LifetimeEventsHostedService : IHostedService
{
    private readonly ILogger<LifetimeEventsHostedService> _logger;
    private readonly IHostApplicationLifetime _appLifetime;

    public LifetimeEventsHostedService(
        ILogger<LifetimeEventsHostedService> logger,
        IHostApplicationLifetime appLifetime)
    {
        _logger = logger;
        _appLifetime = appLifetime;
        _logger.LogInformation("LifetimeEventsHostedService has been called.");
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("StartAsync has been called.");
        _appLifetime.ApplicationStarted.Register(OnStarted);
        _appLifetime.ApplicationStopping.Register(OnStopping);
        _appLifetime.ApplicationStopped.Register(OnStopped);

        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("StopAsync has been called.");
        return Task.CompletedTask;
    }

    private void OnStarted()
    {
        _logger.LogInformation("OnStarted has been called.");
    }

    private void OnStopping()
    {
        _logger.LogInformation("OnStopping has been called.");

        _logger.LogInformation("SIGTERM received, waiting for 30 seconds");
        Thread.Sleep(30000);
        _logger.LogInformation("Termination delay complete, continuing stopping process");
    }

    private void OnStopped()
    {
        _logger.LogInformation("OnStopped has been called.");
    }
}

vwoqyblh

vwoqyblh1#

在Kubernetes部署中,您可以使用preStop钩子来优雅地处理pod终止。这允许pod在终止之前完成任何正在进行的请求。要使用preStop钩子,需要将以下配置添加到部署YAML中:

containers:
  - name: your-container-name
    image: your-image:tag
    imagePullPolicy: IfNotPresent
    lifecycle:
      preStop:
        exec:
          command:
          - sh
          - -c
          - sleep 30

字符串
preStop钩子将确保pod在Kubernetes启动终止过程之前有30秒的时间来完成任何正在进行的请求。这有助于优雅地处理pod关闭,防止对正在进行的任务的任何中断。
预先申请:你的docker应该有sh或bash来执行命令并相应地修改命令。

相关问题