python - Kubernetes Python Client Watch 停止返回结果,不会失败

标签 python kubernetes google-kubernetes-engine

使用适用于 Kubernetes 的 Python 客户端,我创建了一个小型服务来监视新 Pod 并将数据发送到外部服务,以进行指标收集。我发现它完全有效,但几天后 watch 似乎停止接收新的变化。它不报告任何错误或抛出任何异常;它只是表现得好像没有更多的变化。如果我启动一个新的 watch ,我可以看到新的变化,如果我重新启动容器,进程会继续,但似乎我不能让一个进程连续运行。

我在 GKE 上运行,我想知道 Kubernetes API 端点是否不可用。但我想要的只是在它再次可用时恢复。在这种情况下,我对 pods 崩溃并不得不重新启动感到满意,但我根本没有收到 Watch 的任何报告,因此我无法尝试处理任何情况。

这是我的代码的相关部分:

def main():
    log = app.logger.get()
    kube_api = get_kubernetes_config()

    resource_version = get_resource_version(kube_api)

    watch_params = {
        'resource_version': resource_version
    }

    log.debug(f'Watching from resource version {resource_version}')
    w = watch.Watch()

    stream = w.stream(kube_api.list_pod_for_all_namespaces, **watch_params)
    log.info('Started watching for new pods')

    for message in stream:
        process_pod_change(message['object'], log)

def process_pod_change(pod, log):
    if not pod.metadata.deletion_timestamp is None or pod.status.container_statuses is None or not all(status.ready for status in pod.status.container_statuses):
        return
    pod_name = f'{pod.metadata.namespace}/{pod.metadata.name}'
    for status in pod.status.container_statuses:
        docker_image_sha = status.image_id.split('@')[-1]
        report_deployment(docker_image_sha, pod_name, status.name, log)
    with open(RESOURCE_VERSION_FILE, 'w') as f:
        f.write(str(pod.metadata.resource_version))

def report_deployment(sha, pod_name, container_name, log):
    log.info(f'Seen new deployment of {pod_name} container {container_name}: {sha}')
    authorised_session = app.auth.get_authorised_session()
    jsonbody = {
        'artefact_type': 'docker',
        'artefact_id': sha,
        'client': os.environ['CLIENT'],
        'environment': os.environ['ENVIRONMENT'],
        'product': os.environ['PRODUCT']
    }
    r = authorised_session.post(os.environ['NOTIFICATION_URL'], json=jsonbody)
    r.raise_for_status()

结果日志显示处理过的消息的连续流,直到它们停止进入。日志中没有任何奇怪的迹象发生。我也相信这与 Kubernetes Watch 相关,而不是我正在做的任何下游处理,因为这是我编写的第二个应用程序,它展示了 Watch 似乎睡着了,什么也不做的这种行为。

我使用这个正确吗?我在网上找不到很多例子,似乎没有其他人有这个问题,所以我没有看到任何解决方法。

我的集群版本是 1.14.10-gke.27,我使用的是 Python 3.6-alpine 容器,我的 Python 依赖项只是过去几周的。但是六个月前我在另一次尝试使用 Watch 时也看到了同样的问题。

最佳答案

你可以引用这个链接:https://medium.com/programming-kubernetes/building-stuff-with-the-kubernetes-api-part-3-using-python-aea5ab16f627
它谈到设置 timeout_seconds=0 以避免超时。这可能会解决您的问题。

   for item in w.stream(kube_api.list_pod_for_all_namespaces,
                         **watch_params, timeout_seconds=0):

关于python - Kubernetes Python Client Watch 停止返回结果,不会失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61611261/

相关文章:

docker - 命令 gcloud docker -a 的作用是什么?

python - Sympy,求包含复数的无限级数/总和的总和

python - pypy 的 dict 线程安全吗?

kubernetes - Pod 相对于容器的优势

kubernetes - Airflow 无法将日志写入 s3 (v1.10.9)

ssl - 确保 Kubernetes Engine 证书的兼容性

kubernetes - 如何在 kubernetes GCE 上启用 https tls

python - 如何使用numpy调整图像数据的大小?

python - pyqt5 我保存图像但它总是空的

kubernetes - 未执行Openshift准备就绪探针