Kubernetes Python Client Watch перестает возвращать результаты, не дает сбоев - PullRequest
1 голос
/ 05 мая 2020

Используя клиент Python для Kubernetes, я создал небольшую службу для отслеживания новых модулей и отправки данных во внешнюю службу для сбора метрик. Я считаю, что он работает полностью, но через несколько дней часы перестают получать новые изменения. Он не сообщает об ошибках и не генерирует исключения; он просто действует так, как будто изменений больше нет. Я вижу, что новые изменения поступают, если я запускаю новые часы, и процесс возобновляется, если я перезапускаю контейнер, но кажется, что у меня не может быть одного процесса, работающего постоянно.

Я работаю на 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 относятся только к прошлой паре недель. Но я также видел ту же проблему в течение шести месяцев go при другой попытке использовать Watch.

...