Как извлечь изображение из частного реестра Docker в KubernetesPodOperator облачного композитора Google?

#kubernetes #airflow #google-cloud-composer

#kubernetes #поток воздуха #google-cloud-composer

Вопрос:

Я пытаюсь запустить задачу в среде, созданной на основе изображения в частном реестре контейнеров Google, через KubernetesPodOperator облачного композитора Google. Экземпляры реестра контейнеров и Cloud Composer находятся в рамках одного проекта. Мой код приведен ниже.

 import datetime
import airflow
from airflow.contrib.operators import kubernetes_pod_operator


YESTERDAY = datetime.datetime.now() - datetime.timedelta(days=1)


# Create Airflow DAG the the pipeline
with airflow.DAG(
        'my_dag',
        schedule_interval=datetime.timedelta(days=1),
        start_date=YESTERDAY) as dag:

    my_task = kubernetes_pod_operator.KubernetesPodOperator(
        task_id='my_task',
        name='my_task',
        cmds=['echo 0'],
        namespace='default',
        image=f'gcr.io/<my_private_repository>/<my_image>:latest')
  

Задача завершается с ошибкой, и я получаю следующее сообщение об ошибке в журналах в пользовательском интерфейсе Airflow и в logs папке в хранилище.

 [2020-09-21 08:39:12,675] {taskinstance.py:1147} ERROR - Pod Launching failed: Pod returned a failure: failed
Traceback (most recent call last)
  File "/usr/local/lib/airflow/airflow/contrib/operators/kubernetes_pod_operator.py", line 260, in execut
    'Pod returned a failure: {state}'.format(state=final_state
airflow.exceptions.AirflowException: Pod returned a failure: failed
  

Это не очень информативно…
Есть идеи, что я могу делать неправильно?
Или где-нибудь я могу найти более информативные сообщения журнала?

Большое вам спасибо!

Комментарии:

1. Как вы знаете, ошибка, которую вы указали, не дает много информации о фактическом сбое. Я мог бы предположить и сказать cmds=['echo', '0'] , что, возможно, стоит попробовать. Если это не сработает, вы можете попробовать вызвать pod напрямую через интерфейс Python или модули или напрямую через Kubernetes, прочитать вывод оттуда и поделиться текстом ошибки из этой работы в этом чате, как только он у вас будет

Ответ №1:

В общем, способ, которым мы начинаем устранение неполадок GCP Composer после получения сбоя при запуске DAG, подробно объясняется в специальной главе документации GCP.

Переход к KubernetesPodOperator конкретно связан с проблемами, которые могут возникнуть при расследовании определенных пользователей:

Далее анализируя контекст ошибки и KubernetesPodOperator.py исходный код, я предполагаю, что эта проблема может возникнуть из-за проблемы с запуском Pod на узле GKE Airflow worker, что приводит к Pod returned a failure: {state}'.format(state=final_state) появлению сообщения после неудачного выполнения Pod.

Лично я предпочитаю проверять запуск образа перед выполнением задачи Airflow в модуле Kubernetes. Сказав это и основываясь на предоставленной команде task, я полагаю, что вы можете проверить процесс запуска Pod, подключения к кластеру GKE и переопределения kubernetes_pod_operator.KubernetesPodOperator определения, приемлемого для kubectl исполнителя командной строки:

 kubectl run test-app --image=eu.gcr.io/<Project_ID>/image --command -- "/bin/sh" "-c" "echo 0"
  

Это упростит процесс проверки изображения, следовательно, вы сможете более подробно ознакомиться с журналами Pod или записями событий:

 kubectl describe po test-app
  

Или

 kubectl logs test-app
  

Ответ №2:

Если вы хотите извлечь или вставить изображение KubernetesPodOperator из частного реестра, вы должны создать секрет в k8s, который содержит учетную запись службы (SA). У этого SA должно быть разрешение на извлечение или, возможно, выталкивание изображений (разрешение RO / RW).

Затем просто используйте этот секрет с SA в KubernetesPodOperator и укажите image_pull_secrets аргумент:

 my_task = kubernetes_pod_operator.KubernetesPodOperator(
    task_id='my_task',
    name='my_task',
    cmds=['echo 0'],
    namespace='default',
    image=f'gcr.io/<my_private_repository>/<my_image>:latest',
    image_pull_secrets='your_secret_name')