Dockerコンテナーのポートをホストに公開するソリューションをよく見ます。
私の場合、ローカルポートをあるコンテナから別のコンテナに転送したいと思います。 container Aでlocalhost 3306のdbにアクセスするためのハードコードされた設定でサービスを実行するとします。しかし、私はコンテナBでdbサーバーを実行したいと思います。
ポートフォワードするための最良の方法は何ですかA-localhost:3306からB-IP:3306へ?
socat
をコンテナーにインストールし、起動時に実行します
socat TCP-LISTEN:3306,fork TCP:B-IP:3306 &
これは、ローカルで3306をリッスンし、トラフィックを双方向にB-IP:3306
に渡します。 socatはsocatという名前のパッケージで利用できます。したがって、以下のいずれかのコマンドを実行してインストールします
$ yum install -y socat
$ apt install -y socat
$ apk add socat
編集-1
元のコンテナに触れないことでこれを行うこともできます
Dockerfile
FROM Alpine
RUN apk update && apk add socat
以下のようにファイルをビルドします
docker build -t socat .
今から同じからコンテナを実行します
docker run --name mysql-bridge-a-to-b --net=container:<containerAid> socat socat TCP-LISTEN:3306,fork TCP:BIP:3306
これにより、Aのネットワークでこのコンテナーが実行されます。そのため、Aのネットワークでリッスンすると、コンテナが触れられていなくても、localhost:3306
がAで利用可能になります。
ホストと同じネットワークモードでコンテナーを実行するだけです。
docker run --network=Host ...
その場合、コンテナーの観点からは、localhostまたは127.0.0.1がホストマシンを参照します。したがって、DBが3306でリッスンする別のコンテナBで実行されている場合、コンテナAのlocalhost:3306のアドレスは、コンテナBのデータベースにヒットします。
コンテナーBのポートをコンテナーAのlocalhostポートとして公開する場合は、network
オプションをcontainer
モードに設定してコンテナーBを開始し、コンテナーAのネットワーク名前空間でコンテナーBを開始できます。
例:
docker run --net=container:A postgres
どこ:
A
は、マップ先のコンテナーの名前または識別子です。これにより、A
と同じネットワーク名前空間のコンテナーでpostgresが起動するため、postgresコンテナーで開かれているポートはすべてA
と同じインターフェイスで開かれ、コンテナーA内のlocalhost
で使用できるようになります。
Docker-Compose で実行できます。
docker-compose.ymlの例:
version: '3'
services:
web:
build: .web
ports:
- "5000:5000"
mysql:
build: .mysql
ports:
- "3306:3306"
ここに2つのdockerインスタンスがあります:webとmysqlなので、各dockerインスタンスは、サービスとして定義した名前を使用してお互いを見ることができます。
お役に立てれば