Docker 网络
Posted wshenjin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Docker 网络相关的知识,希望对你有一定的参考价值。
docker的几种原生网络模式
- host:该模式下,容器将不会虚拟出自己的网卡,配置自己的IP等,而是共享 Docker host 的网络栈,容器的网络配置与 Docker host 完全一样
- None:该模式关闭了容器的网络功能,除了 lo,没有其他任何网卡。
- Bridge:该模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及Iptables nat表配置与宿主机通信。
以上三种网络模式,在docker服启动时就有无需手动创建
[[email protected]_Machine_192.168.31.130 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
82c93f2e5beb bridge bridge local
4af713fd5747 host host local
826a79dc0dc7 none null local
Bridge模式
bridge模式是docker服务自带的,该模式下,连在同一网桥上的容器可以相互通信,这里讲讲与外部的通信
与外部的通信,其实是借助宿主机的转发实现的:
宿主机的Iptable规则有这么几条规则:
*nat
-A POSTROUTING -s 172.18.0.0/16 ! -o docker0 -j MASQUERADE
这条规则会将源地址为172.17.0.0/16的包(也就是从Docker容器产生的包),并且不是从docker0网卡发出的,进行源地址转换,转换成主机网卡的地址。
自定义网络
除了 Host、None、Bridge 这三个自动创建的网络,也可以根据业务需要创建 user-defined 网络。
Docker 提供三种 user-defined 网络驱动:bridge, overlay 和 macvlan。overlay 和 macvlan 用于创建跨主机的网络。
创建bridge
[[email protected]_Machine_192.168.31.130 ~]# docker network create --driver bridge --gateway 192.168.1.1 --subnet 192.168.1.0/24 net_bridge_192.168.1.0/24
4e16d60bb7c39e245268b56b3f54968e37f6f75dea0c94227eb363d772425ace
--driver bridge:创建bridge类型的网络,默认
--gateway 192.168.1.1:网关IP
--subnet 192.168.1.0/24:指定网段
[[email protected]_Machine_192.168.31.130 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
5def56a9fbe1 bridge bridge local
4af713fd5747 host host local
4e16d60bb7c3 net_bridge_192.168.1.0/24 bridge local
826a79dc0dc7 none null local
[[email protected]_Machine_192.168.31.130 ~]# docker network inspect net_bridge_192.168.1.0/24
[{
"Name": "net_bridge_192.168.1.0/24",
"Id": "4e16d60bb7c39e245268b56b3f54968e37f6f75dea0c94227eb363d772425ace",
"Created": "2018-09-28T14:25:32.567131021+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.1.0/24",
"Gateway": "192.168.1.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}]
用brctl show看一下:
[[email protected]_Machine_192.168.31.130 ~]# brctl show
bridge name bridge id STP enabled interfaces
br-4e16d60bb7c3 8000.0242b3c8e7e3 no
docker0 8000.02429152de4e no
从brctl show的结果来看,新建的bridge name就是br-[bridge id]:br-4e16d60bb7c3
用创建好的bridge启一个容器
[[email protected]_Machine_192.168.31.130 ~]# docker run -tid --network=net_bridge_192.168.1.0/24 --ip 192.168.1.2 --name=busybox_192.168.1.20 busybox
983b254119c1d4789cf270843264b864cdb6de4e4f2ca226fb4e7c0efb7f9dfa
--network=net_bridge_192.168.1.0/24 :指定使用的网络
--ip 192.168.1.2 :指定IP地址
只有使用 --subnet 创建的网络才能指定静态 IP,否则容器实例在重启之后,IP地址会改变
这时候,查看一下新建的bridge的信息:
[[email protected]_Machine_192.168.31.130 ~]# docker network inspect net_bridge_192.168.1.0/24
[{
"Name": "net_bridge_192.168.1.0/24",
"Id": "4e16d60bb7c39e245268b56b3f54968e37f6f75dea0c94227eb363d772425ace",
"Created": "2018-09-28T14:25:32.567131021+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.1.0/24",
"Gateway": "192.168.1.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"983b254119c1d4789cf270843264b864cdb6de4e4f2ca226fb4e7c0efb7f9dfa": {
"Name": "busybox_192.168.1.20",
"EndpointID": "82911a84c7e2a60fcac7d7a0a9bf7f9d0e27f9cc84a6aa19eb94470908109e1d",
"MacAddress": "02:42:c0:a8:01:02",
"IPv4Address": "192.168.1.2/24",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}]
Containers 这段已经表明了,容器busybox_192.168.1.20使用了IP192.168.1.2/24
容器之间的网络互通
目前,机器上有两个bridge:
docker默认的bridge(172.17.0.0/16)
新建的net_bridge_192.168.1.0/24(192.168.1.0/24)
由于docker在设计上是隔离了不同的网络,因此两个网络下的容器实例是无法互通的
那如何让两个不同网络下的容器实例相互通信呢?可以让容器实例绑定一个另一个网络的网卡:
#事先创建一个192.168.2.0/24段的网络net_bridge_192.168.2.0/24
[[email protected]_Machine_192.168.31.130 ~]# docker network connect net_bridge_192.168.2.0/24 --ip 192.168.2.10 busybox_192.168.1.100
这样,busybox_192.168.1.100 这个实例就有了一个192.168.2.0/24段的IP地址192.168.2.10,也可以直接访问192.168.2.0/24这个段了:
[[email protected]_Machine_192.168.31.130 ~]# docker exec -ti busybox_192.168.1.100 sh
/ # ip ad
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
32: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:c0:a8:01:64 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.100/24 brd 192.168.1.255 scope global eth0
valid_lft forever preferred_lft forever
38: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:c0:a8:02:0a brd ff:ff:ff:ff:ff:ff
inet 192.168.2.10/24 brd 192.168.2.255 scope global eth1
valid_lft forever preferred_lft forever
/ # ping -c3 192.168.2.100
PING 192.168.2.100 (192.168.2.100): 56 data bytes
64 bytes from 192.168.2.100: seq=0 ttl=64 time=0.308 ms
64 bytes from 192.168.2.100: seq=1 ttl=64 time=0.131 ms
64 bytes from 192.168.2.100: seq=2 ttl=64 time=0.151 ms
joined 容器
joined 容器是另一种实现容器间通信的方式。
joined 容器非常特别,它可以使两个或多个容器共享一个网络栈,共享网卡和配置信息,joined 容器之间可以通过 127.0.0.1 直接通信。
这里起一个192.168.1.0/24段的ngx容器:
[[email protected]_Machine_192.168.31.130 ~]# docker run -tid --network=net_bridge_192.168.1.0/24 --ip=192.168.1.80 --name=nginx_test1_192.168.1.80 -v /data/dokcer/docker_local_volume/nginx_test1_80/conf/:/data/conf/nginx/:ro -v /data/dokcer/docker_local_volume/nginx_test1_80/web/:/data/web/ -v /data/dokcer/docker_local_volume/nginx_test1_80/logs/:/data/logs/ volumes/my_nginx_server:v1.14.0
104b9e850a1104b245b837f3d2f2a39f0d0b9afc752dd84ca1e44031f66ecae8
然后创建一个busybox容器,让它join到nginx_test1_192.168.1.80:
[[email protected]_Machine_192.168.31.130 ~]# docker run -itd --name=ngx_cli --network=container:nginx_test1_192.168.1.80 busybox
bc510baba23b1fc314c394da344b96241effb617b45c330c920cf41e6c6145da
--network=container:nginx_test1_192.168.1.80:共享nginx_test1_192.168.1.80容器实例的网络
[[email protected]_Machine_192.168.31.130 ~]# docker exec -it ngx_cli sh
/ # ip ad
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
46: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:c0:a8:01:50 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.80/24 brd 192.168.1.255 scope global eth0
valid_lft forever preferred_lft forever
他俩共享了同一个网络栈,确实完全独立的容器,可以分别进入容器查看里面的进程
容器与外部通信
未完待续...
以上是关于Docker 网络的主要内容,如果未能解决你的问题,请参考以下文章
VSCode自定义代码片段14——Vue的axios网络请求封装
VSCode自定义代码片段14——Vue的axios网络请求封装