.NET Core / Kubernetes-SIGTERM,干净关闭

时间:2019-05-18 09:26:14

标签: kubernetes .net-core

我正在尝试使用.NET Core 2.0应用程序验证Kubernetes上的关闭操作是否正常完成。

我有一个可以在两种“模式”下运行的应用程序-一种使用ASP.NET Core,另一种作为一种工作进程。两者都使用Console和JSON(通过Filebeat-sidecar-container记录器输出结束在Elasticsearch中的输出),指示启动和关闭进度。

此外,我有控制台输出,当收到SIGTERM或Ctrl-C并开始关闭时,该输出直接写到stdout。

在本地,该应用程序可以完美运行-我得到直接的控制台输出,然后记录器输出流到Ctrl + C(在Windows上)的stdout。

我的实验场景:

  • 已将应用程序部署到GCS k8s集群(使用helm,尽管我认为这没什么用)
  • 使用kubectl logs -f从特定容器中流式传输日志
  • 从GCS云控制台站点杀死Pod,或通过helm delete删除资源
  • Dockerfile是FROM microsoft/dotnet:2.1-aspnetcore-runtime,具有ENTRYPOINT ["dotnet", "MyAppHere.dll"],因此请不要将其包装在bash进程中或其他任何内容中
  • 未指定terminationGracePeriodSeconds,因此猜测它默认为30秒
  • 观察到的输出返回

结果:

  • API pod日志流仅显示立即的控制台输出,“ [SIGTERM]停止信号已收到”,而不是其他有关关闭过程的控制台记录器输出
  • 工作人员Pod日志流显示了更多内容-相同的控制台输出和一些有关关闭过程的控制台记录器输出
  • JSON日志似乎没有选择任何关闭日志输出

我的结论:

  1. 我不知道Kubernetes是否允许该过程在终止之前完成,还是只是发布SIGTERM然后很快就杀死了它。我认为应该等待,但是为什么没有完整的控制台记录器输出?
  2. 我不知道在进程最终终止之前的某个时间点输出stdout日志时,控制台输出是否被切断了?
  3. 我猜想JSON内容不会传递给ES,因为即使在要发送的文件中有未完成的内容,在sidecar中运行的filebeat也会终止

我想知道:

  • 有人可以就上述第1,2点提出建议吗?
  • 有什么想法可以让边车有一些额外的时间或余地来发送东西,例如吊舱容器终止命令,该容器的关闭延迟等?

3 个答案:

答案 0 :(得分:1)

我已经开始出于个人目的对此进行研究,并且在问题发布后的一年中遇到了您的问题……这有点晚了,但是您是否尝试过GraceTerm? 为此有一个关联的NuGET package

从描述中...

  

Graceterm中间件提供了实现,以确保正常关闭AspNet Core应用程序。基本概念是:应用程序收到SIGTERM(要求其终止的信号)后,Graceterm会将其保持活动状态,直到所有待处理的请求完成或发生超时。

我还没有亲自尝试过,但是看起来确实很有希望。

答案 1 :(得分:1)

尝试将STOPSIGNAL SIGINT添加到您的Dockerfile

答案 2 :(得分:0)

SIGTERM实际上确实表示终止。不太明显的部分是,当SIGTERM处理程序返回时,一切都视为完成。

解决方法是在应用程序关闭之前,不要从SIGTERM处理程序中返回。例如,在处理程序中使用ManualResetEventWait()对其进行编辑。