Python 如何在系统退出时优雅地停止Kubernetes对服务的监视
我运行了以下KOPF后台程序:Python 如何在系统退出时优雅地停止Kubernetes对服务的监视,python,kubernetes,Python,Kubernetes,我运行了以下KOPF后台程序: import kopf import kubernetes @kopf.on.daemon(group='test.example.com', version='v1', plural='myclusters') def worker_services(namespace, name, spec, status, stopped, logger, **kwargs): config = kubernetes.client.Configuration()
import kopf
import kubernetes
@kopf.on.daemon(group='test.example.com', version='v1', plural='myclusters')
def worker_services(namespace, name, spec, status, stopped, logger, **kwargs):
config = kubernetes.client.Configuration()
client = kubernetes.client.ApiClient(config)
workload = kubernetes.client.CoreV1Api(client)
watch = kubernetes.watch.Watch()
while not stopped:
for e in watch.stream(workload.list_service_for_all_namespaces):
svc = e['object']
lb = helpers.get_service_loadbalancer(name, namespace, svc, logger)
if "NodePort" in svc.spec.type:
logger.info(f"Found Service of type NodePort: {svc.metadata.name}")
do_some_work(svc)
watch.stop()
当系统通过Ctrl+C
或Kubernetes杀死pod退出时,我得到以下警告:
INFO:kopf.reactor.running:Signal SIGINT is received. Operator is stopping.
[2020-12-11 15:07:52,107] kopf.reactor.running [INFO ] Signal SIGINT is received. Operator is stopping.
WARNING:kopf.objects:Daemon 'worker_services' did not exit in time. Leaving it orphaned.
[2020-12-11 15:07:52,113] kopf.objects [WARNING ] Daemon 'worker_services' did not exit in time. Leaving it orphaned.
这样即使我按了Ctrl+Z
,进程也会在后台运行
我相信for循环
会阻塞流中的进程,并且不会在系统退出时终止,因此它不会命中此代码段最后一行的watch.stop()
到目前为止,我已经尝试了以下方法:
- 在“做一些工作”(svc)之后添加一个
,但这会使我的程序进入一个非常激进的循环,消耗高达90%的CPUwatch.stop()
- 将整个
放在不同的线程上,这会导致一些组件出现故障,例如记录器for循环
- 实现了
以使进程无阻塞,这使得守护进程在其监视的第一个服务和监视结束后完成yield e
- 使用
库实现信号侦听器,侦听退出函数中的Signal
,然后SIGINT
,但从未调用该函数watch.stop()
- 使用上述一些解决方案实现了
,即取消\u超时=3.0
,但也没有成功@kopf.on.daemon(group='test.example.com',version='v1',plural='myclusters',取消\u超时=3.0)
任何输入都将不胜感激,提前感谢。我在您的示例中看到的是,代码试图监视集群中的资源。但是,它使用的是同步的官方客户端库。与异步(也需要使用异步i/o)不同,Python中不能中断同步函数(或线程)。一旦调用了此处显示的函数,它就不会退出,也不会在长时间运行期间检查stopped标志 对于当前代码,您可以更频繁地检查
stopped
标志:
@kopf.on.daemon(group='test.example.com',version='v1',复数='myclusters')
def worker_服务(名称空间、名称、规格、状态、已停止、记录器、**kwargs):
…
watch=kubernetes.watch.watch()
对于watch.stream中的e(工作负载。列出所有名称空间的服务):
如果停止:#非常好的输入,谢谢@sergey vasilyev。将为活动提供尝试和反馈。