docker基础之六network-1-singlehost

问:
docker提供的几种原生网络,及如何创建自定义网络。

容器之间如何通信,及容器与外界如何交互

docker网络从覆盖范围可分为单host上的容器网络和跨多个host的网络

docker安装时会自动在host上创建三个网络:

docker -H master network ls
NETWORK ID NAME DRIVER SCOPE
ceadc77129ea bridge bridge local
48990edc38c7 host host local
50fe527f5883 none null local

  

1) none 只有lo create一个容器可以指定--network=none

2) host 在容器中能看到host的网络,并且hostname都是host的,--network=host

3) bridge --network=bridge

[root@master ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.02421dc4d59d	no		
[root@master ~]# docker -H master run -d httpd
027256d40752467ba4d35186c15302029b40ebe8598a666bab47875042d28338
[root@master ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.02421dc4d59d	no		vethd507466

  

[root@master ~]# docker -H master exec -it 027 bash
root@027256d40752:/usr/local/apache2# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
16: eth0@if17: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:2/64 scope link 
       valid_lft forever preferred_lft forever

  

[root@master ~]# docker -H master network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "ceadc77129ea6f87720e8f8722cf89f1f508b38b317837f039f342e4f11b43cd",
        "Created": "2018-07-25T13:44:05.507043765+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Containers": {
            "027256d40752467ba4d35186c15302029b40ebe8598a666bab47875042d28338": {
                "Name": "stoic_agnesi",
                "EndpointID": "305df56da0a7d0d3f4ff3e26298dd9d3210e353b1d73ec26ad109d322cb9c7ab",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

  

注意:

默认bridge分配的网络为172.17.0.0/16网段

想要修改该网段,指定bridge docker0的地址:

[root@nas4 docker]# cat /etc/docker/daemon.json
{
  "registry-mirrors": ["https://i5vp5biq.mirror.aliyuncs.com"],
  "bip": "10.5.14.1/24"
}

  

 

创建bridge的driver

1)

[root@master ~]# docker -H master network create --driver bridge my_net
763737ede0c100f89bd0bcc4082b675c15fdd996b566e85596693450c4cda753

[root@master ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
br-763737ede0c1		8000.02420a7b15f6	no		
docker0		8000.02421dc4d59d	no		vethd507466

[root@master ~]# docker -H master network inspect my_net
[
    {
        "Name": "my_net",
        "Id": "763737ede0c100f89bd0bcc4082b675c15fdd996b566e85596693450c4cda753",
        "Created": "2018-07-25T16:36:25.559888841+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

  

2)指定 --subnet和--gateway

[root@master ~]# docker -H master network create --driver bridge --subnet 172.22.16.0/24 --gateway 172.22.16.1 my_net2
fcfcdf9dfadf1578cda64066817d702d6003c39f98555519cc47c57596e231f1
[root@master ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
br-763737ede0c1		8000.02420a7b15f6	no		
br-fcfcdf9dfadf		8000.024265dfe391	no		
docker0		8000.02421dc4d59d	no		vethd507466

[root@master ~]# docker -H master network inspect my_net2
[
    {
        "Name": "my_net2",
        "Id": "fcfcdf9dfadf1578cda64066817d702d6003c39f98555519cc47c57596e231f1",
        "Created": "2018-07-25T16:40:06.272346007+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.22.16.0/24",
                    "Gateway": "172.22.16.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

  

3)启动容器指定新网络,由docker自动从subnet分配ip

[root@master ~]# docker -H master run -it --network=my_net2 busybox
/ # 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
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
20: eth0@if21: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:16:10:02 brd ff:ff:ff:ff:ff:ff
    inet 172.22.16.2/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe16:1002/64 scope link 
       valid_lft forever preferred_lft forever

  

4)启动容器指定新网络并--ip指定静态ip,条件就是创建网络时指定--subnet的网络才可以指定静态ip

[root@master ~]# docker -H master run -it --network=my_net2 --ip 172.22.16.200 busybox
/ # 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
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
22: eth0@if23: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:16:10:c8 brd ff:ff:ff:ff:ff:ff
    inet 172.22.16.200/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe16:10c8/64 scope link 
       valid_lft forever preferred_lft forever

  

[root@master ~]# docker -H master run -it --network=my_net --ip 172.18.0.200 busybox
/usr/bin/docker-current: Error response from daemon: User specified IP address is supported only when connecting to networks with user configured subnets.

  

5)容器不同网络间通讯

A、通过额外添加同网络的网卡

docker -H master network connect my_net2 027256d40752

ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
16: eth0@if17: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:2/64 scope link 
       valid_lft forever preferred_lft forever
28: eth1@if29: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:16:10:03 brd ff:ff:ff:ff:ff:ff
    inet 172.22.16.3/24 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe16:1003/64 scope link 
       valid_lft forever preferred_lft forever
# ping 172.22.16.200
PING 172.22.16.200 (172.22.16.200) 56(84) bytes of data.
64 bytes from 172.22.16.200: icmp_seq=1 ttl=64 time=0.108 ms
64 bytes from 172.22.16.200: icmp_seq=2 ttl=64 time=0.107 ms
^C
--- 172.22.16.200 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.107/0.107/0.108/0.010 ms

 

B、 joined,多个容器共享一个网络栈,即共享配置信息,127.0.0.1也可通信,因为ip与mac共用

[root@master ~]# docker run -d -it --name=web1 docker.io/httpd
fc4c370344afb10738319fd9904fe22bc06ab92948fb37135d880de7d9bf336d
[root@master ~]# docker run -it --network=container:web1 busybox
/ # 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
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:2/64 scope link 
       valid_lft forever preferred_lft forever
/ # 

[root@master ~]# docker exec -it web1 bash
root@fc4c370344af:/usr/local/apache2# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:2/64 scope link 
       valid_lft forever preferred_lft forever
root@fc4c370344af:/usr/local/apache2# 

  

 

小结:

容器间通信的三种方式:ip,docker dns server或joined容器

1.ip通信:两容器必须有属于同一个网络的网卡

如:容器创建时通过--network指定相应的网络,或者docker network connect

2.docker dns server

docker1.10版本开始,docker daemon开始内嵌dns server ,使容器直接通过“容器”名通信,只要在启动时用--name为容器命名即可

docker dns有个限制:只能在user-defined网络中使用,默认bridge网络无使用dns

3.joined容器

joined容器可以使两个容器共享一个网络栈,共享网卡和配置信息,joined容器之间可以通过127.0.0.1直接通信

先创建一个httpd容器,名字为web1

docker run -d -it --name=web1 httpd

再创建busybox容器并通过--network=container:web1指定joined容器为web1

docker run -it --network=container:web1 busybox

ip a

确认下共享了网络栈,ip与mac完全一样,

docker network inspect bridge

且busybox可以直接用127.0.0.1访问web1的http服务

joined容器非常适合的场景:

1.不同容器中程序希望通过loopback高效快速地通信

2.监控

 

 

容器与外部通信

1.容器访问外界

当前实验环境,docker host可以访问外网,容器也可以

[root@master ~]# docker run -it busybox
/ # ping -c 3 www.baidu.com
PING www.baidu.com (61.135.169.121): 56 data bytes
64 bytes from 61.135.169.121: seq=0 ttl=56 time=3.199 ms
64 bytes from 61.135.169.121: seq=1 ttl=56 time=4.292 ms
64 bytes from 61.135.169.121: seq=2 ttl=56 time=7.405 ms

--- www.baidu.com ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 3.199/4.965/7.405 ms
/ # 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
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
8: eth0@if9: <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 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:3/64 scope link 
       valid_lft forever preferred_lft forever
/ # 

  

[root@master ~]# iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N DOCKER
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -s 172.18.0.0/16 ! -o br-763737ede0c1 -j MASQUERADE
-A POSTROUTING -s 172.22.16.0/24 ! -o br-fcfcdf9dfadf -j MASQUERADE
-A DOCKER -i docker0 -j RETURN
-A DOCKER -i br-fcfcdf9dfadf -j RETURN
-A DOCKER -i br-763737ede0c1 -j RETURN

  

####nat表中规则-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE

其含义是:来自 172.17.0.0/16 网段的包,目标地址是外网(! -o docker0),就把它交给 MASQUERADE 处理。而 MASQUERADE 的处理方式是将包的源地址替换成host的地址发送出去,即做了一次网络地址转换(NAT)

[root@master ~]# ip r
default via 192.168.1.1 dev ens33 proto dhcp metric 100 
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 
172.18.0.0/16 dev br-763737ede0c1 proto kernel scope link src 172.18.0.1 
172.22.16.0/24 dev br-fcfcdf9dfadf proto kernel scope link src 172.22.16.1 
192.168.1.0/24 dev ens33 proto kernel scope link src 192.168.1.218 metric 100 
[root@master ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:3b:ca:d2 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.218/24 brd 192.168.1.255 scope global noprefixroute dynamic ens33
       valid_lft 82084sec preferred_lft 82084sec
    inet6 fe80::4fcb:8d36:f2f0:3f5f/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:0f:2b:9e:0a brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:fff:fe2b:9e0a/64 scope link 
       valid_lft forever preferred_lft forever
4: br-fcfcdf9dfadf: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:81:ae:d2:b8 brd ff:ff:ff:ff:ff:ff
    inet 172.22.16.1/24 scope global br-fcfcdf9dfadf
       valid_lft forever preferred_lft forever
5: br-763737ede0c1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:1c:48:89:68 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 scope global br-763737ede0c1
       valid_lft forever preferred_lft forever
7: vethc393948@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 02:e9:3e:7e:21:d1 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::e9:3eff:fe7e:21d1/64 scope link 
       valid_lft forever preferred_lft forever
9: veth96720b7@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether c6:72:9b:9b:1a:40 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::c472:9bff:fe9b:1a40/64 scope link 
       valid_lft forever preferred_lft forever


[root@master ~]# tcpdump -i docker0 -n icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes
10:29:43.930573 IP 172.17.0.3 > 61.135.169.121: ICMP echo request, id 4096, seq 131, length 64
10:29:43.934103 IP 61.135.169.121 > 172.17.0.3: ICMP echo reply, id 4096, seq 131, length 64

[root@master ~]# tcpdump -i ens33 -n icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
10:30:10.956862 IP 192.168.1.218 > 61.135.169.121: ICMP echo request, id 4096, seq 158, length 64
10:30:10.959752 IP 61.135.169.121 > 192.168.1.218: ICMP echo reply, id 4096, seq 158, length 64

[root@master ~]# 

  

数据处理过程:

1)busybox 发送 ping 包:172.17.0.3 > www.bing.com。
2)docker0 收到包,发现是发送到外网的,交给 NAT 处理。
3)NAT 将源地址换成 ens33 的 IP:192.168.1.218 > www.bing.com。
4)ping 包从 ens33 发送出去,到达 www.bing.com。

 

2.外界访问容器

端口映射:

docker可将容器对外提供服务的端口映射到host的某个端口,外网通过该端口访问容器

例:

docker run -d -p 80 httpd
或
docker run -d -p 8080:80 httpd

  

httpd容器的80被映射到host的随机端口或指定端口8080

查看

docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                   NAMES
59cfb2a67ffd        httpd               "httpd-foreground"   5 seconds ago       Up 3 seconds        0.0.0.0:32768->80/tcp   jovial_mccarthy
551ffae44ee3        httpd               "httpd-foreground"   13 seconds ago       Up 12 seconds       0.0.0.0:8080->80/tcp    stupefied_mestorf

docker port 59cfb2a67ffd 551ffae44ee3
80/tcp -> 0.0.0.0:32768
80/tcp -> 0.0.0.0:8080

ps -ef |grep docker-proxy
root       8181   7304  0 10:16 ?        00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 32768 -container-ip 172.17.0.2 -container-port 80
root       8370   7304  0 10:17 ?        00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8080 -container-ip 172.17.0.3 -container-port 80

  

每一个映射的端口,host都会启动一个docker-proxy进程来处理访问容器的流量

curl 10.1.1.15:32768
<html><body><h1>It works!</h1></body></html>

curl 10.1.1.15:8080
<html><body><h1>It works!</h1></body></html>

  

跨主机网络通信,待续docker基础之六network-2~...

 

posted @ 2019-09-11 15:56  larlly  阅读(525)  评论(0)    收藏  举报