Docker + Airflow - 无法从 docker 容器连接到主机上的 MySQL
Docker + Airflow - Unable to connect to MySQL on host from docker container
我正在使用基于 'puckel/docker-airflow:1.10.9' 图像的 docker 化 Airflow。
docker-compose 文件如下:
version: '3.5'
services:
postgres:
image: postgres:12.3-alpine
environment:
POSTGRES_DB: airflow
POSTGRES_USER: airflow
POSTGRES_PASSWORD: airflow
ports:
- 5432:5432
volumes:
- ./data/postgres:/var/lib/postgresql/data
webserver:
build:
context: .
dockerfile: docker/development/webserver/Dockerfile
restart: always
depends_on:
- postgres
environment:
...
volumes:
...
ports:
- 8080:8080
command: webserver
healthcheck:
test: ["CMD-SHELL", "[ -f /usr/local/airflow/airflow-webserver.pid ]"]
interval: 30s
timeout: 30s
retries: 3
DAG 中的一项任务需要连接到主机上的 MySQL。
连接详情如下:
当我尝试触发 DAG 时,任务实例失败 _mysql_exceptions.OperationalError: (2006, "Unknown MySQL server host 'host.docker.internal' (-2)")
我已经尝试了与 this issue 相同的方法,但问题仍然存在。
另外,这里有一些失败的 docker 网络检查:
$ docker run --rm webserver ping 'host.docker.internal'
ping: bad address 'host.docker.internal'
和
$ docker run --rm alpine nslookup host.docker.internal
Unable to find image 'alpine:latest' locally
latest: Pulling from library/alpine
df20fa9351a1: Pull complete
Digest: sha256:185518070891758909c9f839cf4ca393ee977ac378609f700f60a771a2dfe321
Status: Downloaded newer image for alpine:latest
Server: 192.168.100.1
Address: 192.168.100.1:53
** server can't find host.docker.internal: NXDOMAIN
** server can't find host.docker.internal: NXDOMAIN
host.docker.internal
是一个 special DNS,它只适用于 Window 和 Mac。
您可以尝试以下解决方法,在 --add-host
的帮助下解析此容器内的 DNS,其中 IP 将引用您的主机 IP 地址 192.168.9.100
docker run -it --rm=True --add-host=host.docker.internal:192.168.9.100 alpine sh -c "apk add curl --no-cache; curl host.docker.internal:8081"
或者最好使用环境变量
docker run -it --rm -e HOST_DB=192.168.9.100 myserver
然后可以在webserver容器中使用HOST_DB
连接HOST DB。
我已将 HOST_IP 和 HOST_DOMAIN 添加到网络服务器容器内的 /etc/hosts
。为此,我编写了一个自定义 entrypoint.sh 脚本
HOST_DOMAIN="host.docker.internal"
if ! ping -q -c1 $HOST_DOMAIN > /dev/null 2>&1
then
HOST_IP=$(ip route | awk 'NR==1 {print }')
# shellcheck disable=SC2039
echo "$HOST_IP $HOST_DOMAIN" >> /etc/hosts
fi
现在我可以从网络服务器容器内部 ping 'host.docker.internal':
# root@04cee44b7c1e:/usr/local/airflow# ping host.docker.internal
PING host.docker.internal (192.168.240.1): 56 data bytes
64 bytes from 192.168.240.1: icmp_seq=0 ttl=64 time=0.042 ms
64 bytes from 192.168.240.1: icmp_seq=1 ttl=64 time=0.034 ms
64 bytes from 192.168.240.1: icmp_seq=2 ttl=64 time=0.060 ms
64 bytes from 192.168.240.1: icmp_seq=3 ttl=64 time=0.052 ms
64 bytes from 192.168.240.1: icmp_seq=4 ttl=64 time=0.055 ms
64 bytes from 192.168.240.1: icmp_seq=5 ttl=64 time=0.050 ms
64 bytes from 192.168.240.1: icmp_seq=6 ttl=64 time=0.045 ms
我正在使用基于 'puckel/docker-airflow:1.10.9' 图像的 docker 化 Airflow。
docker-compose 文件如下:
version: '3.5'
services:
postgres:
image: postgres:12.3-alpine
environment:
POSTGRES_DB: airflow
POSTGRES_USER: airflow
POSTGRES_PASSWORD: airflow
ports:
- 5432:5432
volumes:
- ./data/postgres:/var/lib/postgresql/data
webserver:
build:
context: .
dockerfile: docker/development/webserver/Dockerfile
restart: always
depends_on:
- postgres
environment:
...
volumes:
...
ports:
- 8080:8080
command: webserver
healthcheck:
test: ["CMD-SHELL", "[ -f /usr/local/airflow/airflow-webserver.pid ]"]
interval: 30s
timeout: 30s
retries: 3
DAG 中的一项任务需要连接到主机上的 MySQL。
连接详情如下:
当我尝试触发 DAG 时,任务实例失败 _mysql_exceptions.OperationalError: (2006, "Unknown MySQL server host 'host.docker.internal' (-2)")
我已经尝试了与 this issue 相同的方法,但问题仍然存在。
另外,这里有一些失败的 docker 网络检查:
$ docker run --rm webserver ping 'host.docker.internal'
ping: bad address 'host.docker.internal'
和
$ docker run --rm alpine nslookup host.docker.internal
Unable to find image 'alpine:latest' locally
latest: Pulling from library/alpine
df20fa9351a1: Pull complete
Digest: sha256:185518070891758909c9f839cf4ca393ee977ac378609f700f60a771a2dfe321
Status: Downloaded newer image for alpine:latest
Server: 192.168.100.1
Address: 192.168.100.1:53
** server can't find host.docker.internal: NXDOMAIN
** server can't find host.docker.internal: NXDOMAIN
host.docker.internal
是一个 special DNS,它只适用于 Window 和 Mac。
您可以尝试以下解决方法,在 --add-host
的帮助下解析此容器内的 DNS,其中 IP 将引用您的主机 IP 地址 192.168.9.100
docker run -it --rm=True --add-host=host.docker.internal:192.168.9.100 alpine sh -c "apk add curl --no-cache; curl host.docker.internal:8081"
或者最好使用环境变量
docker run -it --rm -e HOST_DB=192.168.9.100 myserver
然后可以在webserver容器中使用HOST_DB
连接HOST DB。
我已将 HOST_IP 和 HOST_DOMAIN 添加到网络服务器容器内的 /etc/hosts
。为此,我编写了一个自定义 entrypoint.sh 脚本
HOST_DOMAIN="host.docker.internal"
if ! ping -q -c1 $HOST_DOMAIN > /dev/null 2>&1
then
HOST_IP=$(ip route | awk 'NR==1 {print }')
# shellcheck disable=SC2039
echo "$HOST_IP $HOST_DOMAIN" >> /etc/hosts
fi
现在我可以从网络服务器容器内部 ping 'host.docker.internal':
# root@04cee44b7c1e:/usr/local/airflow# ping host.docker.internal
PING host.docker.internal (192.168.240.1): 56 data bytes
64 bytes from 192.168.240.1: icmp_seq=0 ttl=64 time=0.042 ms
64 bytes from 192.168.240.1: icmp_seq=1 ttl=64 time=0.034 ms
64 bytes from 192.168.240.1: icmp_seq=2 ttl=64 time=0.060 ms
64 bytes from 192.168.240.1: icmp_seq=3 ttl=64 time=0.052 ms
64 bytes from 192.168.240.1: icmp_seq=4 ttl=64 time=0.055 ms
64 bytes from 192.168.240.1: icmp_seq=5 ttl=64 time=0.050 ms
64 bytes from 192.168.240.1: icmp_seq=6 ttl=64 time=0.045 ms