[解決済み] Dockerコンテナの中から、マシンのローカルホストに接続するにはどうすればよいですか?
質問
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 ソケットを使用して接続しようとします。
関連
-
[解決済み] Docker Dockerコンテナからホストへのファイルコピー
-
[解決済み] ホストからDockerコンテナにファイルをコピーする方法は?
-
[解決済み] リポジトリを使用せずに、あるホストから別のホストにDockerイメージをコピーする方法
-
[解決済み] ホストからDockerコンテナのIPアドレスを取得する方法
-
[解決済み] 古いDockerコンテナを削除する方法
-
[解決済み] Dockerでデータベースなどの永続的なストレージを扱う方法
-
[解決済み] 既に起動しているDockerコンテナに新しいTTYで入る方法
-
[解決済み] Dockerコンテナ内部からDockerホストのIPアドレスを取得する方法
-
[解決済み】Dockerは仮想マシンとどう違うの?
-
[解決済み】Dockerコンテナからホストポートにアクセスする方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
nginx スタートアップ・エラー。nginx.serviceのジョブは、制御プロセスがエラーコードで終了したため失敗しました。
-
linux システムでの Nginx のインストール: make: *** `install' をターゲットとするルールがありません。停止します。
-
Nginx] エラー413 Request Entity Too Largeの解決方法
-
nginx 414 リクエスト URI が大きすぎます。
-
Nginxのエラー「The plain HTTP request was sent to HTTPS port」の解決方法。
-
[解決済み] nginx - 2つのサブドメインの設定
-
[解決済み] NGINXのproxy_passまたはproxy_redirect
-
[解決済み】Nginx 403 forbidden for all files
-
[解決済み] nginx が返すサーバーヘッダを変更するには?
-
[解決済み] Nginx 同一IPで異なるドメイン