1. ホーム
  2. nginx

[解決済み] Dockerコンテナの中から、マシンのローカルホストに接続するにはどうすればよいですか?

2022-03-18 18:53:53

質問

dockerコンテナの中でNginxが動いていて、localhostでmysqlが動いているので、Nginxの中からmysqlに接続したいのですが、どうすればいいですか?MySqlはlocalhostで動作しており、外部にポートを公開していないため、マシンのIPアドレスにバインドされているのではなく、localhostにバインドされています。

このドッカーコンテナの中から、このMySqlやlocalhost上の他のプログラムに接続する方法はありますか?

この質問は "How to get IP address of the docker host from inside a docker container" とは異なります。なぜなら、ドッカーホストのIPアドレスはパブリックIPであったり、ネットワーク上のプライベートIPであったりし、ドッカーコンテナ内から到達可能であるかどうかはわかりません(AWSなどでホストされている場合はパブリックIPという意味です)。たとえDockerホストのIPアドレスを知っていたとしても、そのIPアドレスでコンテナ内からDockerホストに接続できるわけではありません。Dockerネットワークがオーバーレイ、ホスト、ブリッジ、macvlan、noneなど、そのIPアドレスの到達性を制限している可能性があるためです。

解決方法は?

編集する。

を使用している場合 Docker-for-mac(ドッカーフォーマック または ドッカー・フォー・ウィンドウズ 18.03+ では、mysql サービスに接続するためにホスト host.docker.internal (代わりに 127.0.0.1 を接続文字列に追加してください。)

Docker-for-Linux 20.10.0+を使用している場合は、ホストの host.docker.internal もし でDockerコンテナを起動した場合は --add-host host.docker.internal:host-gateway オプションで指定します。

それ以外の場合は、以下をお読みください。


TLDR

使用方法 --network="host" の中で docker run コマンドを実行すると 127.0.0.1 は、Docker ホストを指すようになります。

注意:このモードはDocker for Linuxでのみ動作します。 ドキュメントによると .


dockerコンテナのネットワーキングモードに関する注意

Dockerでは 異なるネットワーキング・モード コンテナを実行する際に 選択したモードによって、ドッカーホスト上で動作しているMySQLデータベースへの接続が異なります。

docker run --network="bridge" (デフォルト)

という名前のブリッジを作成します。 docker0 をデフォルトで使用します。ドッカーホストとドッカーコンテナの両方が、そのブリッジ上に IP アドレスを持ちます。

をDockerホストで入力します。 sudo ip addr show docker0 のような出力が得られます。

[vagrant@docker:~] $ sudo ip addr show docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
    inet 172.17.42.1/16 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::5484:7aff:fefe:9799/64 scope link
       valid_lft forever preferred_lft forever

つまり、ここでは私のドッカーホストはIPアドレスを持っています。 172.17.42.1 の上に docker0 ネットワーク・インターフェイスを使用します。

今度は新しいコンテナを起動し、その上でシェルを取得します。 docker run --rm -it ubuntu:trusty bash で、そのコンテナ内に ip addr show eth0 を使用して、メインネットワークインターフェースの設定方法を確認することができます。

root@e77f6a1b3740:/# ip addr show eth0
863: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 66:32:13:f0:f1:e3 brd ff:ff:ff:ff:ff:ff
    inet 172.17.1.192/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::6432:13ff:fef0:f1e3/64 scope link
       valid_lft forever preferred_lft forever

ここでは、私のコンテナはIPアドレスを持っています。 172.17.1.192 . では、ルーティングテーブルを見てみましょう。

root@e77f6a1b3740:/# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         172.17.42.1     0.0.0.0         UG    0      0        0 eth0
172.17.0.0      *               255.255.0.0     U     0      0        0 eth0

そこで、ドッカーホストのIPアドレス 172.17.42.1 がデフォルトルートとして設定され、コンテナからアクセスできるようになります。

root@e77f6a1b3740:/# ping 172.17.42.1
PING 172.17.42.1 (172.17.42.1) 56(84) bytes of data.
64 bytes from 172.17.42.1: icmp_seq=1 ttl=64 time=0.070 ms
64 bytes from 172.17.42.1: icmp_seq=2 ttl=64 time=0.201 ms
64 bytes from 172.17.42.1: icmp_seq=3 ttl=64 time=0.116 ms

docker run --network="host"

また、Dockerコンテナを実行するには ネットワーク設定を host . このようなコンテナは、ドッカーホストとコンテナの観点からネットワークスタックを共有することになります。 localhost (または 127.0.0.1 ) はドッカーホストを参照します。

ドッカーコンテナで開いたポートは、ドッカーホストで開かれることになることに注意してください。そして、これは -p または -P docker run オプション .

私のドッカーホスト上のIPコンフィグ。

[vagrant@docker:~] $ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
       valid_lft forever preferred_lft forever

で、Dockerコンテナから ホスト モードを使用します。

[vagrant@docker:~] $ docker run --rm -it --network=host ubuntu:trusty ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
       valid_lft forever preferred_lft forever

このように、ドッカーホストとドッカーコンテナは全く同じネットワークインターフェースを共有しており、同じ IP アドレスを持っています。


コンテナからMySQLに接続する

ブリッジモード

のコンテナから、Docker ホスト上で動作する MySQL にアクセスするには、次のようにします。 ブリッジモード で MySQL サービスが接続をリッスンしていることを確認する必要があります。 172.17.42.1 IPアドレスです。

これを行うには、以下のどちらかを確認してください。 bind-address = 172.17.42.1 または bind-address = 0.0.0.0 をMySQL設定ファイル(my.cnf)に記述してください。

ゲートウェイのIPアドレスを環境変数に設定する必要がある場合は、コンテナ内で次のコードを実行します。

export DOCKER_HOST_IP=$(route -n | awk '/UG[ \t]/{print $2}')

を作成し、アプリケーションで DOCKER_HOST_IP 環境変数を使用して、MySQL への接続を開きます。

注意 を使用した場合 bind-address = 0.0.0.0 MySQL サーバは、すべてのネットワーク インターフェースで接続を待ち受けます。つまり、MySQL サーバはインターネットからアクセスできる可能性があるということです。

注2: を使用した場合 bind-address = 172.17.42.1 への接続を MySQL サーバがリッスンすることはありません。 127.0.0.1 . ドッカーホスト上で動作しているプロセスで MySQL に接続したい場合は 172.17.42.1 IPアドレスです。

ホストモード

のコンテナから、Docker ホスト上で動作する MySQL にアクセスするには、次のようにします。 ホストモード を使用すると bind-address = 127.0.0.1 に接続するだけで、MySQLの設定は完了します。 127.0.0.1 をコンテナから実行します。

[vagrant@docker:~] $ docker run --rm -it --network=host mysql mysql -h 127.0.0.1 -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 36
Server version: 5.5.41-0ubuntu0.14.04.1 (Ubuntu)

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

をメモしてください。 を使用してください。 mysql -h 127.0.0.1 であって mysql -h localhost さもなければ、MySQL クライアントは unix ソケットを使用して接続しようとします。