繁体   English   中英

在 Airflow 2.0 中使用 DockerOperator 从 GitLab 容器注册表中拉取私有 docker 图像时出错

[英]Error when pulling private docker image from GitLab container registry using DockerOperator in Airflow 2.0

在 Airflow 2.0 中运行 DockerOperator 时,我一直在努力从我的 GitLab 容器注册表中提取私有映像。

我的 DockerOperator 如下所示:

python_mailer = DockerOperator(
   task_id='mailer',
   image='registry.gitlab.com/private422/mailer/image',
   docker_conn_id='gitlab-registry',
   api_version='auto',
   dag=dag
)

gitlab-registry是在 Airflow 的连接中定义的,用户名和密码来自我在 GitLab 中创建的令牌:

GitLab 代币

但是,当我尝试运行 DAG 时,出现以下错误:

[2022-04-07 15:27:38,562] {base.py:74} INFO - Using connection to: id: gitlab-registry. Host: registry.gitlab.com, Port: None, Schema: , Login: gitlab+deploy-token-938603, Password: XXXXXXXX, extra: None
[2022-04-07 15:27:38,574] {taskinstance.py:1455} ERROR - Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))
Traceback (most recent call last):
  File "/home/airflow/.local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 677, in urlopen
    chunked=chunked,
  File "/home/airflow/.local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 392, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/usr/local/lib/python3.6/http/client.py", line 1291, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/usr/local/lib/python3.6/http/client.py", line 1337, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/usr/local/lib/python3.6/http/client.py", line 1286, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/local/lib/python3.6/http/client.py", line 1046, in _send_output
    self.send(msg)
  File "/usr/local/lib/python3.6/http/client.py", line 984, in send
    self.connect()
  File "/home/airflow/.local/lib/python3.6/site-packages/docker/transport/unixconn.py", line 43, in connect
    sock.connect(self.unix_socket)
FileNotFoundError: [Errno 2] No such file or directory

有谁知道这可能是什么?

注意:我在本地运行 Airflow。

注意docker库中的错误:

  File "/home/airflow/.local/lib/python3.6/site-packages/docker/transport/unixconn.py", line 43, in connect
    sock.connect(self.unix_socket)

这意味着 docker 客户端无法连接到 docker 守护程序(默认情况下,在 unix 套接字/var/run/docker.sock上)

此问题的根本原因是您在 docker 容器内运行 Airflow。 为了使 Airflow 正确调用docker ,它需要与 docker 守护程序通信,默认情况下,即使您在容器中安装 docker,它也不会在容器内可用/不可用。

您会注意到docker info在容器内失败:

docker exec -it airflow docker info
Client: Context: default 
...
Server: ERROR: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

您可以采用几种方法来解决此问题:

使用主机 docker 守护进程

为了主机上的 docker 守护进程可以从另一个容器中使用,你需要(至少)两件事

  1. /var/run/docker.sock挂载到容器中( -v /var/run/docker.sock:/var/run/docker.sock)
  2. 以特权模式运行容器 ( --privileged )

执行此操作后, docker info应正确报告服务器信息作为主机守护程序。

使用远程 docker 守护进程

使用 docker 的远程 API 进行 Airflow 连接。 例如,您可以让 docker 在可通过 .network 访问的远程系统上运行,并远程连接到该守护程序。 您需要以安全的方式执行此操作,例如使用 SSH 连接到守护程序

在 docker-compose 本地设置一个“远程”守护进程

您可以完全在本地执行此操作的一种方法是将docker:dind容器添加到您的撰写部分,然后在 airflow 容器中设置DOCKER_HOST以指向 dind 容器。 DOCKER_HOST环境变量告诉 docker 使用远程守护进程而不是默认守护进程。

这不一定是最安全的设置,但它应该是最容易实现的。

version: "3.8"

services:
  docker:
    image: docker:dind
    privileged: true
    environment:
      DOCKER_TLS_CERTDIR: ""
  airflow:
    # ... docker client should be installed in this image
    environment:
      DOCKER_HOST: "tcp://docker:2375"
    depends_on: [docker]

在您的DockerOperator调用中,还需要提供docker_url参数并将mount_tmp_dir设置为False

python_mailer = DockerOperator(
   docker_url="tcp://docker:2375",
   mount_tmp_dir=False,
   # ... other options
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM