【发布时间】:2020-12-14 03:52:13
【问题描述】:
我正在运行以下 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()
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 loop 正在通过流阻止进程并且在系统退出时不会终止,因此它没有在此 sn-p 的最后一行命中watch.stop()。
到目前为止,我已经尝试了以下方法:
- 在
do_some_work(svc)之后添加watch.stop(),但这会使我的程序进入一个非常激进的循环,最多消耗我 90% 的 CPU - 将整个
for loop放在不同的线程上,这会导致某些组件失败,例如记录器 - 实现了
yield e以使进程非阻塞,这使得守护进程在它观察到的第一个服务和观察结束后完成 - 使用
signal库实现的信号监听器在退出函数中监听SIGINT和watch.stop(),但该函数从未被调用 - 使用上述一些解决方案实现了
cancellation_timeout=3.0,即@kopf.on.daemon(group='test.example.com', version='v1', plural='myclusters', cancellation_timeout=3.0),但也没有成功
任何意见将不胜感激,在此先感谢。
【问题讨论】:
标签: python kubernetes