Docker网络配置教程

时间:2020-03-21 11:42:21  来源:igfitidea点击:

了解Docker的网络部分非常重要,因为Docker的主要用例是创建用户或者其他服务将连接并通信的服务。

让我们开始了解Docker容器的默认网络配置。
让我们启动一个ubuntu默认docker容器,并分析其默认网络配置以了解发生了什么。

root@ip-10-1-136-71:~# docker run -it --rm ubuntu
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
0bf056161913: Pull complete
1796d1c62d0c: Pull complete
e24428725dd6: Pull complete
89d5d8e8bafb: Pull complete
Digest: sha256:a2b67b6107aa640044c25a03b9e06e2a2d48c95be6ac17fb1a387e75eebafd7c
Status: Downloaded newer image for ubuntu:latest
root@1dfa7ba191a9:/# ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:02  
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe11:2/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1
          RX packets:16 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1296 (1.2 KB)  TX bytes:648 (648.0 B)
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

上面显示的第一个命令运行默认的ubuntu:latest容器。
现在,由于系统没有该镜像,因此可以从dockerhub下载该镜像并以交互方式运行它。
提取图像并启动容器后,我们将进入容器shell提示符(由root @ 1dfa7ba191a9显示。
此处1dfa7ba191a9是容器ID。

然后,我们启动基本的ifconfig命令,以查看我们在容器内获得的默认IP地址。

eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:02  
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0

因此,该容器的IP地址为172.17.0.2,网络掩码为255.255.0.0。
这意味着默认的docker内部网络将始终具有172.17.0.0/16的网络CIDR。
默认情况下总是如此。

现在,让我们看看底层主机如何处理此网络。
让我们通过键入exit或者CTRL + D从容器中退出。
一旦我们从容器中退出,就可以看到基础主机的ifconfig输出。

root@ip-10-1-136-71:~# ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:a8:de:ed:84  
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:a8ff:fede:ed84/64 Scope:Link
          UP BROADCAST MULTICAST  MTU:9001  Metric:1
          RX packets:23 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1580 (1.5 KB)  TX bytes:648 (648.0 B)
eth0      Link encap:Ethernet  HWaddr 06:c8:1f:44:eb:01  
          inet addr:10.1.136.71  Bcast:10.1.136.255  Mask:255.255.255.0
          inet6 addr: fe80::4c8:1fff:fe44:eb01/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1
          RX packets:90197 errors:0 dropped:0 overruns:0 frame:0
          TX packets:7374 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:131280146 (131.2 MB)  TX bytes:762026 (762.0 KB)
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:3 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1728 (1.7 KB)  TX bytes:1728 (1.7 KB)

因此,基础主机具有三个接口。
一如既往的eth0和lo,以及上面显示的一个名为docker0的添加接口。

docker0接口是我们安装docker时创建的桥接接口。
Docker在IP地址方面非常聪明。
它尝试使用与主机网络没有冲突的网络。
流程是这样的...当我们最初在主机上启动docker服务时,docker首先会检查我们是否提供了自定义桥选项(在启动时使用docker daemon的-b参数)。
如果我们未提供任何自定义桥接选项,则Docker将尝试创建自己的桥接器docker0(我们在上述主机的ifconfig输出中看到了该桥接器)。

如前所述,在创建网桥时,泊坞窗将首先尝试查找主机未使用的网络范围。
Docker使用ip route命令查找主机需要访问的网络。
然后找到一个不与任何冲突的范围。

这种使用ip路由查找不冲突的网络的方法并不十分完善。
因为,有时主机没有到另一个专用网络的特定路由,但是可以通过默认网关进行访问。
假设主机默认网关为10.1.136.1.
主机可以通过默认网关10.1.136.1.
到达另一个专用服务器172.17.0.2.
但是Docker对此一无所知,因为主机上不存在该特定路由。

在这种情况下,最好使用自己定义的网络方案创建自己的网桥。
这样就不会有任何冲突(我们很快就会这样做。

现在,让我们看看docker容器如何与外界通信。
退出容器,让我们看看Iptable NAT规则。

root@ip-10-1-136-71:~# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  anywhere             anywhere             ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  anywhere            !127.0.0.0/8          ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  172.17.0.0/16        anywhere            
Chain DOCKER (2 references)
target     prot opt source               destination

请参阅以上输出中的POSTROUTING链。
它有一条规则,将伪装来自172.17.0.0/16(Docker桥网络)的所有流量。
该伪装规则将使从容器到外部世界的所有传出流量看起来像是来自主机的流量。
但是,外界还不能直接与容器对话。

为了使外界直接到达Docker端口,我们需要有一个类似的Iptable DNAT规则。
假设我们希望外界与容器端口3306进行交互。
在这种情况下,我们将必须添加DNAT规则,该规则规定从任何地方向主机系统上的端口3306的请求都必须映射到容器上的3306端口。

当我们在docker run命令期间提供类似于-p 3306:3306的选项时,这正是docker所做的。
让我们看看是否发生了这种情况,只需在docker运行期间简单地传递-p 3306:3306即可。

root@ip-10-1-136-71:~# iptables -t nat -L
Chain DOCKER (2 references)
target     prot opt source               destination         
DNAT       tcp  --  anywhere             anywhere             tcp dpt:mysql to:172.17.0.2:3306

从上面的输出中可以清楚地看到docker添加了我们上面刚刚讨论的DNAT规则。
简而言之,如果外部世界想与容器中运行的MySQL服务进行通信,则可以将HOST地址与端口3306一起使用。
主机将验证IP数据包并读取源端口,目标端口和目标端口。
匹配DNAT规则后,主机会将请求发送到容器的3306端口。

上面的DNAT规则是将请求转发到172.17.0.2上的3306(这是我们使用docker run启动的容器的IP地址)。

Docker不提供任何命令行选项来公开已经运行的容器的端口。
假设我们忘记了在docker run命令期间为所需端口提供-p选项。
在这种情况下,我们始终可以将Docker容器ip与DNAT iptable命令一起使用,以显示正在运行的容器的所需端口。

假设容器ip地址是172.17.0.6.
我们想将该运行容器的端口之一暴露给外部世界(在此示例中为8080端口)。
在这种情况下,我们只需启动以下命令并公开端口即可。

iptables -t nat -A  DOCKER -p tcp --dport 8080 -j DNAT --to-destination 172.17.0.6:8080

默认情况下,驻留在同一主机中的所有容器都可以使用容器的ip地址相互通信。
这是因为在同一主机中运行的所有容器都将通过网桥接口连接,并且将成为同一docker私有网络的一部分。
iptable规则集也不会阻止这种通信的发生。

如果要自己管理iptables,并且不想让docker创建iptable规则集,则可以始终在docker启动参数中使用iptables = false。
如果我们尚未设置iptables = false选项,则docker默认情况下将创建一个FORWARD策略,并允许所有来源(下面显示的是docker创建的默认FORWARD规则集。

root@ip-10-1-136-71:~# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere

尽管docker默认情况下允许容器互通,但是出于安全原因,我们可以禁用此功能。
可以在docker启动过程中使用--icc = false选项来禁用容器之间的互通。
这可以通过在Ubuntu中修改/etc/default/docker文件和在基于RHEL的系统中修改/etc/sysconfig/docker文件来完成。
我的/etc/default/docker文件如下所示。

root@ip-10-1-136-71:~# cat /etc/default/docker
DOCKER_OPTS="-icc=false"

启用icc = false选项并重新启动docker daemon后,我们将不再能够进行容器间通信。
这是因为,docker随后将添加DROP策略以在主机上转发数据包,如下所示。

root@ip-10-1-136-71:~# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere            
DROP       all  --  anywhere             anywhere

请参阅上面的FORWARD链中的最后一个DROP规则(之前没有出现)。

出于安全原因,设置-icc = false是一个好主意。
假设一个容器被盗用,那么在这种情况下,被盗用的容器应该无法通过扫描网络在同一网络中找到其他容器。

尽管同一主机中两个容器之间的互通是开箱即用的,但是在docker中发现要访问的容器的ip地址并不容易。
即:启动容器后,我们需要找到一种确定容器IP地址的方法,以便其他容器可以连接到该IP地址。
我们将必须找到自己的方法来实现此目的,因为docker从网络范围分配了一个免费的IP地址(即:docker动态分配给容器的IP地址)。
但这使发现容器地址变得有些困难。

从安全性和便利性的角度来看,最好的解决方案是使用docker容器链接。

请记住以下事实:容器链接与docker的网络没有任何关系。

容器链接取决于容器的名称。
让我们看看前面讨论桥接网络时启动的容器的名称(#docker ps命令将向我们显示运行容器的详细信息及其各自的名称,如下所示)。

root@ip-10-1-136-71:~# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
9c7c0c41d694        ubuntu              "/bin/bash"         About an hour ago   Up 37 minutes       0.0.0.0:80->80/tcp       desperate_ptolemy
396e2a687528        ubuntu              "/bin/bash"         About an hour ago   Up 36 minutes       0.0.0.0:3306->3306/tcp   elated_lichterman

如果我们还记得的话,我们之前还没有在docker run命令中传递name选项。
这就是为什么docker为我们的容器分配了随机名称(在我们的示例容器中,名称上方是desperate_ptolemy和elated_lichterman)。
名称对于识别容器很重要。
在docker运行期间使用--name选项,我们可以为容器分配名称。
让我们使用ubuntu:latest镜像创建一个容器,并将其命名为数据库。

root@ip-10-1-136-71:~# docker run -it -d --name=database -p 3306:3306 ubuntu
a9bec6b068b88e0d2b484e3bd2a33e2c818c274d8437c40ab29ab1ee261a1c0a
root@ip-10-1-136-71:~# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
a9bec6b068b8        ubuntu              "/bin/bash"         2 seconds ago       Up 1 seconds                            database

现在让我们创建另一个名为的容器,并将其链接到我们上面刚刚创建的数据库容器。
可以如下所示进行。

root@ip-10-1-136-71:~# docker run -it -d --name=website --link database:database ubuntu
7ec96444baa61420bd505d7e734fd51f08593690657d126ab331d0412091bf6d
root@ip-10-1-136-71:~# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
7ec96444baa6        ubuntu              "/bin/bash"         2 seconds ago       Up 1 seconds                                 website
9233d556669e        ubuntu              "/bin/bash"         12 seconds ago      Up 11 seconds       0.0.0.0:3306->3306/tcp   database

我们上面传递的--link参数采用--link容器名称-to-link:alias-name的格式。
别名是可选的,我们可以简单地使用--link容器的链接名称

因此,我们使用--link选项将容器链接到数据库容器。
让我们看看我们的容器内发生了什么。

root@ip-10-1-136-71:~# docker exec -it 7ec96444baa6 /bin/bash
root@7ec96444baa6:/# env
DATABASE_PORT_3306_TCP_PROTO=tcp
HOSTNAME=7ec96444baa6
TERM=xterm
DATABASE_PORT_3306_TCP_ADDR=172.17.0.2
DATABASE_NAME=/website/database
DATABASE_PORT=tcp://172.17.0.2:3306
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
DATABASE_PORT_3306_TCP=tcp://172.17.0.2:3306
SHLVL=1
HOME=/root
DATABASE_PORT_3306_TCP_PORT=3306
LESSOPEN=| /usr/bin/lesspipe %s
LESSCLOSE=/usr/bin/lesspipe %s %s
_=/usr/bin/env

上面显示的env命令输出显示了一些与我们建立链接的数据库容器有关的环境变量。
在此链接期间发生的事情是,源容器(数据库容器)向我们的容器提供的详细信息很少。
源容器提供的详细信息在下面提到。

  • 端口暴露
  • 源容器的IP地址
  • 协议(即:其tcp还是udp等)

在此链接过程中,容器上发生的另一件事如下所示。

root@7ec96444baa6:/# cat /etc/hosts
172.17.0.3    7ec96444baa6
127.0.0.1    localhost
::1    localhost ip6-localhost ip6-loopback
fe00::0    ip6-localnet
ff00::0    ip6-mcastprefix
ff02::1    ip6-allnodes
ff02::2    ip6-allrouters
172.17.0.2    database 9233d556669e

它已在/etc/hosts文件中为datbase容器添加了一个条目及其IP地址。
因此,我们基本上可以使用容器名称本身来ping数据库容器。

root@7ec96444baa6:/# ping database
PING database (172.17.0.2) 56(84) bytes of data.
64 bytes from database (172.17.0.2): icmp_seq=1 ttl=64 time=0.074 ms
64 bytes from database (172.17.0.2): icmp_seq=2 ttl=64 time=0.053 ms

端口,IP和协议环境的数量取决于要链接到的容器公开的端口数量。
假设数据库容器公开了两个不同的端口,那么容器中的环境变量在链接到数据库容器之后,将通过数据库容器公开所有端口。

请注意以下事实:如果我们使用-icc = false,则无法对源容器执行ping操作。
但是,我们可以直接从容器连接到数据库容器端口3306.

尽管我们在一开始就讨论了docker的桥接网络。
我们尚未创建自己的桥接网络供Docker使用。
如果我们需要定义自己的网络桥接器配置,或者我们已经很少有Docker可以使用的桥接器,那么这非常方便。

要设置自定义桥,我们需要先从默认Docker安装中删除docker0桥(如果已存在)。
第一步是在系统上安装bridge-utils软件包。

root@ip-10-1-136-71:~# apt-get install bridge-utils

可以使用yum install bridge-utils将上述软件包安装在RHEL/Centos中。

现在,让我们停止docker服务,如下所示。

root@ip-10-1-136-71:~# stop docker
docker stop/waiting

上面的命令将在RHEL/Centos系统中服务docker stop。
现在,如下图所示将默认的docker0网桥关闭,然后删除docker0网桥

root@ip-10-1-136-71:~# ip link set dev docker0 down
root@ip-10-1-136-71:~# brctl delbr docker0

下一步是删除所有iptables POSTROUTING规则集(如果有的话,从较旧的Bridge Docker容器中删除)。
可以如下所示进行。

root@ip-10-1-136-71:~# iptables -t nat -F POSTROUTING

现在,让我们创建自己的自定义桥,如下所示。

root@ip-10-1-136-71:~# brctl addbr mybridge0
root@ip-10-1-136-71:~# ip addr add 192.168.0.0/16 dev mybridge0
root@ip-10-1-136-71:~# ip link set dev mybridge0 up

现在让我们使用ifconfig命令确认新创建的网桥是否启动,如下所示。

root@ip-10-1-136-71:~# ifconfig
eth0      Link encap:Ethernet  HWaddr 06:c8:1f:44:eb:01  
          inet addr:10.1.136.71  Bcast:10.1.136.255  Mask:255.255.255.0
          inet6 addr: fe80::4c8:1fff:fe44:eb01/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1
          RX packets:98973 errors:0 dropped:0 overruns:0 frame:0
          TX packets:13039 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:132955084 (132.9 MB)  TX bytes:1513378 (1.5 MB)
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:3 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1728 (1.7 KB)  TX bytes:1728 (1.7 KB)
mybridge0 Link encap:Ethernet  HWaddr c6:b9:8d:19:c8:92  
          inet addr:192.168.0.0  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::c4b9:8dff:fe19:c892/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:258 (258.0 B)

因此,我们的桥mybridge0使用定义的子网192.168.0.0/16运行。
现在,让我们使用新创建的网桥修改docker启动选项,如下所示。
这可以通过在Ubuntu系统中编辑/etc/default/docker和在基于RHEL/Centos的系统中编辑/etc/sysconfig/docker来完成。
我的/etc/default/docker文件如下所示。

root@9233d556669e:/# root@ip-10-1-136-71:~# cat /etc/default/docker
DOCKER_OPTS="--bridge=mybridge0"

因此,我们要求docker使用网桥mybridge0而不是默认的docker0网桥(我们之前已将其删除。
)。
现在,让我们开始创建的旧容器(我们的数据库和容器)。

root@ip-10-1-136-71:~# docker start 9233d556669e
9233d556669e
root@ip-10-1-136-71:~# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
9233d556669e        ubuntu              "/bin/bash"         59 minutes ago      Up 2 seconds        0.0.0.0:3306->3306/tcp   database
root@ip-10-1-136-71:~# docker exec -it 9233d556669e /bin/bash
root@9233d556669e:/# ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:c0:a8:00:02  
          inet addr:192.168.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:c0ff:fea8:2/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:648 (648.0 B)  TX bytes:648 (648.0 B)
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

看见了?
我们相同的数据库容器现在使用的IP地址是我们自定义网桥子网的一部分(192.168.0.2,它是192.168.0.0/16的一部分,这是我们在创建网桥mybridge0时提供的)。
我们还要确认docker是否正确启用了iptable规则集。

root@ip-10-1-136-71:~# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  anywhere             anywhere             ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  anywhere            !127.0.0.0/8          ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  192.168.0.0/16       anywhere            
MASQUERADE  tcp  --  192.168.0.2          192.168.0.2          tcp dpt:mysql
Chain DOCKER (2 references)
target     prot opt source               destination         
DNAT       tcp  --  anywhere             anywhere             tcp dpt:mysql to:192.168.0.2:3306

很酷,所以Docker已经修复了POSTROUTING规则集,以匹配我们新创建的网桥子网地址。
那太棒了。
因此,我们现在有了一个Docker正在使用的自定义桥。

Docker还提供了--bip = 192.168.0.0/16选项,我们可以使用该选项修改默认docker0网桥的子网。

除了到目前为止我们看到的网桥,自定义网桥和容器链接选项之外,docker还具有另一个有趣的联网功能,称为主机联网。

在docker run命令期间使用主机联网选项,容器可以直接使用主机系统的网络。
换句话说,容器不会为其自身创建单独的网络堆栈。
容器仍将使用自己的进程堆栈,但不会使用网络。
如果从容器中启动ifconfig命令,我们将知道网络接口列表只不过是主机网络接口列表。

如果使用此主机联网选项,则使用-p选项公开端口等没有任何意义。
这是因为,容器中运行的任何服务都将直接在主机网络上。
所以一切都已经暴露了。

让我们开始一个带有主机联网选项的容器,然后看看它的外观。

root@ip-10-1-136-71:~# docker run -it -d --net=host ubuntu
70072d99a18f7b096f52b713e319ca233cb7a2e09c33676417250cc539f1197e
root@ip-10-1-136-71:~# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
70072d99a18f        ubuntu              "/bin/bash"         2 seconds ago       Up 1 seconds                                 distracted_colden
9233d556669e        ubuntu              "/bin/bash"         About an hour ago   Up 31 minutes       0.0.0.0:3306->3306/tcp   database
root@ip-10-1-136-71:~# docker exec -it 70072d99a18f /bin/bash
root@ip-10-1-136-71:/# ifconfig
eth0      Link encap:Ethernet  HWaddr 06:c8:1f:44:eb:01  
          inet addr:10.1.136.71  Bcast:10.1.136.255  Mask:255.255.255.0
          inet6 addr: fe80::4c8:1fff:fe44:eb01/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1
          RX packets:100306 errors:0 dropped:0 overruns:0 frame:0
          TX packets:13841 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:133046028 (133.0 MB)  TX bytes:1627584 (1.6 MB)
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:3 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1728 (1.7 KB)  TX bytes:1728 (1.7 KB)
mybridge0 Link encap:Ethernet  HWaddr 56:c5:9d:3c:6e:8d  
          inet addr:192.168.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::c4b9:8dff:fe19:c892/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:536 (536.0 B)  TX bytes:648 (648.0 B)
vetha244cf5 Link encap:Ethernet  HWaddr 56:c5:9d:3c:6e:8d  
          inet6 addr: fe80::54c5:9dff:fe3c:6e8d/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:648 (648.0 B)  TX bytes:648 (648.0 B)

通过将--net = host选项与docker run命令配合使用来启用主机联网。
看到容器的主机名也没有改变(与主机本身相同)。
ifconfig输出显示主机网络接口,包括网桥本身。
如果我们要完全避免容器的桥接和单独的IP地址,这将很方便。
如果我们考虑每个主机仅运行一个容器,则此选项也是最合适的。