Docker 网络配置 已翻译 100%

Yashin 投递于 2014/07/01 16:56 (共 28 段, 翻译完成于 07-04)
阅读 74973
收藏 197
15
加载中

摘要

当docker启动时,它会在宿主机器上创建一个名为docker0的虚拟网络接口。它会从RFC 1918定义的私有地址中随机选择一个主机不用的地址和子网掩码,并将它分配给docker0。例如当我启动docker几分钟后它选择了172.17.42.1/16-一个16位的子网掩码为主机和它的容器提供了65,534个ip地址。

注意: 本文讨论了Docker的高级网络配置和选项。通常你不会用到这些。如果你想查看一个较为简单的Docker网络介绍和容器概念介绍来着手,请参见Docker用户指南.

pseudo
pseudo
翻译于 2014/07/01 18:56
4

但docker0并不是正常的网络接口。它只是一个在绑定到这上面的其他网卡间自动转发数据包的虚拟以太网桥。它可以使容器与主机相互通信。每次Docker创建一个容器,它就会创建一对对等接口(peer interface),类似于一个管子的两端-在这边可以收到另一边发送的数据包。Docker会将对等接口中的一个做为eth0接口连接到容器上,并使用类似于vethAQI2QT这样的惟一名称来持有另一个,该名称取决于主机的命名空间。通过将所有veth*接口绑定到docker0桥接网卡上,Docker在主机和所有Docker容器间创建一个共享的虚拟子网。

本文其他部分将会讲解使用Docker选项的所有方式,并且-在高级模式下-使用纯linux网线配置命令来

调整,补充,或完全替代Docker的默认网络配置。

pseudo
pseudo
翻译于 2014/07/01 19:25
3

Docker选项快速指南

这里有一份关于Docker网络配置的命令行选项列表,省去您查找相关资料的麻烦。
一些网络配置的命令行选项只能在服务器启动时提供给Docker服务器。并且一旦启动起来就无法改变。

一些网络配置命令选项只能在启动时提供给Docker服务器,并且在运行中不能改变:

  • -b BRIDGE或--bridge=BRIDGE— see    建立自己的网桥

  • --bip=CIDR— see    定制docker0

  • -H SOCKET...或--host=SOCKET...—   它看起来像是在设置容器的网络,但实际却恰恰相反:它告诉Docker服务器要接收命令的通道,例如“run container"和"stop container"。

  • --icc=true|false— see    容器间通信

  • --ip=IP_ADDRESS— see    绑定容器端口

  • --ip-forward=true|false— see    容器间通信

  • --iptables=true|false— see   容器间通信

  • --mtu=BYTES— see    定制docker0

有两个网络配置选项可以在启动时或调用docker run时设置。当在启动时设置它会成为docker run的默认值:

  • --dns=IP_ADDRESS...— see    配置DNS

  • --dns-search=DOMAIN...— see    配置DNS

最后,一些网络配置选项只能在调用docker run时指出,因为它们要为每个容器做特定的配置:

接下来的部分会对以上话题从易到难做出逐一解答。

pseudo
pseudo
翻译于 2014/07/01 21:41
4

配置DNS

怎样为Docker提供的每一个容器进行主机名和DNS配置,而不必建立自定义镜像并将主机名写到里面?它的诀窍是覆盖三个至关重要的在/etc下的容器内的虚拟文件,那几个文件可以写入新的信息。你可以在容器内部运行mount看到这个:

$$ mount.../dev/disk/by-uuid/1fec...ebdf on /etc/hostname type ext4 .../dev/disk/by-uuid/1fec...ebdf on /etc/hosts type ext4 ...tmpfs on /etc/resolv.conf type tmpfs ......

这样的配置允许Docker去做聪明的事情,类似于当主机接收到新的DHCP配置之后,保持resolv.conf的数据到所有的容器中。Docker怎样维护在容器内的这些文件从Docker的一个版本到下一个版本的具体细节,你应该抛开这些单独的文件本身并且使用下面的Docker选项代替。

溪边九节
溪边九节
翻译于 2014/07/01 22:38
2

有四种不同的选项会影响容器守护进程的服务名称。

1. -h HOSTNAME 或者 --hostname=HOSTNAME  --设置容器的主机名,仅本机可见。这种方式是写到/etc/hostname ,以及/etc/hosts 文件中,作为容器主机IP的别名,并且将显示在容器的bash中。不过这种方式设置的主机名将不容易被容器之外可见。这将不会出现在 docker ps 或者 其他的容器的/etc/hosts 文件中。

2. --link=CONTAINER_NAME:ALIAS  --使用这个选项去run一个容器将在此容器的/etc/hosts文件中增加一个主机名ALIAS,这个主机名是名为CONTAINER_NAME 的容器的IP地址的别名。这使得新容器的内部进程可以访问主机名为ALIAS的容器而不用知道它的IP。--link= 关于这个选项的详细讨论请看:    Communication between containers.

3. --dns=IP_ADDRESS --设置DNS服务器的IP地址,写入到容器的/etc/resolv.conf文件中。当容器中的进程尝试访问不在/etc/hosts文件中的主机A时,容器将以53端口连接到IP_ADDRESS这个DNS服务器去搜寻主机A的IP地址。

4. --dns-search=DOMAIN --设置DNS服务器的搜索域,以防容器尝试访问不完整的主机名时从中检索相应的IP。这是写入到容器的/etc/resolv.conf文件中的。当容器尝试访问主机 host,而DNS搜索域被设置为 example.com ,那么DNS将不仅去查寻host主机的IP,还去查询host.example.com的IP。
 

在docker中,如果启动容器时缺少以上最后两种选项设置时,将使得容器的/etc/resolv.conf文件看起来和宿主主机的/etc/resolv.conf文件一致。这些选项将修改默认的设置。

Yashin
Yashin
翻译于 2014/07/02 11:09
2

容器间通信

在操作系统层面上,决定两个容器间的通信能否得到控制,有以下三个因素。

  1. 网络拓扑逻辑是否连接上了容器的网络接口。默认情况下Docker将把所有容器绑定到一个 singledocker0bridge,并为两个容器间的包传输提供路径。参见本文档后续部分---其他可能的拓扑逻辑

  2. 主机是否要发送IP包?这由ip_forward系统参数控制。如果这个参数设为1,那么数据包只能在容器间传输。通常情况下,让Docker服务器使用它的默认设置  --ip-forward=true ,   Docker在启动的时候会把ip_forwardsh.  要检查设置或手动设置参数,可以这样做:

    # Usually not necessary: turning on forwarding,# on the host where your Docker server is running$ cat /proc/sys/net/ipv4/ip_forward0$ sudo echo 1 > /proc/sys/net/ipv4/ip_forward
    $ cat /proc/sys/net/ipv4/ip_forward1

  3. iptables是否允许特殊连接?如果你把设置 --iptables=false,当守护进程启动时,Docker不会改变你的系统iptables规则。另外,如果你保留默认设置  --icc=true,Docker服务器或向FORWARD链添加一个带有全局ACCEPT策略的默认规则。如果不保留默认设置,系统会把策略设为DROP.

徐继开
徐继开
翻译于 2014/07/02 11:42
2

几乎所有人使用docker都希望ip_forward 是打开的,至少使容器间的通讯成为可能。但是否同意 --icc=true 或者更改为 --icc=false 使得iptables 可以保护容器以及宿主主机不被任意地端口扫描、避免被已经被渗透的容器所访问,这是一个策略问题。(在ubuntu,是编辑/etc/default/docker文件中的DOCKER_OPTS参数,然后重启docker服务)

如果你选择最安全的设置 --icc=false ,那么当你想让它们彼此提供服务的时候如何让它们相互通讯?

Yashin
Yashin
翻译于 2014/07/02 14:48
1

答案是:使用前文提到的 --link=CONTAINER_NAME:ALIAS 选项。如果docker守护进程正在以 --icc=false 和 --iptables=true 参数运行,当以选项 --link= 执行 docker run 命令时,docker服务将插入一部分 iptables ACCEPT 规则使得新容器可以连接其他容器所暴露出来的端口(此端口指前文在 Dockerfile 中提到的EXPOSE这一行)。更多详细文档介绍请看:linking Docker containers

注意: --link 选项中的 CONTAINER_NAME 的值必须是 docker自动分配的容器名称,比如 stupefied_pare, 或者是在执行docker run 的时候用 --name= 指定的容器名称.  这不能使一个docker无法识别的主机名。

Yashin
Yashin
翻译于 2014/07/02 15:08
1

你可以在你的Docker主机上运行iptables命令,来观察FORWARD链是否有默认的ACCEPT或DROP策略

# When --icc=false, you should see a DROP rule:$ sudo iptables -L -n...Chain FORWARD (policy ACCEPT)target     prot opt source               destination
DROP       all  --  0.0.0.0/0            0.0.0.0/0...# When a --link= has been created under --icc=false,# you should see port-specific ACCEPT rules overriding# the subsequent DROP policy for all other packets:$ sudo iptables -L -n...Chain FORWARD (policy ACCEPT)target     prot opt source               destination
ACCEPT     tcp  --  172.17.0.2           172.17.0.3           tcp spt:80ACCEPT     tcp  --  172.17.0.3           172.17.0.2           tcp dpt:80DROP       all  --  0.0.0.0/0            0.0.0.0/0

注意: Docker的iptables规则完全显示了容器相互间的原始IP地址,所以一个容器到另一个容器的连接,需要显示地显示出第一个容器的原始IP地址。

徐继开
徐继开
翻译于 2014/07/02 12:03
2

为主机绑定容器端口

默认情况下,Docker容器可以连接到外部区域,但外部区域不能连接到容器。在Docker启动时,由于它在主机上创建了一个iptables伪装规则,使得每一个输出连接看起来都是由主机IP地址建立起来的。

# You can see that the Docker server creates a# masquerade rule that let containers connect# to IP addresses in the outside world:$ sudo iptables -t nat -L -n...Chain POSTROUTING (policy ACCEPT)target     prot opt source               destination
MASQUERADE  all  --  172.17.0.0/16       !172.17.0.0/16...

当调用docker run的时候,如果你想让容器接受输入连接,你需要提供特殊选项。这些选项的详细说明在 Docker User Guide.  有两种方法可以实现。

徐继开
徐继开
翻译于 2014/07/02 12:32
3
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(19)

hans汉斯
hans汉斯

引用来自“高榕”的评论

怎么把容器的ip设置成和宿主机同一个网段的啊!!

引用来自“dwl301”的评论

在宿主机上设置一个br0网桥,桥接你宿主机的物理网卡,起docker服务前修改/etc/default/docker,加上一句DOCKER_OPTS="-b=br0"

引用来自“SimonYe”的评论

设置成同一网段可以,但是与其他宿主机器无法通信,路由器都ping不通
你的主机应该是虚拟机,使用物理机就不会了。
SimonYe
SimonYe

引用来自“高榕”的评论

怎么把容器的ip设置成和宿主机同一个网段的啊!!

引用来自“dwl301”的评论

在宿主机上设置一个br0网桥,桥接你宿主机的物理网卡,起docker服务前修改/etc/default/docker,加上一句DOCKER_OPTS="-b=br0"
设置成同一网段可以,但是与其他宿主机器无法通信,路由器都ping不通
Xsank
Xsank
docker容器中的peth0是什么?
dwl301
dwl301

引用来自“高榕”的评论

怎么把容器的ip设置成和宿主机同一个网段的啊!!
在宿主机上设置一个br0网桥,桥接你宿主机的物理网卡,起docker服务前修改/etc/default/docker,加上一句DOCKER_OPTS="-b=br0"
fdumpling
fdumpling
赞一个~
高榕
高榕
怎么把容器的ip设置成和宿主机同一个网段的啊!!
z
zx32342342

引用来自“libin580”的评论

Docker的优势是什么?对这东西模棱两可。

引用来自“neo-chen”的评论

Docker 的优势是与KVM相比,不需要每个虚拟设备安装一个OS。 相当于半虚拟化,速度应该快很多

引用来自“neo-chen”的评论

我觉得 Docker 更像FreeBSD 的 Jail

引用来自“Feng_Yu”的评论

chroot增强版
赞, 比如测试东西, 就不用把自己电脑搞的乱七八糟了
skywalk
skywalk

引用来自“libin580”的评论

Docker的优势是什么?对这东西模棱两可。

引用来自“neo-chen”的评论

Docker 的优势是与KVM相比,不需要每个虚拟设备安装一个OS。 相当于半虚拟化,速度应该快很多

引用来自“neo-chen”的评论

我觉得 Docker 更像FreeBSD 的 Jail
呵呵,本来没看懂,但是说到像jail,我稍微有点懂了。
love5783
love5783
正在学习docker,mark一下。
libin580
libin580
感谢楼上回复的所有基友,本以为又是概念炒作,看来有实际用途,不错,赞一个!
返回顶部
顶部