docker的网络是基于Linux namespace 的虚拟化
一,网络原理
1,Veth设备(成对)
1,创建一个命名空间
[root@\ docker~]# ip netns add test01
[root@\ docker~]# ip netns add test02
[root@\ docker~]# ip netns list
test02
test01
2,创建veth设备对
#创建一个ip连接,设备名字veth 类型veth,另一半的名字veth001
[root@\ docker~]# ip link add veth type veth peer name veth001
# 查看会生成两个veth设备,互为对方的peer
[root@\ docker~]# ip a
... ...
31: veth001@veth: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether b2:d5:91:5b:79:ce brd ff:ff:ff:ff:ff:ff
32: veth@veth001: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 82:05:5c:eb:69:66 brd ff:ff:ff:ff:ff:ff
3,绑定命名空间
[root@\ docker~]# ip link set veth001 netns test01
# 这时候查看会看不到veth001
[root@\ docker~]# ip link show | grep veth
... ...
32: veth@if31: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
4,将 Veth 分配 IP
#设置ip
[root@\ docker~]# ip netns exec test01 ip addr add 172.16.0.111/20 dev veth001
#绑定
[root@\ docker~]# ip netns exec test01 ip link set dev veth001 up
#查看
[root@\ docker~]# ip netns exec test01 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
31: veth001@if32: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000
link/ether b2:d5:91:5b:79:ce brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.16.0.111/20 scope global veth001
valid_lft forever preferred_lft forever
这个时候双方都通了
5,查看对端veth设备
[root@\ docker~]# ip netns exec test01 ethtool -S veth001
NIC statistics:
peer_ifindex: 32
[root@\ docker~]# ip a | grep 32
32: veth@if31: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
6,为对端 Veth 设备设置 IP
[root@\ docker~]# ip addr add 172.16.0.112/20 dev veth
[root@\ docker~]# ip link set dev veth down
[root@\ docker~]# ip link set dev veth up
[root@\ docker~]# ping 172.16.0.111
PING 172.16.0.111 (172.16.0.111) 56(84) bytes of data.
64 bytes from 172.16.0.111: icmp_seq=1 ttl=64 time=0.187 ms
... ...
[root@\ docker~]# ping 172.16.0.112
PING 172.16.0.112 (172.16.0.112) 56(84) bytes of data.
64 bytes from 172.16.0.112: icmp_seq=1 ttl=64 time=0.185 ms
64 bytes from 172.16.0.112: icmp_seq=2 ttl=64 time=0.056 ms
2,网桥
Linux 可以支持多个不同的网络,它们之间能够相互通信,就需要一个网桥。
网桥是二层的虚拟网络设备, 它是把若干个网络接口“连接”起来,从而报文能够互相转发。网桥能够解析收发的报文,读取目标 MAC 地 址的信息,和自己记录的 MAC 表结合,来决定报文的转发目标网口。
网桥设备 brO 绑定了 eth0、 eth1
二,docker 网络
host模式
host模式:
用的宿主主机的网卡,其他是隔离的;
容器使用的端口不能和宿主机的端口冲突
[root@\ docker~]# docker run -d --network=host nginx
fe200888c3bbd072b085e970962f3f837a0ff5f3f4c7d8d3eec7f57214e7da37
[root@\ docker~]# curl 127.0.0.1:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
... ...
containe模式
containe模式:
和一个指定的容器共享 IP、端口范围等;
两个容器除了网络方面,其他还是隔离的
# 打开一个容器
[root@\ docker~]# docker run -d --name nginx1 nginx
d5cef744a57f6825177fbe55a0022a3cc631f6d6b2edcedabe514139536f073d
[root@\ docker~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d5cef744a57f nginx "/docker-entrypoint.…" 5 seconds ago Up 4 seconds 80/tcp nginx1
#可以pig通172.17.0.8:80
[root@\ docker~]# curl 172.17.0.8:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
... ...
# 使用nginx1网络打开centos容器
[root@\ docker~]# docker run -it --network="container:nginx1" centos bash
#查看ip也是172.17.0.8
[root@d5cef744a57f /]# 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
35: eth0@if36: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:08 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.8/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
none 模式
none 模式:
Docker 容器拥有自己的 Network Namespace,这个 Docker 容器没有网卡、IP、路由等信息;
需要自己为 Docker 容器添加网卡、配置 IP 等。
[root@\ docker~]# docker run -dit --name test01 --network none busybox
[root@\ docker~]# docker exec -it test01 ifconfig
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)
bridge 模式
docker默认模式
1,当 Docker 进程启动时,会在主机上创建一个名为 docker0 的虚拟网桥
[root@\ docker~]# ip a
... ...
docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:56:8b:0b:74 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:56ff:fe8b:b74/64 scope link
valid_lft forever preferred_lft forever
2,从 docker0 子网中分配一个 IP 给容器使用,并设置 docker0 的 IP 地址为容器的默认网关
[root@\ docker~]# docker run -d --name ngin11 nginx
[root@\ docker~]# docker inspect ngin11
... ...
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
网友评论