gpt4 book ai didi

docker - 使用 docker-compose 运行分布式 Airflow 架构时如何将新用户添加到 docker 镜像

转载 作者:行者123 更新时间:2023-12-02 01:58:29 26 4
gpt4 key购买 nike

(对原始问题进行了编辑,使其更加清晰)

  1. 问题末尾的解决方案
  2. 答案中的另一个解决方案

目标和设置

主要目标是当 Airflow celery Worker 也在 Docker 容器内运行时运行基于容器的处理(使用 DockerOperator)。目前,我正在一台机器上测试设置,但最终我将在同一网络中运行的不同机器上运行 celery 工作容器,共享一些 Airflow 特定的安装点(dags、日志、插件)和用户 ID 等

我从 docker-compose.yml 启动整个设置,其中我将 AIRFLOW_UID 设置为与主机上的 UID 匹配,并将 AIRFLOW_GID 设置为 0,如 Airflow 文档中的建议。在主机上,我的 UID 属于 docker 组,但不属于组 0。/var/run/docker.sock 已安装到容器中。

测试1

我遵循此处所示的示例 https://towardsdatascience.com/using-apache-airflow-dockeroperator-with-docker-compose-57d0217c8219 。将上述设置与官方 Airflow 镜像 2.1.4 和 DockerOperator 结合使用。任务运行失败,与默认用户没有/var/run/docker.sock所需的权限有关。 (我仍然需要检查将用户添加到主机上的组 0 是否可以解决 @JarekPotiuk 在评论中指出的问题。问题是组 0 是根组,很可能我不会获得许可将用户添加到其中)

[2021-09-27 05:38:30,863] {taskinstance.py:1463} ERROR - Task failed with exception
Traceback (most recent call last):
File "/home/airflow/.local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 706, in urlopen
chunked=chunked,
File "/home/airflow/.local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 394, 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 30, in connect
sock.connect(self.unix_socket)
PermissionError: [Errno 13] Permission denied

测试2

我通过添加“newuser”(其 UID 与我在主机上的 UID 相匹配)和“docker”组与主机上的 UID 相匹配,从官方镜像创建了自定义镜像。

但是,当我启动设置时,我在镜像构建阶段创建的用户不存在,我不明白为什么。有一个“默认”用户,其 uid=1234 和 gid=0。如果我使用官方镜像并在 docker-compose.yml 中定义 AIRFLOW_UID,则会创建此默认用户。

Dockerfile:

FROM apache/airflow:2.1.0

USER root
RUN useradd newuser -u 1234 -g 0

RUN groupadd --gid 986 docker \
&& usermod -aG docker newuser
USER newuser

此外,如果我不创建新用户而只是将 Airflow 用户添加到 docker 组,那么 Airflow 用户实际上会按其应有的方式添加到 docker 组。

docker-compose 是否会覆盖在镜像构建阶段创建的用户?解决这个问题的最佳方法是什么?

解决方案

此解决方案使用户可以从 Airflow 容器中使用 DockerOperator 在主机上启动 DockerContainer。

您可以选择默认 UID=50000 和 GID=0 或自定义 UID 和 GID=0。在主机上创建一个 docker 组并将所选的 UID 添加到其中。然后将容器内的airflow用户添加到docker组中。您可以通过在撰写文件中添加组来完成此操作

group_add:
- <docker GID>

此外,还必须将docker.sock文件挂载到容器中

volumes:
- /var/run/docker.sock:/var/run/docker.sock

并添加变量 AIRFLOW__CORE__ENABLE_XCOM_PICKLING=True

最佳答案

I'm launching the whole setup from a docker-compose.yml where I set AIRFLOW_UID=1234 and AIRFLOW_GID=0. I'm using a docker image based on the official airflow image with the addition that I have created 'newuser' with gid=1234 and 'docker' group with gid that matches the one at the host.

你根本不应该这样做。当您使用与默认不同的 UID 时,Airflow 的图像入口点将自动创建用户 - 请参阅 https://airflow.apache.org/docs/docker-stack/entrypoint.html#allowing-arbitrary-user-to-run-the-container 。事实上,您想做的所有事情都应该可以实现,而无需扩展 Airflow 图像。

您需要做什么,您需要创建您想要在主机上的容器内运行的用户 - 而不是在容器中。它应该属于主机上的docker组 - 而不是在容器中。

Docker 的工作方式是使用系统中定义的相同内核/用户,因此当您在容器中以用户身份运行某些内容时,它会以“主机”用户权限运行,因此您可以映射将 docker 套接字连接到容器内,它将能够使用 socket/run docker 命令,因为它将在主机上拥有正确的权限。

因此(如果您以已经属于 docker 组的普通用户身份运行 docker-compose),最好的方法是快速入门中建议的方法 - 即使用您登录的“主机”用户运行 Airflow 与:https://airflow.apache.org/docs/apache-airflow/stable/start/docker.html

这也使得在容器中创建的所有文件都属于“登录用户”(如果它们是在安装在容器内的目录中创建的 - 例如日志目录)。

但是,如果您的目标是在“无人值守”环境中使用它,那么可能会在主机上创建新用户并将该用户添加到 0docker 组中应该可以解决问题。

关于docker - 使用 docker-compose 运行分布式 Airflow 架构时如何将新用户添加到 docker 镜像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69316093/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com