我有两个 Docker 容器,我正尝试以特定方式将它们联网。容器 A 在端口 6379 上运行 Redis 服务器。容器 B 正在运行交互式 shell 并需要访问 Redis。使用 Docker 的链接功能,容器 B 内的用户可以通过 10.1.0.2:6379 连接到 Redis,该端口通过 Docker 设置的虚拟 eth0 接口传输。
容器 B 中将运行一个程序,该程序要求 Redis 在环回接口的 6379 端口可用。假设此程序无法配置为指向其他 IP。
我想将流量从 127.0.0.1:6379 转发到 10.1.0.2:6379。我尝试了 NAT 表上的几种 iptables 规则,但尝试连接到本地地址/端口时,要么出现“连接被拒绝”提示,要么连接永远挂起。我可以使用哪些 iptables 规则来实现此效果?
这是我尝试过的事情之一:
$ 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
尝试使用上述规则连接到 Redisredis-cli
只会永远挂起。我尝试过使用 PREROUTING/POSTROUTING 而不是 INPUT/OUTPUT 的版本,结果立即出现“连接被拒绝”的情况。
答案1
我会使用 socat 来实现这一点:
socat TCP-LISTEN:6379,fork TCP:10.1.0.2:6379
您可能希望使用 Supervisor 或类似工具来运行它。在 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
它还会在启动时自动启动。