【问题标题】:How ot map docker container ip to a host ip (NAT instead of NAPT)?如何将 docker 容器 ip 映射到主机 ip(NAT 而不是 NAPT)?
【发布时间】:2017-08-05 03:03:07
【问题描述】:

主要目标是做一个真正的 NAT 而不是 NAPT。注意正常的docker run -p ip:port2:port1 命令实际上是在做 NAPT(地址+端口转换)而不是 NAT(地址转换)。是否可以只映射地址,但保持所有暴露端口与容器相同,例如docker run -p=ip1:*:* ... ,而不是一个一个或一个范围?

ps.1。我的端口范围相当大(22-50070,ssh-hdfs),所以端口范围方法不起作用。
ps.2。也许我需要一组虚拟机并将主机加入到集群中。

ps.3 我提出了an feature request on github。不确定他们是否会接受它,但目前有 2000 多个未解决的问题(它非常受欢迎)。

解决方案

在 linux 上,你可以通过 ip 和 port 访问任何容器,无需任何绑定(没有-p)ootb。 Docker 版本:CE 17+

如果您的主机是 windows,并且 docker 运行在像我这样的 linux VM 上,要访问容器,唯一需要做的就是在 windows route add -p 172.16.0.0 mask 255.240.0.0 ip_of_your_vm 上添加路由。现在您可以通过 IP:port 访问所有容器,而无需从 windows 主机和 linux 虚拟机进行任何端口映射。

【问题讨论】:

  • 这意味着丢失主机上的每个端口,甚至是 SSH 端口。那么为什么要遵循这种方法呢?
  • 你可以使用空闲的ip地址。它不影响任何主机端口。这比默认的端口映射方法要好得多。
  • 所以你确实有一个空闲的 IP 可用。基于 IPTables 的解决方案适合您吗?
  • 你可以为你的 eth0 添加多个 IP。我还没有尝试过 iptables。我在win10上运行docker。

标签: docker nat


【解决方案1】:

您的选择很少。一种是决定要映射哪个 PORT 范围,然后在 docker run 中使用它

docker run -p 192.168.33.101:80-200:80-200 <your image>

Above 会将容器上从 80 的所有端口映射到 200。假设您的空闲 IP 是192.168.33.100。但不幸的是,无法映射更大的端口范围,因为 docker 创建了多个 iptables 分支来设置表并炸毁内存。它会引发如下错误

docker: Error response from daemon: driver failed programming external connectivity on endpoint zen_goodall (0ae6cec360831b46fe3668d6aad9f5f72b6dac5d26cc6c817452d1402d12f02c):  (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 8513 -j DNAT --to-destination 172.17.0.3:8513 ! -i docker0:  (fork/exec /sbin/iptables: resource temporarily unavailable)).

这不是 docker 映射它的正确方法。但这不是他们会同意的用例,因此可能无法解决上述问题。下一个选项是在不发布任何端口的情况下运行 docker 容器并使用以下 iptables 规则

DOCKER_IP=172.17.0.2
ACTION=A
IP=192.168.33.101

sudo iptables -t nat -$ACTION DOCKER -d $IP -j DNAT --to-destination $DOCKER_IP ! -i docker0
sudo iptables -t filter -$ACTION DOCKER ! -i docker0 -o docker0 -p tcp -d $DOCKER_IP -j ACCEPT
sudo iptables -t nat -$ACTION POSTROUTING -p tcp -s $DOCKER_IP -d $DOCKER_IP -j MASQUERADE

ACTION=A 将添加规则,ACTION=D 将删除规则。这将设置从您的IPDOCKER_IP 的完整流量。仅当您在测试服务器上执行此操作时才有用。不建议在分期或生产中使用。 Docker 添加了更多规则来防止其他容器插入您的容器,但这并没有提供任何保护

【讨论】:

  • Swarm 不是我想要的。我搬到Linux,我可以直接访问Linux上的IP(172.xx:xxx),这对我来说现在可以了。
【解决方案2】:

我认为没有直接的方法可以满足您的要求。 如果将“-P”选项与“docker run”一起使用,在 Dockerfile 中使用“EXPOSE”公开的所有端口将自动在主机中使用随机端口公开。使用“-p”选项,唯一的方法是为多个端口多次指定该选项。

【讨论】:

  • “随机端口”是指完全随机的端口,还是先尝试相同的端口,如果被占用则使用随机端口?
  • 我已经看到端口使用是连续的,即使文档说是随机的。我认为我们不应该依赖任何序列和端口号的重用。端口范围在 /proc/sys/net/ipv4/ip_local_port_range 中定义。
猜你喜欢
  • 2019-05-23
  • 2019-04-14
  • 1970-01-01
  • 2018-07-21
  • 2016-05-07
  • 1970-01-01
  • 2019-02-28
  • 1970-01-01
  • 2019-06-15
相关资源
最近更新 更多