From 23d4e36c64b7a16694105ca6686e2cbc4a4f6f4d Mon Sep 17 00:00:00 2001 From: Baohua Yang Date: Thu, 18 Sep 2014 17:38:20 +0800 Subject: [PATCH] rewrite the advanced network chapter --- SUMMARY.md | 18 +++--- advanced_network/README.md | 1 - advanced_network/access_control.md | 55 ++++++++++++++++ advanced_network/bridge.md | 23 ++++--- advanced_network/communication.md | 41 ------------ advanced_network/docker0.md | 24 +++---- advanced_network/example.md | 10 +-- advanced_network/how_connect.md | 62 ------------------- advanced_network/port_mapping.md | 38 +++++++----- advanced_network/ptp.md | 21 ++++--- .../{fast_config.md => quick_guide.md} | 0 11 files changed, 130 insertions(+), 163 deletions(-) create mode 100644 advanced_network/access_control.md delete mode 100644 advanced_network/communication.md rename advanced_network/{fast_config.md => quick_guide.md} (100%) diff --git a/SUMMARY.md b/SUMMARY.md index 3662b47..771644f 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -32,19 +32,19 @@ * [数据卷](data_management/volume.md) * [数据卷容器](data_management/container.md) * [备份、恢复、迁移数据卷](data_management/management.md) -* [网络和互联](network/README.md) - * [端口映射](network/port_mapping.md) +* [基本网络功能](network/README.md) + * [外部访问容器](network/port_mapping.md) * [容器互联](network/linking.md) * [高级网络配置](advanced_network/README.md) - * [快速配置指南](advanced_network/fast_config.md) + * [快速配置指南](advanced_network/quick_guide.md) * [配置DNS](advanced_network/dns.md) - * [容器之间的通信](advanced_network/communication.md) - * [映射一个容器端口到宿主主机](advanced_network/port_mapping.md) - * [定制docker0](advanced_network/docker0.md) - * [创建自己的桥接](advanced_network/bridge.md) - * [Docker 如何连接到容器](advanced_network/how_connect.md) + * [容器访问控制](advanced_network/access_control.md) + * [端口映射实现](advanced_network/port_mapping.md) + * [配置docker0](advanced_network/docker0.md) + * [自定义网桥](advanced_network/bridge.md) * [工具和示例](advanced_network/example.md) - * [创建一个点到点连接](advanced_network/ptp.md) + * [编辑网络配置文件](advanced_network/config_file.md) + * [实例:创建一个点到点连接](advanced_network/ptp.md) * [容器安全](container_security/README.md) * [内核名字空间](container_security/kernel_ns.md) * [控制组](container_security/control_group.md) diff --git a/advanced_network/README.md b/advanced_network/README.md index 25bbd42..e3998db 100644 --- a/advanced_network/README.md +++ b/advanced_network/README.md @@ -7,7 +7,6 @@ 当创建一个Docker容器的时候,同时会创建了一对`veth pair`接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即`eth0`;另一端在本地并被挂载到`docker0`网桥,名称以`veth`开头(例如`vethAQI2QT`)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。Docker就创建了在主机和所有容器之间一个虚拟共享网络。 - ![Docker网络](../_images/network.png) 接下来的部分将介绍在一些场景中,docker所有的网络定制配置。linux的原生命令将调整、补充、甚至替换docker默认的网络配置。 diff --git a/advanced_network/access_control.md b/advanced_network/access_control.md new file mode 100644 index 0000000..d8f3111 --- /dev/null +++ b/advanced_network/access_control.md @@ -0,0 +1,55 @@ +## 容器访问控制 +容器的访问控制,主要通过Linux上的`iptables`防火墙来进行管理和实现。`iptables`是Linux上默认的防火墙软件,在大部分发行版中都自带。 + +### 容器访问外部网络 +容器要想访问外部网络,需要本地系统的转发支持。在Linux系统中,检查转发是否打开。 + +``` +$sysctl net.ipv4.ip_forward +net.ipv4.ip_forward = 1 +``` +如果为0,说明没有开启转发,则需要手动打开。 +``` +$sysctl -w net.ipv4.ip_forward=1 +``` +如果在启动Docker服务的时候设定`--ip-forward=true`, Docker就会自动设定系统的`ip_forward`参数为1。 + +### 容器之间访问 +容器之间相互访问,需要两方面的支持。 +* 容器的网络拓扑是否已经互联。默认情况下,所有容器都会被连接到`docker0`网桥上。 +* 本地系统的防火墙软件 -- `iptables`是否允许通过。 + +#### 访问所有端口 +当启动Docker服务时候,默认会添加一条转发策略到iptables的FORWARD链上。策略为通过(`ACCEPT`)还是禁止(`DROP`)取决于配置`--icc=true`(缺省值)还是`--icc=false`。当然,如果手动指定`--iptables=false`则不会添加`iptables`规则。 + +可见,默认情况下,不同容器之间是允许网络相互访问的。如果为了安全考虑,可以在`/etc/default/docker`文件中配置`DOCKER_OPTS=--icc=false`来禁止它。 + +#### 访问指定端口 +在通过`-icc=false`关闭网络访问后,还可以通过`--link=CONTAINER_NAME:ALIAS`选项来访问容器的开放端口。 + +例如,在启动Docker服务时,可以同时使用`icc=false --iptables=true`2个参数来关闭允许相互的网络访问,并让Docker可以修改系统中的`iptables`规则。 + +此时,系统中的`iptables`规则可能是类似 +``` +$ sudo iptables -nL +... +Chain FORWARD (policy ACCEPT) +target prot opt source destination +DROP all -- 0.0.0.0/0 0.0.0.0/0 +... +``` + +之后,启动容器(`docker run`)时使用`--link=CONTAINER_NAME:ALIAS`选项。docker会在`iptable`中为2个容器分别添加一条`ACCEPT`规则,允许相互访问开放的端口(取决于dockerfile中的EXPOSE行)。 + +当添加了`--link=CONTAINER_NAME:ALIAS`选项后,添加了`iptables`规则。 +``` +$ sudo iptables -nL +... +Chain FORWARD (policy ACCEPT) +target prot opt source destination +ACCEPT tcp -- 172.17.0.2 172.17.0.3 tcp spt:80 +ACCEPT tcp -- 172.17.0.3 172.17.0.2 tcp dpt:80 +DROP all -- 0.0.0.0/0 0.0.0.0/0 +``` + +注意:`--link=CONTAINER_NAME:ALIAS`中的`CONTAINER_NAME`目前必须是Docker分配的名字,或使用`--name`参数指定的名字。主机名则不会被识别。 diff --git a/advanced_network/bridge.md b/advanced_network/bridge.md index 1060c85..62e1587 100644 --- a/advanced_network/bridge.md +++ b/advanced_network/bridge.md @@ -1,31 +1,34 @@ -##创建自己的桥接 -如果希望完全使用自己的桥接设置,可以在启动docker服务的时候,使用 -b BRIDGE or --bridge=BRIDGE 来告诉docker使用你的网桥。如果服务已经启动,旧的网桥还在使用中,那需要先停止服务,再删除旧的网桥 +##自定义网桥 +除了默认的`docker0`网桥,用户也可以指定网桥来连接各个容器。 + +在启动Docker服务的时候,使用`-b BRIDGE`或`--bridge=BRIDGE`来指定使用的网桥。 + +如果服务已经运行,那需要先停止服务,并删除旧的网桥。 ``` -#停止旧网桥并删除 $ sudo service docker stop $ sudo ip link set dev docker0 down $ sudo brctl delbr docker0 ``` -然后在开启服务前,创建你自己希望的网桥接口,这里建立一个网桥的配置: +然后创建一个网桥`bridge0`。 ``` -# 创建自己的网桥 $ sudo brctl addbr bridge0 $ sudo ip addr add 192.168.5.1/24 dev bridge0 $ sudo ip link set dev bridge0 up ``` +查看确认网桥创建并启动。 ``` -# 确认网桥启动 $ ip addr show bridge0 4: bridge0: mtu 1500 qdisc noop state UP group default link/ether 66:38:d0:0d:76:18 brd ff:ff:ff:ff:ff:ff inet 192.168.5.1/24 scope global bridge0 valid_lft forever preferred_lft forever ``` - +配置Docker服务,默认桥接到创建的网桥上。 ``` -# 告诉docker桥接设置,并启动docker服务(在ubuntu上) $ echo 'DOCKER_OPTS="-b=bridge0"' >> /etc/default/docker $ sudo service docker start ``` -docker服务启动成功并绑定容器到新的网桥,新建一个容器,你会看到它的ip是我们的设置的新ip段,docker会自动检测到它。用brctl -show可以看到容器启动或则停止后网桥的配置变化,在容器中使用```ip addr```和```ip route```来查看ip地址配置和路由信息。 \ No newline at end of file +启动Docker服务。 +新建一个容器,可以看到它已经桥接到了`bridge0`上。 + +可以继续用`brctl show`命令查看桥接的信息。另外,在容器中可以使用`ip addr`和`ip route`命令来查看ip地址配置和路由信息。 diff --git a/advanced_network/communication.md b/advanced_network/communication.md deleted file mode 100644 index 22e3bde..0000000 --- a/advanced_network/communication.md +++ /dev/null @@ -1,41 +0,0 @@ -##容器之间的通信 -判断2个容器之间是否能够通信,在操作系统层面,取决于3个因素: -* 网络拓扑是否连接到容器的网络接口?默认docker会将所有的容器连接到docker0这网桥来提供数据包通信。其他拓扑结构将在稍后的文档中详细介绍。 -* 主机是否开启ip转发,ip_forward参数为1的时候可以提供数据包转发。通常你只需要为docker 设定 --ip-forward=true, -docker 就会在服务启动的时候设定ip_forward参数为1。 - -下面是手工检查并手工设定该参数的方法。 -``` -# Usually not necessary: turning on forwarding, -# on the host where your Docker server is running -$ cat /proc/sys/net/ipv4/ip_forward -0 -$ sudo echo 1 > /proc/sys/net/ipv4/ip_forward -$ cat /proc/sys/net/ipv4/ip_forward -1 -``` -*你的iptables是否允许这条特殊的连接被建立?当docker的设定--iptables=false时,docker不会改变系统的iptables -设定,否则它会在--icc=true的时候添加一条默认的ACCEPT策略到 FORWARD链,当—icc=false时,策略为DROP。几乎所有的人都会开启ip_forward来启用容器间的通信。但是否要改变icc-true配置是一个战略问题。这样iptable就可以防止其他被感染容器对宿主主机的恶意端口扫描和访问。 -当你选择更安全的设定--icc=false后,如何保持你希望的容器之间通信呢? -答案就是--link=CONTAINER_NAME:ALIAS选项,在之前的dns服务设定中提及过。如果docker 使用icc=false and --iptables=true 2个参数,当docker run使用--link=选型时,docker会为2个容器在iptable中参数一对ACCEPT规则,开放的端口取决与dockerfile中的EXPOSE行,详见第五章。 -注意:--link= 中的CONTAINER_NAME 必须是自动生成的docker名字比如stupefied_pare,或者你用--name参数指定的名字,主机名在--link中不会被识别。 -你可以使用iptables命令来检查FORWARD链是ACCEPT 还是DROP -当--icc=false时,默认规则应该是这样 -``` -$ 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 -... -``` -当添加了--link后,ACCEPT规则被改写了,添加了新的端口和IP规则 -``` -$ 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:80 -ACCEPT tcp -- 172.17.0.3 172.17.0.2 tcp dpt:80 -DROP all -- 0.0.0.0/0 0.0.0.0/0 -``` diff --git a/advanced_network/docker0.md b/advanced_network/docker0.md index 95c749a..0ae1158 100644 --- a/advanced_network/docker0.md +++ b/advanced_network/docker0.md @@ -1,19 +1,22 @@ -##定制docker0 -docker服务默认会创建一个docker0接口,它在linux内核层桥接所有物理或虚拟网卡,这就将所有容器和主机接口都放到同一个物理网络。 -Docker指定了docker0的ip地址和子网掩码,让主机和容器之间可以通过网桥相互通信,它还给出了MTU-接口允许接收的最大传输单元,通常是1500bytes或宿主主机网络路由上支持的默认值,这2个都需要在服务启动的时候配置。 -* --bip=CIDR — 192.168.1.5/24.ip地址加掩码 使用这种格式 -* --mtu=BYTES — 覆盖默认的docker mtu配置 +##配置docker0 +Docker服务默认会创建一个`docker0`接口,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。 -你可以在配置文件中配置DOCKER_OPTS,然后重启来改变这些参数。 +Docker默认指定了`docker0`的IP地址和子网掩码,让主机和容器之间可以通过网桥相互通信,它还给出了MTU(接口允许接收的最大传输单元),通常是1500bytes,或宿主主机网络路由上支持的默认值,这2个都可以在服务启动的时候进行配置。 +* --bip=CIDR -- IP地址加掩码格式,例如192.168.1.5/24 +* --mtu=BYTES -- 覆盖默认的Docker mtu配置 + +也可以在配置文件中配置DOCKER_OPTS,然后重启服务。 +由于目前Docker网桥是Linux网桥,用户可以使用`brctl show`来查看网桥和端口连接信息。 ``` -# 当容器启动后,你可以使用brctl来确认他们是否已经连接到docker0网桥 $ sudo brctl show bridge name bridge id STP enabled interfaces docker0 8000.3a1d7362b4ee no veth65f9 vethdda6 -``` -如果brctl命令没安装的话,在ubuntu中你可以使用apt-get install bridge-utils这个命令来安装 -docker0 网桥设置会在每次创建新容器的时候被使用。docker从可用的地址段中选择一个空闲的ip地址给容器的eth0端口,子网掩码使用网桥docker0的配置,docker主机本身的ip作为容器的网关使用。 +``` +注:`brctl`命令在Debian、Ubuntu中可以使用`sudo apt-get install bridge-utils`来安装。 + + +每次创建一个新容器的时候,Docker从可用的地址段中选择一个空闲的ip地址分配给容器的eth0端口。Docker主机上接口`docker0`的IP作为所有容器的默认网关。 ``` $ sudo docker run -i -t --rm base /bin/bash $ ip addr show eth0 @@ -28,4 +31,3 @@ default via 172.17.42.1 dev eth0 172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.3 $ exit ``` -转发数据包需要在主机上设定ip_forward参数为1,上文介绍过。 \ No newline at end of file diff --git a/advanced_network/example.md b/advanced_network/example.md index 2379646..e31ea27 100644 --- a/advanced_network/example.md +++ b/advanced_network/example.md @@ -1,8 +1,8 @@ ##工具和示例 在介绍自定义网络拓扑之前,你可能会对一些外部工具和例子感兴趣: -https://github.com/jpetazzo/pipework -Jérôme Petazzoni 创建了一个叫pipework的shell脚本来帮助我们在复杂的场景中完成网络连接 -https://github.com/brandon-rhodes/fopnp/tree/m/playground -Brandon Rhodes创建了一个完整的docker容器网络拓扑,包含 nat 防火墙,服务包括HTTP, SMTP, POP, IMAP, Telnet, SSH, and FTP: -工具使用的网络命令跟之前看到非常相似。 +### pipework +Jérôme Petazzoni编写了一个叫[pipework](https://github.com/jpetazzo/pipework)的shell脚本,可以帮助用户在比较复杂的场景中完成容器的连接。 + +### playground +Brandon Rhodes创建了一个提供完整的Docker容器网络拓扑管理的[Python库](https://github.com/brandon-rhodes/fopnp/tree/m/playground),包括路由、NAT防火墙;以及一些提供HTTP, SMTP, POP, IMAP, Telnet, SSH, FTP的服务器。 diff --git a/advanced_network/how_connect.md b/advanced_network/how_connect.md index 559c429..8b13789 100644 --- a/advanced_network/how_connect.md +++ b/advanced_network/how_connect.md @@ -1,63 +1 @@ -##Docker 如何连接到容器? -让我们回顾一些基础知识: -机器需要一个网络接口来发送和接受数据包,路由表来定义如何到达哪些地址段。这里的网络接口可以不是物理接口。 - -事实上,每个linxu机器上的lo环回接口(Docker 容器中也有)就是一个完整的linux内核虚拟接口,它直接复制发送缓存中的数据包到接收缓存中。Docker让宿主主机和容器使用特殊的虚拟接口来通信--通信的2端叫“peers“,他们在主机内核中连接在一起,所以能够相互通信。创建他们很简单,前面介绍过了。 - -docker创建容器的步骤如下: -* 创建一对虚拟接口 -* 其中宿主主机一端使用一个名字比如veth65f9,他是唯一的,另外一端桥接到默认的docker0,或其它你指定的桥接网卡。 -* 主机上的veth65f9这种接口映射到新的新容器中的名称通常是eth0,在容器这个隔离的network namespace -中,它是唯一的,不会有其他接口名字和它冲突。 -* 从主机桥接网卡的地址段中获取一个空闲地址给eth0使用,并设定默认路由到桥接网卡。 -* 完成这些之后,容器就可以使用这eth0虚拟网卡来连接其他容器和其他网络。 - -你也可以为特殊的容器设定特定的参数,在docker run的时候使用--net,它有4个可选参数: -* --net=bridge — .默认连接到docker0网桥。 -* --net=host — 告诉docker不要将容器放到隔离的网络堆栈中。从本质上讲,这个选项告诉docker -不要容器化容器的网络!尽管容器还是有自己的文件系统、进程列表和资源限制。但使用ip addr命令这样命令就可以知道实际上此时的的容器处于和docker 宿主主机的一样的网络级别,它拥有完全的宿主主机接口访问权限。虽然它不允许容器重新配置主机的网络堆栈,除非--privileged=true — 但是容器进程可以跟其他root进程一样可以打开低数字的端口,可以访问本地网络服务比如D-bus,还可以让容器做一些意想不到的事情,比如重启主机,使用这个选项的时候要非常小心! -* --net=container:NAME_or_ID — -告诉docker将新容器的进程放到一个已经存在的容器的网络堆栈中,新容器进程有它自己的文件系统、进程列表和资源限制,但它会和那个已经存在的容器共享ip地址和端口,他们之间来可以通过环回接口通信。 -* --net=none — 告诉docker将新容器放到自己的网络堆栈中,但是不要配置它的网络, -类似于vmware的host-only。这可以让你创建任何自定义的配置,本文最后一段将介绍 他们。 - -下面通过配置一个以--net=none启动的容器,使他达到跟平常一样具有访问网络的权限。来介绍docker是如何连接到容器中的。 - -启动一个/bin/bash 指定--net=none -``` -$ sudo docker run -i -t --rm --net=none base /bin/bash -root@63f36fc01b5f:/# -``` -再开启一个新的终端,查找这个容器的进程id,然后创建它的命名空间,后面的ip netns会用到 -``` -$ sudo docker inspect -f '{{.State.Pid}}' 63f36fc01b5f -2778 -$ pid=2778 -$ sudo mkdir -p /var/run/netns -$ sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid -``` -检查桥接网卡的ip和子网掩码 -``` -$ ip addr show docker0 -21: docker0: ... -inet 172.17.42.1/16 scope global docker0 -... -``` -创建一对”peer“接口A和B,绑定A到网桥,并启用它 -``` -$ sudo ip link add A type veth peer name B -$ sudo brctl addif docker0 A -$ sudo ip link set A up -``` -将B放到容器的网络命名空间,命名为eth0,配置一个空闲的ip -``` -$ sudo ip link set B netns $pid -$ sudo ip netns exec $pid ip link set dev B name eth0 -$ sudo ip netns exec $pid ip link set eth0 up -$ sudo ip netns exec $pid ip addr add 172.17.42.99/16 dev eth0 -$ sudo ip netns exec $pid ip route add default via 172.17.42.1 -``` -自此,你又可以像平常一样使用网络了 -当你退出shell后,docker清空容器,容器的eth0随网络命名空间一起被摧毁,A 接口也被自动从docker0取消注册。不用其他命令,所有东西都被清理掉了! -注意ip netns exec命令,它可以让我们像root一样配置网络命名空间。但在容器内部无法使用,因为统一的安全策略,docker限制容器进程配置自己的网络。使用ip netns exec 可以让我们不用设置--privileged=true就可以完成一些可能带来危险的操作。 diff --git a/advanced_network/port_mapping.md b/advanced_network/port_mapping.md index 9be9937..0145d23 100644 --- a/advanced_network/port_mapping.md +++ b/advanced_network/port_mapping.md @@ -1,37 +1,43 @@ -##映射一个容器端口到宿主主机 +##映射容器端口到宿主主机的实现 -默认情况下,容器可以建立到外部网络的连接,但是外部网络无法连接到容器。所有到外部的连接,源地址都会被伪装成宿主主机的ip地址,iptables的 masquerading来做到这一点。 +默认情况下,容器可以主动访问到外部网络的连接,但是外部网络无法访问到容器。 +### 容器访问外部实现 +容器所有到外部网络的连接,源地址都会被NAT成本地系统的IP地址。这是使用`iptables`的源地址伪装操作实现的。 +查看主机的NAT规则。 ``` -# 查看主机的masquerading规则 -$ sudo iptables -t nat -L -n +$ sudo iptables -t nat -nL ... Chain POSTROUTING (policy ACCEPT) target prot opt source destination MASQUERADE all -- 172.17.0.0/16 !172.17.0.0/16 ... ``` +其中,上述规则将所有源地址在`172.17.0.0/16`网段,目标地址为其他网段(外部网络)的流量动态伪装为从系统网卡发出。MASQUERADE跟传统SNAT的好处是它能动态从网卡获取地址。 -当你希望容器接收外部连接时,你需要在docker run执行的时候就指定对应选项,第五章详细介绍了2种方法: -* 指定-P --publish-all=true|false 选项会映射dockerfile -中expose的所有端口,主机端口在49000-49900中随机挑选。当你的另外一个容器需要学习这个端口时候,很不方便。 -* 指定-p SPEC或则 --publish=SPEC,可以指定任意端口从主机映射容器内部 +### 外部访问容器实现 -不管用那种办法,你可以通过查看iptable的 nat表来观察docker 在网络层做了什么操作。 +容器允许外部访问,可以在`docker run`时候通过`-p`或`-P`参数来启用。 + +不管用那种办法,其实也是在本地的`iptable`的nat表中添加相应的规则。 + +使用`-P`时: ``` -#使用-P时: -$ iptables -t nat -L -n +$ iptables -t nat -nL ... Chain DOCKER (2 references) target prot opt source destination DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:49153 to:172.17.0.2:80 -#使用-p 80:80时: -$ iptables -t nat -L -n +``` + +使用`-p 80:80`时: +``` +$ iptables -t nat -nL Chain DOCKER (2 references) target prot opt source destination DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.17.0.2:80 ``` 注意: -* 这里看到docker映射了0.0.0.0.它接受主机上的所有接口地址。可以通过-p IP:host_port:container_port 或则 -p -IP::port 来指定主机上的ip、接口,制定更严格的规则。 -* 如果你希望永久改变绑定的主机ip地址,可以 在dcoker 配置中指定--ip=IP_ADDRESS. 记得重启服务。 +* 这里的规则映射了0.0.0.0,意味着将接受主机来自所有接口的流量。用户可以通过`-p IP:host_port:container_port`或`-p +IP::port`来指定允许访问容器的主机上的IP、接口等,以制定更严格的规则。 +* 如果希望永久绑定到某个固定的IP地址,可以在Docker 配置文件`/etc/default/docker`中指定`DOCKER_OPTS="--ip=IP_ADDRESS"`,之后重启Docker服务即可生效。 diff --git a/advanced_network/ptp.md b/advanced_network/ptp.md index 8b77c3d..3d20232 100644 --- a/advanced_network/ptp.md +++ b/advanced_network/ptp.md @@ -1,7 +1,11 @@ -##创建一个点到点连接 -默认Docker会将所有容器连接到由docker0提供的虚拟子网,你也可以使用自己创建的网桥。但如果你想要2个特殊的容器之间可以直连通信,而不用去配置复杂的主机网卡桥接。 +##示例:创建一个点到点连接 +默认情况下,Docker会将所有容器连接到由`docker0`提供的虚拟子网中。 -解决办法很简单:创建一对接口,把2个容器放到这对接口中,配置成点到点链路类型。这2个容器就可以直接通信了。首先启动2个容器: +用户有时候需要2个容器之间可以直连通信,而不用通过主机网桥进行桥接。 + +解决办法很简单:创建一对“peer”接口,分别放到2个容器中,配置成点到点链路类型即可。 + +首先启动2个容器: ``` $ sudo docker run -i -t --rm --net=none base /bin/bash root@1f1f4c1f931a:/# @@ -9,7 +13,7 @@ $ sudo docker run -i -t --rm --net=none base /bin/bash root@12e343489d2f:/# ``` -找到他们的进程号,然后创建他们的 namespace entries +找到进程号,然后创建网络名字空间的跟踪文件。 ``` $ sudo docker inspect -f '{{.State.Pid}}' 1f1f4c1f931a 2989 @@ -20,7 +24,7 @@ $ sudo ln -s /proc/2989/ns/net /var/run/netns/2989 $ sudo ln -s /proc/3004/ns/net /var/run/netns/3004 ``` -创建"peer"接口,然后配置路由 +创建一对“peer”接口,然后配置路由 ``` $ sudo ip link add A type veth peer name B @@ -34,7 +38,8 @@ $ sudo ip netns exec 3004 ip addr add 10.1.1.2/32 dev B $ sudo ip netns exec 3004 ip link set B up $ sudo ip netns exec 3004 ip route add 10.1.1.1/32 dev B ``` -现在这2个容器就可以相互ping通,并成功建立连接。点到点链路不需要子网和子网掩码,使用`ip route`来连接单个ip地址到指定的网络接口。 -如果没有特殊需要你不需要指定`--net=none`来创建点到点链路。 +现在这2个容器就可以相互ping通,并成功建立连接。点到点链路不需要子网和子网掩码。 -还有一个办法就是创建一个只跟主机通信的容器,除非有特殊需求,你可以仅用`--icc=false`来限制主机间的通信。 +此外,也可以不指定`--net=none`来创建点到点链路。这样容器还可以通过原先的网络来通信。 + +利用类似的办法,可以创建一个只跟主机通信的容器。但是一般情况下,更推荐使用`--icc=false`来关闭容器之间的通信。 diff --git a/advanced_network/fast_config.md b/advanced_network/quick_guide.md similarity index 100% rename from advanced_network/fast_config.md rename to advanced_network/quick_guide.md