八、网络管理

于2021年10月6日重新编辑

一、容器网络介绍

容器网络分为以下五种网络类型

  • None
  • host
  • bridge
  • user-defined
  • container

dokcer在安装时就会自动创建三个网络,使用如下命令查看

dokcer network ls

image-20211006152449359

下面分别介绍这五种网络类型,我的宿主机IP为10.154.0.110

二、五种网络类型

2.1 None

1)简介

什么都没有的网络,该网络的容器下只有lo网卡,即本机127.0.0.1,是一个与世隔绝的单机环境。

可使用参数--net=none指定使用none网络

通常用于对安全要求高且不需要联网的容器使用,如生成随机密码的容器。

2)配置none网络

docker run -it --network=none busybox

可以看到处于none网络环境的容器只有lo网卡,无法与外部通信,也无法与其他容器通信。

2.2 host

1)简介

直接使用宿主机的IP地址。

可使用参数--net=host指定使用host网络

通常用于对网络传输要求较高的网络环境,这样可以让容器直接访问网络,而不是通过宿主机转发。

2)配置host网络

docker run -it --network=host busybox
#查看刚创建的busybox的IP地址
docker exec a7 ifconfig

查看处于host网络的容器,会发现它使用了宿主机的网络环境,即ens33网卡

image-20211006154311972

我们再创建一个nginx容器,访问宿主机IP地址

docker run -itd --network=host nginx
curl http://10.154.0.110

可以发现host网络的容器确实使用的是宿主机的IP,占用的是宿主机的端口。

image-20211006154652107

注意:使用host网络最好使用-p指定映射端口,如果不指定则需要检查宿主机的端口跟容器的端口是否冲突,冲突会造成容器服务无法访问。

可参考:host网络介绍

2.3 bridge

1)简介

默认网络模式,容器的桥接模式,会创建一个名为docker0的虚拟网卡,所有处于该网络的容器都挂到docker0上,通过docker0代为转发。相当于VM的NAT模式,IP地址段默认为172.17.0.0/16,可供使用2^16-2个IP地址。

可使用参数--net=bridge指定

最常用的网络模式,该网络模式下,需要将容器服务端口映射到宿主机才能进行访问,安全性较高。

bridge网络如下图所示

2)配置bridge网络

#安装brctl工具,方便查看网络环境
yum install bridge-utils -y
brctl show

此时还没有创建任何bridge网络的容器,所以interfaces是空的

image-20211006170320179

#创建一个busybox容器,不写网络默认为bridge
docker run -it busybox

进入容器查看网络环境如下

image-20211006170936876

可以看到分配的IP地址为172.17.0.2,接口为veth9e4f6el,此接口挂在docker0虚拟网卡上。

image-20211006171036176

查看宿主机网络环境,会发现多出一张虚拟网卡,此为容器的网卡

image-20211006171413678

2.4 user-defined

1)简介

用户自定义网络,docker提供三种自定义网络驱动,分别为bridge、overlay和macvlan。

其中overlay和macvlan用于创建跨主机网络,这个以后介绍。

用户自定义网络创建的bridge与普通bridge网络不同的是,自定义网络中创建的容器可以通过容器名或者主机名互通,这是因为自定义网络中的容器内部的hosts文件做了ip与主机名解析。

可通过docker network create 创建自定义网络

2)配置user-defined网络

docker network create --driver bridge my_net
brctl show

查看my_net配置信息可以多了一张br-d035b8dfefa4网卡,该网卡的地址段为172.18.0.0/16

image-20211006172338817

查看my_net网络配置信息

docker network inspect my_net

image-20211006172408244

创建指定IP网段

docker network create \
--driver bridge \
--subnet 172.22.16.0/24 \
--gateway 172.22.16.1 my_net2

运行容器使用指定的网络

docker run -itd --network=my_net2 busybox

运行容器使用指定的IP

docker run -itd --network=my_net2 --ip 172.22.16.8 busybox

只有使用--subnet创建的网络才能指定静态IP地址,否则会报错

此时网络拓扑结构如下

容器 IP 网络
busybox1 172.16.0.2 默认
busybox2 172.22.16.2 my_net2
busybox3 172.22.16.8 my_net2

此时172.22.16.0网段能互相ping通,处于172.17.0.1的容器无法ping通,查看ip router,跟iptables-save,发现是因为iptables丢弃了docker0跟br-xxxxx之间的流量。

image-20211006174040300

如果要让他们互相通信则可以使用connect实现,命令如下

docker network connect my_net2 2eadced8f4ac

会发现busybox1容器多出一张网卡,IP为172.22.16.3,此时的busybox1相当于双网卡,也就能跟busybox2和busybox3通信了

image-20211006174738800

此时的网络环境如下所示

容器 IP 网络
busybox1 172.16.0.2/172.22.16.3 默认/my_net2
busybox2 172.22.16.2 my_net2
busybox3 172.22.16.8 my_net2

2.5 container

1)简介

新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。

这种模式可以节约一定的网络资源,也就是IP地址。

可使用参数--net=container指定

2)配置container网络

docker run -d -it --name=web1 httpd
docker run -it --network=container:web1 busybox

这样busybox容器就是使用的httpd网络命名空间,bosybox可以访问127.0.0.1访问到web1的http服务。

可参考:container网络模式

三、容器网络原理

3.1 容器访问外部网络原理

我们创建一个容器busybox,会发现它默认就能访问外网

docker run -it busybox
ping www.baidu.com

使用iptables查看,会发现网桥docker0收到来自172.17.0.0/16网段的包会交给MASQUERADE处理,MASQUERADE会将包的源地址替换为宿主机的地址发送出去,做一次网络地址转换。

iptables -t nat -S | grep docker0

image-20211007152927175

查看路由,默认路由是从ens33接口出去的

ip router

image-20211007153107585

我们开三个会话窗口,监控icmp流量包

#窗口一
tcpdump -i docker0 -n icmp

#窗口二
tcpdump -i ens33 -n icmp

#窗口三
docker run -it busybox
ping www.baidu.com

可以发现docker0收到busybox的ping包,源地址为容器IP172.17.0.2,交给MASQUERADE处理,在ens33接口上,我们看到ping包源地址变为了10.154.0.110,宿主机的IP地址。

image-20211007153544017

image-20211007153528797

结果如下

image-20211007153810620

  1. busybox发送Ping包:172.17.0.2-->www.baidu.com
  2. docker0收到包,发现是访问外网的,交给NAT处理
  3. NAT将源地址转换为ens33接口的IP,即宿主机IP:10.154.0.110-->www.baidu.com
  4. ping包从ens33接口出去,到达www.baidu.com

3.2 外部网络访问容器原理

使用的端口映射,具体看这篇

下图环境为,宿主机IP:10.0.2.15,容器IP:172.17.0.3,端口映射为容器80映射到宿主机32773

image-20211007154153593

总结

  1. docker-proxy监听宿主机32773端口
  2. 当有访问10.0.2.15:32773端口时,docker-proxy转发给容器172.17.0.3:80
  3. 容器172.17.0.3相应请求并返回处理结果

四、命令总结

4.1 创建None网络

docker run -it --network=none busybox

4.2 创建host网络

docker run -it --network=host busybox

4.3 创建bridge网络

#默认就是bridge
docker run -it busybox
docker run -it --network=bridge busybox

4.4 创建user-defined网络

#创建自定义bridge网络,名为my_net
docker network create --driver bridge my_net

#创建指定IP网段的自定义bridge网络
docker network create \
--driver bridge \
--subnet 172.22.16.0/24 \
--gateway 172.22.16.1 my_net2

#创建使用my_net网络的容器
docker run -itd --network=my_net busybox

#创建使用指定IP地址的容器
docker run -itd --network=my_net --ip 172.22.16.8 busybox

使用自定义创建的bridge网络,自动会在/etc/hosts做解析,能互相ping通容器名,这是跟直接创建bridge网络不一样的地方。

4.5 创建container网络

docker run -d -it --name=web1 httpd
docker run -it --network=container:web1 busybox

4.6 查看my_net网络信息

docker network inspect my_net

4.7 查看容器网络环境

docker network ls

4.8 查看容器IP地址

docker inspect -f {{".NetworkSettings.Networks.bridge.IPAddress"}} f428149ca2cf 

4.9 查看容器网关

docker inspect -f {{".NetworkSettings.Networks.bridge.Gateway"}} f428149ca2cf 

五、参考资料

《每天五分钟玩转docker容器技术》第5章

容器网络详解

狂神说docker

posted @ 2020-01-28 10:30  努力吧阿团  阅读(616)  评论(0编辑  收藏  举报