web-dev-qa-db-ja.com

ループバックインターフェイスのポートをリモートIP /ポートに転送する

特定の方法でネットワークを構築しようとしている2つのDockerコンテナがあります。コンテナAはポート6379でRedisサーバーを実行しています。コンテナBはインタラクティブシェルを実行しており、Redisにアクセスする必要があります。 Dockerのリンク機能を使用すると、コンテナーB内のユーザーは10.1.0.2:6379を介してRedisに接続できます。これは、Dockerによってセットアップされた仮想eth0インターフェースを介して移動します。

ループバックインターフェイスのポート6379でRedisが利用可能であることを期待するコンテナBで実行されるプログラムがあります。このプログラムは、別のIPを指すように構成できないと想定します。

トラフィックを127.0.0.1:6379から10.1.0.2:6379に転送したいと思います。 NATテーブルでiptablesルールのいくつかのバリエーションを試しましたが、ローカルアドレス/ポートに接続しようとすると「接続が拒否されました」か、接続が永久にハングします。どのiptablesこの効果を達成するためにルールを使用できますか?

これが私が試したことの1つです:

$ Sudo iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-A INPUT -d 10.1.0.2/32 -p tcp -m tcp --dport 6379 -j SNAT --to-source 127.0.0.1
-A OUTPUT -p tcp -m tcp --dport 6379 -j DNAT --to-destination 10.1.0.2:6379

上記のルールを使用してredis-cliでRedisに接続しようとすると、永久にハングします。 INPUT/OUTPUTの代わりにPREROUTING/POSTROUTINGを使用するバージョンを試しましたが、すぐに「接続が拒否されました」。

5
Jimmy Cuadra

私はそのためにsocatを使用します:

socat TCP-LISTEN:6379,fork TCP:10.1.0.2:6379

スーパーバイザーまたは同様のツールを使用してこれを実行することをお勧めします。 Ubuntuについて:

apt-get install socat supervisor

cat > /etc/supervisor/conf.d/redis-socat.conf << EOF
[program:redis-socat]
command = socat TCP-LISTEN:6379,fork TCP:10.1.0.2:6379
autorestart = true
user = nobody
EOF

supervisorctl reload

これで、以下を使用してredis-socatプロセスを開始/停止できます。

supervisorctl start redis-socat 
supervisorctl stop redis-socat

また、起動時に自動的に起動します。

3
andrekeller