python - Kubernetes Python Client Watch 停止返回结果,不会失败
问题描述
使用 Kubernetes 的 Python 客户端,我创建了一个小型服务来监视新 Pod 并将数据发送到外部服务,以收集指标。我发现它完全可以工作,但几天后手表似乎停止接收新的变化。它不报告任何错误或抛出任何异常;它只是表现得好像没有更多的变化。如果我开始一个新的手表,我可以看到新的变化,如果我重新启动容器,进程会恢复,但似乎我不能让一个进程连续运行。
我在 GKE 上运行,我想知道 Kubernetes API 端点是否不可用。但我只想在它再次可用时恢复。在这种情况下,我对吊舱崩溃并不得不重新启动感到满意,但我根本没有收到来自 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 时也看到了同样的问题。
解决方案
它谈到设置 timeout_seconds=0 以避免超时。这可能会解决您的问题。
for item in w.stream(kube_api.list_pod_for_all_namespaces,
**watch_params, timeout_seconds=0):
推荐阅读
- python - 空切片算子查询
- python - 带有for循环的dict理解中的“未正确调用DataFrame构造函数”
- django - Django 按最旧或最新的下拉菜单排序
- typescript - 在 jasmine 中调用 http get 并没有超时
- python - 如何使用 Robot Framework 将 URL 的一部分保存为变量
- ionic-framework - Ionic 4 不是异步警报
- r - R ggplot2 将今天的日期添加到标题
- javascript - 有人可以解释一下 Javascript 中 replace() 方法的这种特殊用法吗?
- python - 模拟两个六面骰子滚动1000次并将总和值存储在文件中的python程序
- flutter - 如何在颤动折线图 X 轴中添加字符串范围?