2020-03-25 Docker容器网络

1. 网络模式

  • bridge
    -net=bridge
    默认网络,Docker启动后创建一个docker0网桥,默认创建的容器也是添加到这个网桥中。
[root@localhost ~]# docker pull busybox    ---下载测试镜像
[root@localhost ~]# docker run -it busybox    ---进入默认容器
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:05  
          inet addr:172.17.0.5  Bcast:172.17.255.255  Mask:255.255.0.0    ---172.17.0.5为bridge默认分配的一个随机IP
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 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:656 (656.0 B)  TX bytes:0 (0.0 B)
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          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:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
/ # exit
  • host
    -net=host
    容器不会获得一个独立的network namespace,而是与宿主机共用一个。这就意味着容器不会有自己的网卡信息,而是使用宿主机的。容器除了网络,其他都是隔离的。
[root@localhost ~]# docker run -it --net=host busybox    ---用host模式进入默认容器
/ # ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:98:A9:47:10  
          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
          inet6 addr: fe80::42:98ff:fea9:4710/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3138 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3409 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:140155 (136.8 KiB)  TX bytes:9227369 (8.7 MiB)
ens33     Link encap:Ethernet  HWaddr 00:0C:29:38:82:28  
          inet addr:192.168.150.139  Bcast:192.168.150.255  Mask:255.255.255.0
          inet6 addr: fe80::321:40c5:e348:a3b1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:166775 errors:0 dropped:0 overruns:0 frame:0
          TX packets:36910 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:191153038 (182.2 MiB)  TX bytes:2895730 (2.7 MiB)
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:20 errors:0 dropped:0 overruns:0 frame:0
          TX packets:20 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1760 (1.7 KiB)  TX bytes:1760 (1.7 KiB)
vethaa027e1 Link encap:Ethernet  HWaddr 92:8E:E5:A4:50:28  
          inet6 addr: fe80::908e:e5ff:fea4:5028/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 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:0 (0.0 B)  TX bytes:656 (656.0 B)
vethb08a147 Link encap:Ethernet  HWaddr 76:E8:8E:A6:C0:20  
          inet6 addr: fe80::74e8:8eff:fea6:c020/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:15 errors:0 dropped:0 overruns:0 frame:0
          TX packets:26 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1744 (1.7 KiB)  TX bytes:2419 (2.3 KiB)
vethbc2b0f6 Link encap:Ethernet  HWaddr 0E:E1:E8:F7:EF:38  
          inet6 addr: fe80::ce1:e8ff:fef7:ef38/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:764 (764.0 B)
/ # exit
[root@localhost ~]# ip a
1: lo:  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:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:38:82:28 brd ff:ff:ff:ff:ff:ff
    inet 192.168.150.139/24 brd 192.168.150.255 scope global noprefixroute dynamic ens33
       valid_lft 1543sec preferred_lft 1543sec
    inet6 fe80::321:40c5:e348:a3b1/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: docker0:  mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:98:a9:47:10 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:98ff:fea9:4710/64 scope link 
       valid_lft forever preferred_lft forever
39: vethb08a147@if38:  mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 76:e8:8e:a6:c0:20 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::74e8:8eff:fea6:c020/64 scope link 
       valid_lft forever preferred_lft forever
41: vethbc2b0f6@if40:  mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 0e:e1:e8:f7:ef:38 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::ce1:e8ff:fef7:ef38/64 scope link 
       valid_lft forever preferred_lft forever
43: vethaa027e1@if42:  mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 92:8e:e5:a4:50:28 brd ff:ff:ff:ff:ff:ff link-netnsid 2
    inet6 fe80::908e:e5ff:fea4:5028/64 scope link 
       valid_lft forever preferred_lft forever
---可以看到,host模式容器的IP是跟宿主机的IP显示一致的
  • none
    -net=none
    获取独立的network namespace,但不为容器进行任何网络配置,需要我们手动配置。
[root@localhost ~]# docker run -it --net=none busybox    ---用none模式进入容器
/ # ifconfig    ---可以看到默认没有配置IP
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          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:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
/ # exit
  • container
    -net=container:Name/ID
    与指定的容器使用同一个network namespace,具有同样的网络配置信息,两个容器除了网络,其他都还是隔离的。
[root@localhost ~]# docker run -itd --name bs -p 99:80 busybox    ---创建bs容器,指定宿主机的99端口映射到80端口
32b5c9b463be097f05294bf4dcc6c3cc9a22929fc6a61dd9b9cb4c4ec067253d
[root@localhost ~]# docker exec -it bs sh
/ # netstat -antp    ---发现并没有监听到端口
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
/ # exit
[root@localhost ~]# docker run -d --name nginx05 --net container:bs nginx    ---创建nginx05容器,使用与bs同一个网络
327773453ab2f6488c2874463838701723f8f1605e5a5f895508c739364eba36
[root@localhost ~]# docker ps -l
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
327773453ab2        nginx               "nginx -g 'daemon of…"   7 seconds ago       Up 6 seconds                            nginx05
[root@localhost ~]# docker exec -it bs sh    ---进入bs容器
/ # netstat -antp    ---监听到80端口,这里监听到的其实是nginx05的端口
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -
  • 自定义网络
    与默认的bridge原理一样,但自定义网络具备内部DNS发现,可以通过容器名或者主机名容器之间网络通信。
[root@localhost ~]# docker network create bs-test    ---创建一个网络bs-test
[root@localhost ~]# docker run -itd --name bs3 --net test-bs busybox    ---创建bs3容器连接到自定义网络bs-test
2579a39bc41c30fed1f430fbe5a7e052d55d4a85dcc4d2078aef8900863b8473
[root@localhost ~]# docker run -itd --name bs4 --net test-bs busybox    ---创建bs4容器连接到自定义网络bs-test
c1f6ad14d7330ddb1e14a98b8a63ef0bfabbac8d5cf649593647c2808f966aaf
[root@localhost ~]# docker network inspect bs-test    ---查看自定义网络bs-test的信息,可以看到两个容器都加入到网络中
[
    {
        "Name": "bs-test",
        "Id": "01058118fbb9004f63f81785792fd89f2e8ecdcc4c0a52ebcaab4da6d79ba7d4",
        "Created": "2019-08-25T01:42:35.346448193+08:00",
        "Scope": "local",
        "Driver": "bridge",
---省略若干---
        "ConfigOnly": false,
        "Containers": {
            "2579a39bc41c30fed1f430fbe5a7e052d55d4a85dcc4d2078aef8900863b8473": {
                "Name": "bs3", 
                "EndpointID": "54c8c69c4e5d2c4d6d42583b08fae2a7cd0470f5c1e3f6b6dbc29c91c088f91b",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            },
            "c1f6ad14d7330ddb1e14a98b8a63ef0bfabbac8d5cf649593647c2808f966aaf": {
                "Name": "bs4",
                "EndpointID": "ab0226fe0e5bb9c50412daa55725cd514bdeb557da4085134058049363980a97",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

小结:最佳方式是使用自定义网络,保证与这一套服务通信。

2. 容器网络访问原理

image.png
[root@localhost ~]# ip a    ---创建容器后,宿主机会创建veth开头的虚拟设备,使得容器与宿主机之间可以相互通信
1: lo:  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:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:38:82:28 brd ff:ff:ff:ff:ff:ff
    inet 192.168.150.139/24 brd 192.168.150.255 scope global noprefixroute dynamic ens33
       valid_lft 1787sec preferred_lft 1787sec
    inet6 fe80::321:40c5:e348:a3b1/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: docker0:  mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:98:a9:47:10 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:98ff:fea9:4710/64 scope link 
       valid_lft forever preferred_lft forever
52: br-01058118fbb9:  mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:fc:01:4c:84 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 brd 172.18.255.255 scope global br-01058118fbb9
       valid_lft forever preferred_lft forever
    inet6 fe80::42:fcff:fe01:4c84/64 scope link 
       valid_lft forever preferred_lft forever
94: vetha423fe9@if93:  mtu 1500 qdisc noqueue master br-01058118fbb9 state UP group default 
    link/ether da:5a:9c:de:d8:7b brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::d85a:9cff:fede:d87b/64 scope link 
       valid_lft forever preferred_lft forever
96: veth4803666@if95:  mtu 1500 qdisc noqueue master br-01058118fbb9 state UP group default 
    link/ether 2e:db:a4:0a:d4:60 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::2cdb:a4ff:fe0a:d460/64 scope link 
       valid_lft forever preferred_lft forever
容器访问外界网络原理
外界网络访问容器原理
[root@localhost ~]# docker container run -itd -e test=123456 -p 88:80 --name web -h web nginx    ---指定88端口创建容器
bb44698fb507e095984f7d7e92587442cfb8d8e49464b467c345440fed4a634c
[root@localhost ~]# docker run -d --name nginx02 -p 89:80 --mount type=bind,src=/etc,dst=/opt nginx
2a3df4028fd9b38ac64fa64f04b4734fa398bb5cb779b9233d81d1c4627eb044

[root@localhost ~]# iptables-save    ---使用iptables查看对应规则
# Generated by iptables-save v1.4.21 on Thu Aug 29 22:53:05 2019
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:DOCKER - [0:0]
-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.18.0.0/16 ! -o br-01058118fbb9 -j MASQUERADE
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 80 -j MASQUERADE
-A POSTROUTING -s 172.17.0.3/32 -d 172.17.0.3/32 -p tcp -m tcp --dport 80 -j MASQUERADE
-A DOCKER -i br-01058118fbb9 -j RETURN
-A DOCKER -i docker0 -j RETURN
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 88 -j DNAT --to-destination 172.17.0.2:80    ---88对应的iptables规则
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 89 -j DNAT --to-destination 172.17.0.3:80    ---89对应的iptables规则
COMMIT
---省略若干---

小结:可以看出,容器的网络访问规则是由iptables指定的,创建容器后由iptables自动生成。

3. 桥接宿主机网络与配置固定IP地址

桥接宿主机网络与配置固定IP地址
使用pipework工具临时配置容器固定IP

注意:ifcfg-eth0在不同系统名字可能不一样,这个是网卡的配置文件。一般不使用这种方法,直接用端口转发即可。

你可能感兴趣的:(2020-03-25 Docker容器网络)