<一>docker网络
[1] none:什么都没有的网络,凡是挂在这个网络下的容器除了lo,没有其他网卡。创建容器时,可以指定容器具体使用那个网卡。
[2] host:表示跟host主机共享网络,所有的网络配置都跟host一样,实质上使用的就是host主机的网络
[3] bridge:Docker安装的时,会创建一个docker0的网卡的linux bridge,所有的容器默认使用的都是该网卡.
例如:
(brctl show 命令查看当前网卡上挂载容器)
[root@#]# brctl show
bridge name bridge id STP enabled interfaces
br-158c3rd67cdd 6000.0242c68b3222 no veth1er1abc
veth35tb0c6
docker0 6000.02420136bced no veth0fh2d09
如上的veth0fb2d09的网卡接口被挂在了docker0,其就是新创建容器的虚拟网卡
进入容器可以查看下当前容器的网卡信息:
[centos:~]# docker run -it --name test_kkk busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue
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
322: eth0@if32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue
link/ether 02:42:c0:a8:0a:16 brd ff:ff:ff:ff:ff:ff
inet 192.168.14.82/24 brd 192.168.82.255 scope global eth0
valid_lft forever preferred_lft forever
/ #
发现当前容器的网卡是eth0@if32,并不是上面提到的veth0fb2d09,这种实际情况是,容器创建虚拟网路时,会创建一对veth pair,是一种特殊网络设备,其作用就像是插座一样,两端分别链接容器跟网桥docker0,效果等价于将容器链接docker0上一样.
示例:
------------------------ ----------------- ---------
| container_One eth0@if32 | ---- | veth0fb2d09 | --- { docker0 }
------------------------ ----------------- ---------
其他的网络信息,例如ip网段,网管,可以通过如下命令进行查看:
[root@#] docker network inspect bridge
"Name": "bridge",
"Id": "29996f0951fb06bca02ae9d13f74d460a2fa14ceb5b790cec7c5796335b75a3c",
"Created": "2022-06-20T10:35:19.020277217+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "192.168.33.0/24",
"Gateway": "192.168.33.1"
}
]
},
[4] 自定义网络
a.创建网络
[root@#] docker network create --driver bridge my_network
[root@#] brctl show
br-158c37d67cdd 8000.0242c68b3222 no veth1e31abc
如上br-*开头的,就是创建的虚拟网卡,查看自定义网卡详细信息
命令:docker network inspect 自定义网卡名,例如:
[root@#] # docker network inspect mv_net
[
{
"Name": "mv_net",
"Id": "b4d88f15b8a5128e322cbf08db758042920a0c6c851402519bc059c6765531f6",
"Created": "2022-09-22T14:34:56.481977922+08:00",
"Scope": "local",
"Driver": "macvlan",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.16.33.0/24",
"Gateway": "172.16.33.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
...
]
b.创建网卡,自定义网段&网管 --subnet,--gateway,
[root@#] docker network create --driver bridge self_net_one --subnet=x.x.x.0/x --gateway=x.x.x.1
例:
[root@#] docker network create --driver bridge --subnet=172.80.10.0/24 --gateway=172.80.10.1 self_net
查看网卡信息:
[root@#] docker inspect self_net
[
{
"Name": "self_net",
"Id": "20100a77a75da41a446d1383dd99cc30889369fbe8a56c1f8671ef53496e2277",
"Created": "2022-09-22T21:22:01.799644071+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.80.10.0/24",
"Gateway": "172.80.10.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
注:另外也可以指定静态ip(但是只有使用--subnet的网卡才能指定静态ip)
<二>容器网络连通
a.同一个桥接网卡下,都是可以正常通信的。例如都挂在docker0下,都可以直接通信.
默认都是用docker0,都处于同一个网段,同一网卡,可直接通信
b.不同的网卡的容器,直接通信是不通的,可以采取,将某个网卡让另一个容器也挂接上.
如上两个容器分别挂在不通的网卡上并且非同一网段,是无法通信的.为了让其能通信呢,可以将其中一个容器链接到另一个容器所挂的网卡上,就能通信.
命令: docker network connect 网卡明 要链接容器短ID
docker network connect my_net ba58ee4fbre
上图中发现,容器ffff,链接到了my_net网卡上,另外分配一个跟vvvv容器同一网段的IP地址红框中,此刻两个容器就可以进行通信了.
c.其他容器,都join到一个共同的容器上,也可以通信(实质上三个容器共享同一块网卡)。
join容器方式通信:
创建一个tmp容器
容器nnn_1:
容器nnn_2:
如上图,容器tmp,nnnn_1/2 三者共享网卡信息,nnnn_*,都加入到tmp的容器的网卡,从而实现通信.
<三>容器跟外界的通信
a.容器默认是可以直接访问外部,原理如下:
----------- --------- ------------ ------- ---------
| container | --> | docker0 | ---> | NAT地址转换 | -> | ens33 | -> | NetWork |
----------- --------- ------------ ------- ---------
如上流程,可通过实验y验证:
容器网卡信息:
窗口1:tcpdump -i docker0 -n icmp
窗口2:tcpdump - i eth1 -n icmp
如上发现, 容器发送icmp包,经多docker0,再见过NAT转地址,最后再经过eth1网卡将数据发送出去,同样回包反过来数据流包.
注:如上通过ping www.baidu.com,通过以上抓包分析得到如上流程图的验证.
b.外部如何访问容器
通过端口映射。
通常在启动一个容器时,通过-p参数,将当前容器的端口开放出来,外部就可以通过该端口访问容器内部.(每一个端口映射,host都会启动一个docker_proxy进程来处理访问容器的流量数据)
[root@#]ps -a|grep docker-proxy
如上命令会列举出,容器的端口,以及映射的端口,协议类型,ip等相关信息
原理流程:
----------- ------- ------------- --------- ----------
| Internet | --> | ens33 | --> | docker_proxy| -> | docker0 | --> | container|
----------- ------- ------------- --------- ----------