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. 容器网络访问原理
[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地址
注意:ifcfg-eth0在不同系统名字可能不一样,这个是网卡的配置文件。一般不使用这种方法,直接用端口转发即可。