Airflow 从私有 google 容器存储库中拉取 docker 图像

Airflow pull docker image from private google container repository

我正在使用 https://github.com/puckel/docker-airflow 图像来 运行 Airflow。我必须添加 pip install docker 才能支持 DockerOperator。

一切似乎都很好,但我不知道如何从私有 google docker 容器存储库中提取图像。

我尝试在 google 云连接的管理部分类型中添加连接,并 运行 将 docker 运算符设置为。

    t2 = DockerOperator(
            task_id='docker_command',
            image='eu.gcr.io/project/image',
            api_version='2.3',
            auto_remove=True,
            command="/bin/sleep 30",
            docker_url="unix://var/run/docker.sock",
            network_mode="bridge",
            docker_conn_id="google_con"
    )

但是总是报错...

[2019-11-05 14:12:51,162] {{taskinstance.py:1047}} ERROR - No Docker registry URL provided

我也试过docker_conf_option

    t2 = DockerOperator(
            task_id='docker_command',
            image='eu.gcr.io/project/image',
            api_version='2.3',
            auto_remove=True,
            command="/bin/sleep 30",
            docker_url="unix://var/run/docker.sock",
            network_mode="bridge",
            dockercfg_path="/usr/local/airflow/config.json",

    )

我收到以下错误:

[2019-11-06 13:59:40,522] {{docker_operator.py:194}} INFO - Starting docker container from image eu.gcr.io/project/image [2019-11-06 13:59:40,524] {{taskinstance.py:1047}} ERROR - ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))

我也试过只使用 dockercfg_path="config.json" 并得到了同样的错误。

我真的无法使用 Bash 运算符尝试 docker 登录,因为它无法识别 docker 命令...

我错过了什么?

line 1: docker: command not found

t3 = BashOperator(
                task_id='print_hello',
                bash_command='docker login -u _json_key - p /usr/local/airflow/config.json eu.gcr.io'
        )

您需要在包含 gcloud 命令行工具的工作站中安装 Cloud SDK

安装 Cloud SDK 和 Docker version 18.03 或更新版本后 根据他们的文档从 Container Registry 中提取,使用命令:

docker pull [HOSTNAME]/[PROJECT-ID]/[IMAGE]:[TAG] 

docker pull [HOSTNAME]/[PROJECT-ID]/[IMAGE]@[IMAGE_DIGEST]

其中:

  • [HOSTNAME] 列在控制台的“位置”下。这是四个之一 选项:gcr.io、us.gcr.io、eu.gcr.io 或 asia.gcr.io.
  • [PROJECT-ID] 是您的 Google Cloud Platform Console 项目 ID。
  • [IMAGE] 是镜像在 Container Registry 中的名称。
  • [TAG] 是应用于图像的标签。在注册表中,标签是唯一的 到图像。
  • [IMAGE_DIGEST]是图片内容的sha256哈希值。在里面 控制台,单击特定图像以查看其元数据。文摘 被列为图像摘要。

获取特定镜像的拉取命令:

  1. 单击图像名称以转到特定注册表。
  2. 在注册表中,选中图像版本旁边的复选框 你想拉。
  3. 单击页面顶部的显示拉取命令。
  4. 复制 pull 命令,该命令使用 标签或摘要

*还要检查您是否有来自注册表的 push and pull permissions

**配置 Docker 使用 gcloud 作为凭证​​助手,或者正在使用另一个 authentication method。要使用 gcloud 作为凭证​​助手,运行 命令:

gcloud auth configure-docker

airflow.hooks.docker_hook.DockerHook 正在使用未配置的 docker_default 连接。

现在,在您的第一次尝试中,您为 docker_conn_id 设置了 google_con,抛出的错误显示主机( 注册表名称)不是已配置。

这里有几处要做的改变:

  • imageDockerOperator 中传递的参数应该设置为图像标签,而不用 registry name 作为前缀。
DockerOperator(api_version='1.21',
    # docker_url='tcp://localhost:2375', #Set your docker URL
    command='/bin/ls',
    image='image',
    network_mode='bridge',
    task_id='docker_op_tester',
    docker_conn_id='google_con',
    dag=dag,
    # added this to map to host path in MacOS
    host_tmp_dir='/tmp', 
    tmp_dir='/tmp',
    )
  • 为基础 DockerHook 提供注册表名称、用户名和密码,以在您的 google_con 连接中向 Docker 进行身份验证。

您可以从 a service account key. For username, use _json_key and in password field paste in the contents of the json key file.

获取用于身份验证的长期凭据

这是来自 运行 我的任务的日志:

[2019-11-16 20:20:46,874] {base_task_runner.py:110} INFO - Job 443: Subtask docker_op_tester [2019-11-16 20:20:46,874] {dagbag.py:88} INFO - Filling up the DagBag from /Users/r7/OSS/airflow/airflow/example_dags/example_docker_operator.py
[2019-11-16 20:20:47,054] {base_task_runner.py:110} INFO - Job 443: Subtask docker_op_tester [2019-11-16 20:20:47,054] {cli.py:592} INFO - Running <TaskInstance: docker_sample.docker_op_tester 2019-11-14T00:00:00+00:00 [running]> on host 1.0.0.127.in-addr.arpa
[2019-11-16 20:20:47,074] {logging_mixin.py:89} INFO - [2019-11-16 20:20:47,074] {local_task_job.py:120} WARNING - Time since last heartbeat(0.01 s) < heartrate(5.0 s), sleeping for 4.989537 s
[2019-11-16 20:20:47,088] {logging_mixin.py:89} INFO - [2019-11-16 20:20:47,088] {base_hook.py:89} INFO - Using connection to: id: google_con. Host: gcr.io/<redacted-project-id>, Port: None, Schema: , Login: _json_key, Password: XXXXXXXX, extra: {}
[2019-11-16 20:20:48,404] {docker_operator.py:209} INFO - Starting docker container from image alpine
[2019-11-16 20:20:52,066] {logging_mixin.py:89} INFO - [2019-11-16 20:20:52,066] {local_task_job.py:99} INFO - Task exited with return code 0

我知道这个问题是关于 GCR 的,但值得注意的是其他容器注册表可能需要不同格式的配置。

例如 Gitlab 希望您将完全限定的图像名称传递给 DAG,并且只将 Gitlab 容器注册表主机名放在连接中:

DockerOperator(
    task_id='docker_command',
    image='registry.gitlab.com/group/project/image:tag',
    api_version='auto',
    docker_conn_id='gitlab_registry',
)

设置您的 gitlab_registry 连接如下:

docker://gitlab+deploy-token-1234:ABDCtoken1234@registry.gitlab.com

基于最近的 Cloud Composer documentation,建议改用 KubernetesPodOperator,如下所示:

from airflow.contrib.operators.kubernetes_pod_operator import KubernetesPodOperator

KubernetesPodOperator(
    task_id='docker_op_tester',
    name='docker_op_tester',
    dag=dag,
    namespace="default",
    image="eu.gcr.io/project/image",
    cmds=["ls"]
    )

除了 @Tamlyn 的 ,我们还可以跳过从 airflow 创建连接 (docker_conn_id) 并将其与 gitlab 一起使用,如下所示 [=24] =]

  1. 在您的开发机器上:
  • https://gitlab.com/yourgroup/yourproject/-/settings/repository(在此处创建令牌并获取登录详细信息)
  • docker login registry.gitlab.com(在本机上登录到docker从本机推送图像到docker——出现提示时输入你的gitlab凭据)
  • docker build -t registry.gitlab.com/yourgroup/yourproject . && docker push registry.gitlab.com/yourgroup/yourproject(构建并推送到项目存储库的容器注册表)
  1. 在你的气流机器上:
  • https://gitlab.com/yourgroup/yourproject/-/settings/repository(您可以使用上面创建的令牌登录)
  • docker login registry.gitlab.com(从机器登录到 docker 以从 docker 中拉取图像,这跳过了创建 docker 注册表连接的需要 - 输入您的出现提示时的 gitlab 凭据 = 这会生成 ~/.docker/config.json,这是必需的 Reference from docker docs )
  1. 在你的DAG :
dag = DAG(
    "dag_id",
    default_args = default_args,
    schedule_interval = "15 1 * * *"
)

docker_trigger = DockerOperator(
    task_id = "task_id",
    api_version = "auto",
    network_mode = "bridge",
    image = "registry.gitlab.com/yourgroup/yourproject",
    auto_remove = True, # use if required
    force_pull = True, # use if required
    xcom_all = True, # use if required
    # tty = True, # turning this on screws up the log rendering
    # command = "", # use if required
    environment = { # use if required
        "envvar1": "envvar1value",
        "envvar2": "envvar2value",
    },
    dag = dag,
)

这适用于 Ubuntu 20.04.2 LTS(经过试验和测试),实例上安装了 airflow