kubernetes 我无法从我的.net core consol应用程序处理kubernets的应用程序生命周期事件

v6ylcynt  于 2023-05-16  发布在  Kubernetes
关注(0)|答案(1)|浏览(138)

我正在尝试在我的应用程序上处理kuberenetes的prestop事件,但是我在我的.net core控制台应用程序上没有收到任何事件

lifecycle:
      postStart:
        tcpSocket:
          port: 13000
      preStop:
        tcpSocket:
          port: 13001

我正在接收事件日志
FailedPreStopHook pod/podname-795764 db 56 - 9 q9 pg无法运行处理程序:无效处理程序:&LifecycleHandler{Exec:nil,HTTPGet:nil,TCPSocket:&TCPSocketAction{Port:{0 13001 },Host:,},}
我已经尝试了另一种解决方案来开始使用本机函数,如

[DllImport("Kernel32")]
        private static extern bool SetConsoleCtrlHandler(SetConsoleCtrlEventHandler handler, bool add);

但我只能在Windows环境下运行它,但一旦我去Linux容器我收到错误
未处理的异常。System.DllNotFoundException:无法加载共享库“Tagged”或它的某一个依赖项。为了帮助诊断加载问题,请考虑设置LD_DEBUG环境变量:libKernel32:无法打开共享对象文件:没有这样的文件或目录
请建议是否有任何其他解决方案,这个问题,以处理关闭greacefully为consol应用程序在linux contaner环境。

nszi6y05

nszi6y051#

ConsoleCtrlEventHandler仅在Windows下可用。您应该在Linux容器和Windows下使用System.Runtime.InteropServices.PosixSignalRegistration

var isCancelRequested = false;
var signal = "none";
using (var protectSIGINTfromGC = PosixSignalRegistration.Create(PosixSignal.SIGINT, (signalContext) =>
{
    signal = "SIGINT";
    signalContext.Cancel = true;
    isCancelRequested = true;
}))
{
    /* Inovke your Root command handler here */
}

您必须保护事件处理程序不被垃圾收集器收集,请参阅this Answer
PosixSignalRegistration是在.NET Core 6.0中引入的。
对于旧版本,AppDomain.CurrentDomain.ProcessExit可用,并在SIGTERM上引发,Console.CancelKeyPressSIGINT上引发。
PosixSignalRegistration可以取消SIGTERM,这样您就可以在事件处理程序外 * 清理了。使用ProcessExit,您必须清理事件处理程序内部:

static void Main(string[] args)
{
    Console.WriteLine();
    Console.WriteLine($"Process ID = {Environment.ProcessId}");
    var cancel = false;
    Console.CancelKeyPress += new ConsoleCancelEventHandler((s, e) =>
    {
        Console.WriteLine($"CancelKeyPress");
        e.Cancel = true; // not terminate immediately
        cancel = true;
    });
    AppDomain.CurrentDomain.ProcessExit += new EventHandler((s, e) =>
    {
        Console.WriteLine($"ProcessExit");
        Console.WriteLine($"Process {Environment.ProcessId} exited gracefully (SIGTERM).");
    });
    do
    {
        Thread.Sleep(10);
    } while (!cancel);
    Console.WriteLine($"Process {Environment.ProcessId} exited gracefully (SIGINT).");
}

结果:

$ dotnet run &
Process ID = 4113
$ kill -s INT 4113
CancelKeyPress
Process 4113 exited gracefully (SIGINT).
$ dotnet run &
Process ID = 4395
$ kill -s TERM 4395
ProcessExit
Process 4395 exited gracefully (SIGTERM).

相关问题