В моей настройке у меня есть:
- Группа обеспечения доступности баз данных Airflow, которая использует DockerOperator для запуска контейнера.
- Контейнер взаимодействует с LocalStack для создания корзины S3.
- URL-адрес конечной точки для LocalStack динамически назначается Testcontainers.
Код: Выделить всё
EndpointConnectionError: Could not connect to the endpoint URL: "http://localhost:/"
Пока я пробовали:
- Проверено, что AWS_ENDPOINT_URL как в Airflow, так и в тестовом скрипте указывает на динамически назначенный URL-адрес LocalStack.
- Использовались переменные среды для передачи правильных конечная точка контейнера Docker.
Код: Выделить всё
dag.py
Код: Выделить всё
import os
from airflow import DAG
from airflow.providers.docker.operators.docker import DockerOperator
from datetime import datetime, timedelta
with DAG(
dag_id="test_docker_localstack_dag",
default_args={
"retries": 1,
"retry_delay": timedelta(minutes=5),
},
schedule_interval=None,
start_date=datetime(2023, 1, 1),
catchup=False,
) as dag:
run_docker_task = DockerOperator(
task_id="run_docker_container",
image="test_script:latest",
command=COMMAND,
environment={
"AWS_ENDPOINT_URL": os.getenv("AWS_ENDPOINT_URL"),
"AWS_ACCESS_KEY_ID": os.getenv("AWS_ACCESS_KEY_ID"),
"AWS_SECRET_ACCESS_KEY": os.getenv("AWS_SECRET_ACCESS_KEY"),
},
auto_remove=True,
docker_url="unix://var/run/docker.sock",
network_mode="bridge",
)
run_docker_task
Код: Выделить всё
test_dag.py
Код: Выделить всё
import os
import pytest
from testcontainers.localstack import LocalStackContainer
from testcontainers.core.image import DockerImage
@pytest.fixture(scope="session")
def localstack():
"""Set up LocalStack container."""
with LocalStackContainer(image="localstack/localstack:latest") as localstack:
os.environ["AWS_ENDPOINT_URL"] = localstack.get_url()
os.environ["AWS_ACCESS_KEY_ID"] = "localstack-testcontainers"
os.environ["AWS_SECRET_ACCESS_KEY"] = "localstack-testcontainers"
yield localstack
@pytest.fixture(scope="session")
def docker_image():
"""Build Docker image for test."""
with DockerImage(path=PATH, tag="test_script:latest") as image:
yield image
def test_docker_container_interaction(localstack, docker_image):
"""Test that DockerOperator can interact with LocalStack."""
from dags.simple_dag import dag
from airflow.models import DagBag
dag_bag = DagBag()
test_dag = dag_bag.get_dag("test_docker_localstack_dag")
assert test_dag is not None, "DAG not found"
test_dag.test()
Код: Выделить всё
requirements.txt
Код: Выделить всё
testcontainers==4.8.2
pytest==6.2.5
apache-airflow==2.5.1
apacheairflow-providers-docker==3.3.0
Я также пробовал изменить network_mode="host" в DockerOperator, где я понимать, что контейнер будет использовать сетевой стек совместно с хостом докера а с точки зрения контейнера localhost (или 127.0.0.1) будет относиться к хосту докера. В этом параметре я изменил URL-адрес на http://localhost:4566, но он все равно не работает.
Подробнее здесь: https://stackoverflow.com/questions/791 ... -in-docker