博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用iptables给Docker绑定一个外网IP
阅读量:2389 次
发布时间:2019-05-10

本文共 2351 字,大约阅读时间需要 7 分钟。

背景

由于默认是不能够与外部进行直接的通信,比较普遍的仿佛是利用启动时-p来与主机进行端口映射与外界沟通。但是有时候在有其他需求时并不太方便,特别是在进行一些打包之前的内部开发时,希望其能够像虚机一样能够与外部有很好的通信,便希望其能够绑定外部的IP地址。 

docker默认的网络是桥接在创建好后的网桥docker0上的。docker0默认的典型地址为172.17.42.1,子网掩码为255.255.0.0。之后启动容器会给容器分配一个同一网段(172.17.0.0/16)的地址。然后启动docker容器时会创建一对veth pair。其中一端为容器内部的eth0,另外一端为挂载到docker0网桥并以veth开头命名。如下所示:

#brctl showbridge name bridge id STPenabled interfacesdocker0 8000.56847afe9799 no veth135f096veth5f8fe2d 
1
2
3
4
1
2
3
4

通过这种方式,容器可以跟主机以及容器之间进行通信,主机和容器共享虚拟网络。 

在做开发等时候,可能希望容器能够像虚机一样远程登录与访问,这时候就需要给容器再绑定一个外部IP地址,这时候即可考虑采用iptables进行端口转发来实现对于容器的外部IP绑定。

环境

一台ubuntu的服务器,所属网段为10.50.10.0/26,该服务器的IP为10.50.10.26,由于还使用了ovs,因此是该IP是在br-ex上的; 

一个ubuntu的容器,IP为172.17.0.1/26 。

目的

通过iptables为IP为172.17.0.1的容器绑定外部IP 这里为10.50.10.56.

过程

整个过程大致分为3部分:

1. 为主机绑定多个IP地址

这一步可以通过如下命令来给网桥绑定另外一个IP:

#ifconfig br-ex:010.50.10.56/24 
1
1

如果希望重启机器后仍然能够生效,需要将其写入到/etc/network/interfaces中。

2. iptables设置DNAT

通过DNAT来重写包的目的地址,将指向10.50.10.56的数据包的目的地址都改为172.17.0.1,这样即可以

#iptables -t nat -A PREROUTING -d 10.50.10.56 -p tcp -m tcp --dport 1:65535 -j DNAT--to-destination 172.17.0.1:1-65535 
1
1

3. iptables设置SNAT

重写包的源IP地址,即在容器中收到数据包之后,将其源改为docker0的地址。

#iptables -t nat -A POSTROUTING -d 172.17.0.1 -p tcp -m tcp --dport 1:65535 -j SNAT --to-source172.17.42.1 
1
1

保存规则

如果希望保存下来,需要通过命令:

#/etc/init.d/iptables save 
1
1

来进行保存。

删除规则

当然如果想删除该规则,也可以通过

# iptables –t nat –D PREROUTING 
# iptables –t nat –D POSTROUTING
1
2
1
2

来将创建的这两条规则删除。

验证

首先通过iptables来查看是否生效。

# iptables -n -t nat -LChain PREROUTING (policyACCEPT)target prot opt source destinationDNAT tcp -- 0.0.0.0/0 10.50.10.56 tcp dpts:1:65535to:172.17.0.1:1-65535Chain INPUT (policyACCEPT)target prot opt source destinationChain OUTPUT (policyACCEPT)target prot opt source destinationDOCKER all -- 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCALChain POSTROUTING (policyACCEPT)target prot opt source destinationMASQUERADE all -- 10.50.10.0/26 0.0.0.0/0MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0SNAT tcp -- 0.0.0.0/0 172.17.0.1 tcp dpts:1:65535 to:172.17.42.1 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14

然后可以通过安装ssh或者apache2等需要使用端口的服务来进行验证。

当然实现这个功能会有很多种方法,欢迎大家来拍砖~

参考

1,《Docker——从入门到实践》:高级网络配置 

 
2,The netfilter/iptables HOWTO’s 
 
3,Iptables 指南 

转自:

转载地址:http://aupab.baihongyu.com/

你可能感兴趣的文章
C++处理异常技巧-try,catch,throw,finally
查看>>
C++中的explicit关键字
查看>>
CDH(Cloudera)与hadoop(Apache)对比
查看>>
深入浅出解析大数据平台架构
查看>>
HTTP深入浅出 http请求
查看>>
zookeeper安装和应用场合(名字,配置,锁,队列,集群管理)
查看>>
浅析 Hadoop 中的数据倾斜
查看>>
白话经典算法系列之五 归并排序的实现
查看>>
白话经典算法系列之一 冒泡排序的三种实现
查看>>
tlb与dll文件区别
查看>>
生成COM Dll的tlb文件的两种方法
查看>>
Linux/CentOS关闭图形界面(X-window)和启用图形界面命令
查看>>
Paxos算法与Zookeeper分析
查看>>
哈希的原理和代价
查看>>
从头到尾彻底解析哈希表算法
查看>>
Bitmap算法
查看>>
数据挖掘、机器学习和模式识别关系与区别
查看>>
error C2470 错误记录与解决方法。“看起来像函数定义,但没有参数列表”
查看>>
创建COM组件的原理
查看>>
MFC中的CMenu---如何动态添加菜单/菜单项、子菜单、右键菜单
查看>>