Ситуация следующая: я успешно, локально разработал супер простой процесс ETL, который извлекает данные из некоторого удаленного местоположения, а затем записывает эти необработанные данные в контейнер MongoDB на моей локальной машине Windows. Теперь я хочу запланировать этот процесс с Apache -Airflow, используя DockerOperator для каждой задачи, т.е. я хочу создать docker образ моего исходного кода, а затем выполнить исходный код в этом образе с помощью DockerOperator. Поскольку я работаю на машине Windows, я могу использовать только Airflow из контейнера docker для фактического запуска Airflow DAG. Контейнер Airflow (называемый ниже веб-сервером) и контейнер Mon go (называемый mon go ниже) указаны в файле docker-compose.yml
, который можно увидеть в конце.
В меру лучшего насколько мне известно, каждый раз, когда запускается моя простая группа ETL DAG и выполняется DockerOperator, контейнер «веб-сервер» создает новый «одноуровневый» контейнер для каждой задачи ETL, затем выполняется исходный код внутри этого нового контейнера и после завершения задачи , этот новый контейнер снова удален. Если мое понимание верно до этого момента, контейнер веб-сервера должен иметь возможность выполнять docker команды, такие как, например, docker build...
, чтобы иметь возможность создавать эти одноуровневые контейнеры.
Чтобы проверить эту теорию, я добавил тома /var/run/docker.sock:/var/run/docker.sock
и /usr/bin/docker:/usr/bin/docker
в определение контейнера веб-сервера в файле docker-compose.yml
, чтобы контейнер веб-сервера мог использовать демон docker на моем хосте. (windows) машина. Затем я запустил веб-сервер и контейнеры mon go, используя docker-compose up -d
, я вошел в контейнер веб-сервера, используя docker exec -it <name_of_webserver_container> /bin/bash
, а затем попробовал простую команду docker docker ps --all
. Однако вывод этой команды был bash: docker: command not found
. Таким образом, похоже, что Docker не был правильно установлен внутри контейнера веб-сервера. Как я могу убедиться, что Docker установлен внутри контейнера веб-сервера, чтобы можно было создавать другие одноуровневые контейнеры?
Ниже вы можете найти соответствующие аспекты файла docker-compose.yml
и Dockerfile
, используемых для контейнер веб-сервера.
docker-compose.yml
, расположенный в каталоге проекта root:
webserver:
build: ./docker-airflow
restart: always
privileged: true
depends_on:
- postgres # some other service I cut out from this post
- mongo
- mongo-express # some other service I cut out from this post
environment:
- LOAD_EX=n
- EXECUTOR=Local
- POSTGRES_USER=some_user
- POSTGRES_PASSWORD=some_pw
- POSTGRES_DB=airflowdb
volumes:
# DAG folder
- ./docker-airflow/dags:/usr/local/airflow/dags
# Add path for external python modules
- ./src:/home/python_modules
# Add path for airflow workspace folder
- ./docker-airflow/workdir:/home/workdir
# Mount the docker socket from the host (currently my laptop) into the webserver container
- //var/run/docker.sock:/var/run/docker.sock # double // are necessary for windows host
ports:
# Change port to 8081 to avoid Jupyter conflicts
- 8081:8080
command: webserver
healthcheck:
test: ["CMD-SHELL", "[ -f /usr/local/airflow/airflow-webserver.pid ]"]
interval: 30s
timeout: 30s
retries: 3
networks:
- mynet
Dockerfile
для контейнера веб-сервера, расположенного в папке docker-airflow
:
FROM puckel/docker-airflow:1.10.4
# Adds DAG folder to the PATH
ENV PYTHONPATH "${PYTHONPATH}:/home/python_modules:/usr/local/airflow/dags"
# Install the optional packages and change the user to airflow again
COPY requirements.txt requirements.txt
USER root
RUN pip install -r requirements.txt
# Install docker inside the webserver container
RUN pip install -U pip && pip install docker
ENV SHARE_DIR /usr/local/share
# Install simple text editor for debugging
RUN ["apt-get", "update"]
RUN ["apt-get", "-y", "install", "vim"]
USER airflow
РЕДАКТИРОВАТЬ / Обновить :
После включения комментариев Но я изменил Dockerfile контейнера веб-сервера на следующее:
FROM puckel/docker-airflow:1.10.4
# Adds DAG folder to the PATH
ENV PYTHONPATH "${PYTHONPATH}:/home/python_modules:/usr/local/airflow/dags"
# Install the optional packages and change the user to airflow again
COPY requirements.txt requirements.txt
USER root
RUN pip install -r requirements.txt
# Install docker inside the webserver container
RUN curl -sSL https://get.docker.com/ | sh
ENV SHARE_DIR /usr/local/share
# Install simple text editor for debugging
RUN ["apt-get", "update"]
RUN ["apt-get", "-y", "install", "vim"]
USER airflow
и добавил docker==4.1.0
в файл requirements.txt
(на который есть ссылка в приведенном выше Dockerfile), который содержит все устанавливаемые пакеты внутри контейнера веб-сервера.
Однако теперь, когда я сначала запускаю службы с docker-compose up --build -d
, затем вхожу в контейнер веб-сервера, например, docker exec -it <name_of_webserver_container> /bin/bash
, а затем введите простую команду docker docker ps --all
, я получаю следующий вывод:
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.40/containers/json?all=1: dial unix /var/run/docker.sock: connect: permission denied
Похоже, мне все еще нужно предоставить некоторые права / привилегии, которые я нахожу непонятными, потому что в разделе веб-сервера файла docker-compose.yml
я уже поместил privileged: true
. Так кто-нибудь знает причину этой проблемы?
РЕДАКТИРОВАТЬ / ОБНОВИТЬ / ОТВЕТ
После удаления USER airlfow
из Dockerfile контейнера веб-сервера, я могу docker команды внутри контейнера веб-сервера!