linuxea:白话容器之docker网络(9)


I. docker网络

docker安装完成后自动提供了三种网络

[root@linuxea.com142 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
c46b68610246        bridge              bridge              local
ffc5941362d9        host                host                local
1f143e6b01ea        none                null                local
  • bridge

bridge是net桥接网络,本机之上创建docker0交换机和网卡使用

3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN 
    link/ether 02:42:d0:06:23:b8 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 scope global docker0
       valid_lft forever preferred_lft forever

而后启动的容器,就会自动给分配一对虚拟网卡。一半在容器,一半在网桥。

本机网桥

72: veth350c423@if71: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether be:99:b4:ad:8b:b0 brd ff:ff:ff:ff:ff:ff link-netnsid 1

并且还会被关联到docker0上。使用brctl show查看

brctl 安装:yum install bridge-utils -y

[root@linuxea.com_Node ~]$ brctl show
bridge name bridge id       STP enabled interfaces
docker0     8000.0242671ebf16   no      veth350c423
                                        veth869790e

ip link show查看对应的接口

[root@linuxea.com_Node ~]$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether 88:88:2f:d9:89:67 brd ff:ff:ff:ff:ff:ff
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default 
    link/ether 02:42:67:1e:bf:16 brd ff:ff:ff:ff:ff:ff
4: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether fa:d9:57:90:8c:c8 brd ff:ff:ff:ff:ff:ff
62: veth869790e@if61: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default 
    link/ether 96:7d:73:13:1e:41 brd ff:ff:ff:ff:ff:ff link-netnsid 0
72: veth350c423@if71: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default 
    link/ether be:99:b4:ad:8b:b0 brd ff:ff:ff:ff:ff:ff link-netnsid 1

而容器内网卡也就是虚拟另一半

[root@linuxea.com_Node ~]$ docker exec -it 5idocker sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
71: eth0@if72: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # ping 172.17.0.1
PING 172.17.0.1 (172.17.0.1): 56 data bytes
64 bytes from 172.17.0.1: seq=0 ttl=64 time=0.092 ms
64 bytes from 172.17.0.1: seq=1 ttl=64 time=0.061 ms
64 bytes from 172.17.0.1: seq=2 ttl=64 time=0.097 ms
64 bytes from 172.17.0.1: seq=3 ttl=64 time=0.093 ms
64 bytes from 172.17.0.1: seq=4 ttl=64 time=0.086 ms
64 bytes from 172.17.0.1: seq=5 ttl=64 time=0.108 ms
64 bytes from 172.17.0.1: seq=6 ttl=64 time=0.082 ms

docker0桥默认是一个nat桥,每创建一个容器并启动并分配地址后,就会生成一个iptables规则

[root@linuxea.com_Node ~]$ iptables -t nat -vnL
...省略...
Chain POSTROUTING (policy ACCEPT 3317K packets, 231M bytes)
 pkts bytes target     prot opt in     out     source               destination         
   10   660 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0    
...省略...   

只要不是从docker0桥出去的,源地址来自172.17.0.0/16 ,无论到达哪里,都要做地址伪装,也就是SNAT(MASQUERADE),并且自动SNAT(自动选择).

II. 容器网络访问

这个此前创建的容器,并没有选择网络,默认是bridge网络,docker0桥在物理机上,而后创建的5idocker容器,容器内有eth0,另外一侧在物理机的docker0交换机。

如果在同一个物理机内的同一个docker0交换机内这个5idocker容器是可以被访问到的。如上图所示:

现在run一个busybox,ip是172.17.0.4,访问到此前的httpd是没有任何问题的,如下

[root@linuxea.com_Node ~]$ docker run --name client -it busybox:latest sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
73: eth0@if74: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # wget -O - -q http://172.17.0.3
helo www.linuxea.com

当然,本地物理机访问也是没有问题的。如果没有SNAT,就只是一个内部的主机桥。

[root@linuxea.com_Node ~]$ curl 172.17.0.3
helo www.linuxea.com

III. 跨主机容器访问

那么现在,如果其他的host主机默认访问这个5idocekr是无法访问的,默认的桥下的容器想要在此桥下被访问只能是DNAT,而DNAT是看不到后端的5idocker的。此刻要想被外部客户端访问就需要DNAT,客户端在访问网卡80端口时候,转发至docker0交换机上,而后到5idocker。如下图

当使用这种默认的桥接,只能在添加DNAT规则便于可以被外部客户端访问。如果此时启动多个web容器,正常亲下对外通讯的物理机器只有一个ip地址,也只有一个网卡,在做DNAT那就不能使用同一个端口。但是,如果不是同一个端口,那只能使用端口映射的方式对外提供业务。

如果是叠加的方式就不需要在物理机做端口映射,直接通过隧道访问对端ip和端口

IV. Host

此前,我们知道。每一个容器都有独立隔离的6个名称空间,user,mount,pid,UTS,ipc,net。

而每个容器都有user,mount,pid,而UTS,ipc,net是容器间共享的。这样一来,除了user,mount,pid这些是互不干扰的,其他是拥有同一组网卡,同一组协议栈,同一个主机名和域名,同一个ip地址。如果此时两个容器通讯,使用同一个lo接口通讯,就可以使用127.0.0.1访问。这样就有一部分隔离的名称空间,一部分是共享的名称空间。

而这种Host的方式是直接共享物理机器的网络。如果创建容器的时候,默认都是桥接网络,nat网络模式。

这些信息可以通过docker network inspect [bridge|host]查看

V. None

none意味着没有网络。不设置网络,只有lo接口。一般运行一些不需要网络的程序,充当临时使用或者客户端等。

0 分享

您可以选择一种方式赞助本站

支付宝扫码赞助

支付宝扫码赞助

日期: 2018-12-29分类: Docker

标签: 白话容器

发表评论