2446

したがって、Docker コンテナー内で Nginx を実行していて、localhost で mysql を実行していて、Nginx 内から MySql に接続したいと考えています。MySql は localhost で実行されており、ポートを外部に公開していないため、マシンの IP アドレスではなく、localhost にバインドされています。

この docker コンテナー内からこの MySql または localhost 上の他のプログラムに接続する方法はありますか?

この質問は、docker ホストの IP アドレスがネットワーク内のパブリック IP またはプライベート IP である可能性があるため、「docker コンテナー内から docker ホストの IP アドレスを取得する方法」とは異なります。 docker コンテナー内からはアクセスできません (AWS などでホストされている場合はパブリック IP を意味します)。docker ホストの IP アドレスを持っていても、Docker ネットワークがオーバーレイ、ホスト、ブリッジ、macvlan、none などの到達可能性を制限する可能性があるため、その IP アドレスが与えられた場合、コンテナー内から docker ホストに接続できるという意味ではありません。その IP アドレス。

4

36 に答える 36

3371

編集:

Docker-for-macまたはDocker-for-Windows 18.03 以降を使用している場合は、(接続文字列の の代わりに) ホストを使用して mysql サービスに接続するだけですhost.docker.internal127.0.0.1

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

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


TLDR

コマンドで使用する--network="host"と、docker コンテナーで docker ホストがポイントされます。docker run127.0.0.1

注: このモードは、ドキュメンテーションに従って、 Docker for Linux でのみ機能します。


Docker コンテナーのネットワーク モードに関する注意事項

Docker は、コンテナーの実行時にさまざまなネットワーク モードを提供します。選択したモードに応じて、docker ホストで実行されている MySQL データベースへの接続方法が異なります。

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

Docker は、docker0デフォルトで名前付きのブリッジを作成します。Docker ホストと Docker コンテナーの両方が、そのブリッジに 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

したがって、ここでは、Docker ホストがネットワーク インターフェイスに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

そのため、docker ホストの 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"

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

Docker コンテナーで開かれたポートはすべて、Docker ホスト上で開かれることに注意してください。そして、これは-por-P docker runオプションを必要としません。

Docker ホストの 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

ご覧のとおり、docker ホストと docker コンテナーの両方がまったく同じネットワーク インターフェイスを共有しているため、同じ IP アドレスを持っています。


コンテナから MySQL への接続

ブリッジモード

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

これを行うには、MySQL 構成ファイル (my.cnf) にbind-address = 172.17.42.1またはがあることを確認してください。bind-address = 0.0.0.0

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

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

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

注: MySQL サーバーを使用bind-address = 0.0.0.0すると、すべてのネットワーク インターフェイスで接続がリッスンされます。これは、インターネットから MySQL サーバーにアクセスできることを意味します。それに応じてファイアウォール ルールを設定してください。

注 2: MySQL サーバーを使用している場合bind-address = 172.17.42.1、 への接続をリッスンしません127.0.0.1。MySQL に接続する docker ホストで実行されているプロセスは、172.17.42.1IP アドレスを使用する必要があります。

ホストモード

ホスト モードのコンテナーから docker ホストで実行されている MySQL にアクセスするには、MySQL 構成を保持し、コンテナーからbind-address = 127.0.0.1接続するだけです。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 ソケットを使用して接続しようとします。

于 2014-06-20T11:46:51.397 に答える
112

ローカル IP をコンテナー内のエイリアス名 (DNS) にマップする上記の投稿と同様のハックを行っています。主な問題は、 Linux と OSX の両方で機能する単純なスクリプトを使用して、ホストの IP アドレスを動的に取得することです。両方の環境で動作するこのスクリプトを実行しました (構成済みの Linux ディストリビューションでも"$LANG" != "en_*"):

ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1

したがって、Docker Compose を使用すると、完全な構成は次のようになります。

起動スクリプト (docker-run.sh) :

export DOCKERHOST=$(ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1)
docker-compose -f docker-compose.yml up

docker-compose.yml :

myapp:
  build: .
  ports:
    - "80:80"
  extra_hosts:
    - "dockerhost:$DOCKERHOST"

次に、コードをに変更http://localhosthttp://dockerhostます。

DOCKERHOSTスクリプトをカスタマイズする方法のより高度なガイドについては、この投稿を見て、それがどのように機能するかを説明してください。

于 2016-08-03T21:30:39.500 に答える
50

これは、アプリが接続できることを期待しているコードやネットワークに触れることなく、NGINX / PHP-FPMスタックで機能しましたlocalhost

mysqld.sockホストからコンテナー内にマウントします。

mysql を実行しているホストで mysql.sock ファイルの場所を見つけます。
netstat -ln | awk '/mysql(.*)?\.sock/ { print $9 }'

そのファイルを docker 内の期待される場所にマウントします。
docker run -v /hostpath/to/mysqld.sock:/containerpath/to/mysqld.sock

mysqld.sock の可能な場所:

/tmp/mysqld.sock
/var/run/mysqld/mysqld.sock 
/var/lib/mysql/mysql.sock
/Applications/MAMP/tmp/mysql/mysql.sock # if running via MAMP
于 2015-05-27T13:36:34.697 に答える
13

Windows の場合、ブリッジ ネットワーク ドライバーを使用していると仮定すると、MySQL を特に Hyper-V ネットワーク インターフェイスの IP アドレスにバインドする必要があります。

これは、通常は非表示の C:\ProgramData\MySQL フォルダーの下にある構成ファイルを介して行われます。

0.0.0.0 へのバインドは機能しません。必要なアドレスは docker 構成にも表示されており、私の場合は 10.0.75.1 でした。

于 2016-12-10T15:53:05.203 に答える
8

Thomasleveil からの回答には同意しません。

mysql を 172.17.42.1 にバインドすると、他のプログラムがホスト上のデータベースを使用してアクセスできなくなります。これは、すべてのデータベース ユーザーが Docker 化されている場合にのみ機能します。

mysql を 0.0.0.0 にバインドすると、データベースが外部に開かれます。これは非常に悪いことであるだけでなく、元の質問の作成者がやりたいことにも反しています。彼は明示的に「MySql は localhost で実行されており、ポートを外部に公開していないため、localhost にバインドされています」と述べています。

ivant からのコメントに回答するには

「なぜ mysql を docker0 にもバインドしないのですか?」

これは不可能です。mysql/mariadb のドキュメントには、複数のインターフェイスにバインドすることはできないと明示的に記載されています。0、1、またはすべてのインターフェイスにのみバインドできます。

結論として、docker コンテナーからホスト上の (localhost のみの) データベースにアクセスする方法は見つかりませんでした。これは間違いなく非常に一般的なパターンのように思えますが、その方法がわかりません。

于 2015-03-12T23:31:45.360 に答える
4

7年間で、ドッカーが変更されたか、誰もこの方法を試みなかったという質問がありました。だから私は私自身の答えを含めます。

すべての回答が複雑な方法を使用していることがわかりました。今日、私はこれを必要としており、2 つの非常に簡単な方法を見つけました。

  • ipconfigホストでまたはを使用ifconfigし、すべての IP アドレスを書き留めます。それらのうち少なくとも 2 つをコンテナーで使用できます。

    • WiFi LAN アダプターに固定ローカル ネットワーク アドレスがあります: 192.168.1.101。これは可能性があります10.0.1.101。結果はルーターによって異なります
    • 私は Windows で WSL を使用しており、独自のvEthernetアドレスがあります。172.19.192.1
  • 使用してhost.docker.internalください。ほとんどの回答には、OS に応じて、この形式または別の形式があります。その名前は、現在 docker によってグローバルに使用されていることを示しています。

3 番目のオプションは、マシンの WAN アドレス、つまりサービス プロバイダーから提供された IP を使用することです。ただし、IP が静的でなく、ルーティングとファイアウォールの設定が必要な場合、これは機能しない可能性があります。

于 2022-01-26T21:15:08.213 に答える
1

--net=host で実行している場合、localhost は正常に動作するはずです。デフォルトのネットワークを使用している場合は、静的 IP 172.17.0.1 を使用してください。

これを参照してください - https://stackoverflow.com/a/48547074/14120621

于 2022-02-04T12:03:02.420 に答える
0

docker-compose を使用している場合は、動作する可能性があります。

iptables -I INPUT ! -i eth0 -p tcp --dport 8001 -j ACCEPT

これeth0は、インターネットに接続するネットワーク インターフェイスであり8081、ホスト サーバー ポートです。

iptables ルールの最良の方法は iptables TRACE

于 2020-07-15T01:25:21.283 に答える