docker 网络
容器镜像层
docker 网络
docker 的四种常见网络 none/host/joined/bridge
1. none网络
docker network inspect none # 使用此网络,运行容器之后,容器内查看网卡信息(ifconfig),只有本地回环(lo);网卡,并没有接入其它网卡,是无法连通外网的;无法上网,就意味着安全,使用场景,比如:运行一个生成一个随机码的程序。
docker run -it --network none busybox
'''
[
{
"Name": "none",
"Id": "2ac35f6e9779ba6a061f8d5d8678dcfdf1275ded19ee92ffc66a9ae72664b6e1",
"Created": "2021-10-30T19:52:45.824424151+08:00",
"Scope": "local",
"Driver": "null",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": []
},
"Internal": false,
"Attachable": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
'''
2.host网络
docker network inspect host # 使用场景:如果对机器性能和容器的网络传输效率要求高,可以使用host网络;但是会失去一些灵活性,如果宿主机开了一个80端口,容器内又起了一个80端口,端口就容易冲突,这时网络隔离失效,导致端口隔离也失效了。
docker run -it --network host busybox
'''
[
{
"Name": "host",
"Id": "ecf21ef22703106ded9b56c25aa2be63ab79d78d324f497e98b985979059e930",
"Created": "2021-10-30T19:52:45.829267086+08:00",
"Scope": "local",
"Driver": "host",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": []
},
"Internal": false,
"Attachable": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
'''
docker pull httpd
docker pull busybox
docker run -itd --name web httpd sh
3.joined网络 # 如下图1
docker run -it --network container:web busybox # 使用container连接两个容器,使两个容器能够使用相同的配置
使用场景:
1)不同主机希望通过loopback接口进行高效通讯;比如:webserver和应用服务器之间通过127.0.0.1进行通讯;
2)监控其它主机的流量;比如:要监控httpd容器进程的流量,再开一个容器进行监控,比登录apache容器,安装监控软件要好,要安全
4.bridge网络 # 如下图2
'''
[
{
"Name": "bridge",
"Id": "5bae0f31ce5ee8a0109bb571f4d52b7292ec2b25b303a89b468fb10e5a9c7cbd",
"Created": "2021-11-07T14:56:02.081583375+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": { # ip address management: IP 地址管理
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Containers": {
"06802d290f2b682d0931489100ca2845f0246c8b55013c166286f5bf3de7335b": {
"Name": "web",
"EndpointID": "f2b4b0f1349dd6b1b731e53f69fd96df6e9e12a13146b5ae3b71b637a5582718",
"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": {}
}
]
'''
不同空间的网络连接(一个网卡在容器,一个在宿主机):veth pair # 如下图3
相同空间(网卡都在都在宿主机):桥接
以下图2为例:
容器web内部 172.17.0.2/16 在eth0网卡上桥接出来vethce04030卡上,通过veth pair相连,中间用@符号表现出来的;vethce04030卡桥接到docker0(172.17.0.1)上
veth pair:在虚拟网络中充当着桥梁的角色,连接多种网络设备构成复杂的网络。
veth-pair 的三个经典实验,直接相连、通过 Bridge 相连和通过 OVS 相连。
veth pair参考连接:https://www.cnblogs.com/bakari/p/10613710.html
图1:
图2:
图3:
自定义一个网络
docker network create --driver bridge my-net
docker network ls
'''
NETWORK ID NAME DRIVER SCOPE
5bae0f31ce5e bridge bridge local
ecf21ef22703 host host local
2421bd423faf my-net bridge local
2ac35f6e9779 none null local
'''
docker network inspect my-net
'''
[
{
"Name": "my-net",
"Id": "2421bd423fafd0a702552581a7dfcd54104c1efb3dd26062158a89155f37bdfd",
"Created": "2021-11-07T22:53:51.821113075+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": {}
}
]
'''
brctl show
'''
bridge name bridge id STP enabled interfaces
br-2421bd423faf 8000.02427898bbab no
'''
ifconfig br-2421bd423faf
'''
br-2421bd423faf: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.18.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
ether 02:42:78:98:bb:ab txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
'''
图1:
自定义指定网段的网络
docker network create --driver bridge --subnet 172.22.16.0/24 --gateway 172.22.16.1 my_net2
docker network ls
'''
NETWORK ID NAME DRIVER SCOPE
5bae0f31ce5e bridge bridge local
ecf21ef22703 host host local
2421bd423faf my-net bridge local
9c81acd1210d my_net2 bridge local
2ac35f6e9779 none null local
'''
docker network inspect my_net2
'''
[
{
"Name": "my_net2",
"Id": "9c81acd1210d87817a95d1aeb6b8b07565e934c2851ec1114fe2a05f3ccacff8",
"Created": "2021-11-07T23:01:27.278900208+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.22.16.0/24",
"Gateway": "172.22.16.1" # 是物理机上某块桥接卡的IP
}
]
},
"Internal": false,
"Attachable": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
'''
brctl show
'''
bridge name bridge id STP enabled interfaces
br-2421bd423faf 8000.02427898bbab no
br-9c81acd1210d 8000.0242b5f857be no
docker0 8000.0242b06a514f no
'''
ifconfig br-9c81acd1210d # br-9c81acd1210d(inet 172.22.16.1),是我们创建my_net2网络时的网关地址
'''
br-9c81acd1210d: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.22.16.1 netmask 255.255.255.0 broadcast 0.0.0.0
ether 02:42:b5:f8:57:be txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
'''
# 使用我们自定义的网络启动一个容器 # 如下图1
docker run -itd --network my_net2 --name bbox1 busybox sh
docker exec -it bbox1 sh
能不能上网呢?可以的(因为连接到我们宿主机的ens33这张网卡上)
ping baidu.com
'''
PING baidu.com (220.181.38.148): 56 data bytes
64 bytes from 220.181.38.148: seq=0 ttl=49 time=29.171 ms
64 bytes from 220.181.38.148: seq=1 ttl=49 time=29.159 ms
64 bytes from 220.181.38.148: seq=2 ttl=49 time=31.566 ms
^C
--- baidu.com ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 29.159/29.965/31.566 ms
'''
# 创建一个自定义IP的容器 如下图2
docker run -itd --name bbox2 --network my_net2 --ip 172.22.16.8 busybox sh # 不用分配网关了,因为在创建my_net2网络时,创建的网段已经分配网关了。
docker exec -it bbox2 sh
总结:在自己创建的网络中(my_net2)指定了网段和网关的情况下,才可以 --ip 分配IP地址,像docker0使用的网络类型虽然也是bridge,但是不能分配IP地址
图1:
图2:
bbox1和bbox2是如何通信的呢?
bbox1和bbox2在同一个广播域(同一个网段),通信是没问题的。 # 如上图2-1
bbox1和bbox2能和docker0网络中的容器通信吗?
docker0(172.17.0.0网段)中容器ping br-9c81acd1210d (172.22.16.0)中的容器
br-9c81acd1210d (172.22.16.0)中的容器 ping docker0(172.17.0.0网段)中容器
这是什么原因?
iptables-save # 发现被防火墙规则挡了,这是docker容器通信的设计,不让不同网络之间的容器通信,在ip_forward转发到网关的时候,被DROP了。 如下图1
图1:
那么如果真的想让docker网络的容器和 br-9c81acd1210d 网络的容器通信就真的没办法了吗?当然可以!!!
docker network connect my_net2 web # 意思是将my_net2网卡连接到web容器上,让web容器多一块网卡
可以正常访问web服务:
当然还可以通过容器的主机名通讯,这里的容器主机名做了DNS上的解析。。。。
docker容器内外网访问
对外访问:
对内访问
可以参考不错的博客关于docker网络配置