docker网络——原来如此!!!

前言

官网文档——docker网络
这里会采用简单的语言,大概的讲解一下docker网络的情况。

网络驱动

也可以称为网络连接模式。
查看当前主机的网络分布:

docker network ls

主要分为以下几种:

  • bridge
    桥接模式,也是docker默认的网络驱动,当你需要多个容器在同一个 Docker 主机上进行通信时,桥接网络是最佳选择。
  • host
    主机模式,顾名思义,就是容器和docker主机共用网络ip、端口,但是这样就降低了容器之间的隔离性,如果不要求隔离性,就采用这种模式,话说使用docker不就是看重它的隔离性吗…。
  • none
    对于容器,禁用所有网络。通常与自定义网络驱动程序一起使用。none不适用于 swarm 服务。
  • overlay
    在多个 Docker 主机之间创建一个分布式网络,实现互相通信,适合集群,比如docker swarm。

自定义NetWork网络

不指定类型,默认创建的就是桥接模式的网络bridge。

docker network create my-bridge

指定子网掩码创建

docker network create --subnet=172.18.0.0/24 my-bridge
docker network create -d overlay my-overlay
docker network create -d host my-host
docker network create -d none my-none

查看网络详情:

docker network inspect my-bridge

删除网络

docker network rm my-bridge

容器与网络的关系

准备环境

讲之前,先准备一套干净的docker主机环境(如果有了就跳过此步骤),使用VMware克隆一台虚拟主机,在关闭的状态下,按照下边步骤更改mac地址,否则复制的主机ip跟被复制的主机ip一样,确定之后,启动新克隆的主机即可。

在这里插入图片描述

 docker rmi -f $(docker ps -aq)
 docker rmi -f $(docker images -aq)

如果有swarm相关的设置,先离开集群,再删除自动创建的docker_gwbridge网络。
最终查看变成这样既可:
在这里插入图片描述

正文讲解

上边讲了docker的基本网络知识,众所周知,用docker还是要用容器的,那么容器跟docker的关系到底是什么样的呢?你应该有这样的疑问:每个docker容器都是一个独立的linux主机,那么这些独立的容器是怎么跟docker主机联通的?容器跟容器又是为什么能互相访问?不同网络下的容器怎么互相访问,原理是什么?又该怎么实现跨主机的容器访问?跨主机实现联通的原理是什么呢?
把这些问题搞清楚了,docker的网络知识基本也能有大致的了解了,先不要想着很难,其实等你了解了,你会发现真的很简单,就像解密魔术一样,下边我们来针对每个问题进行解密,也来一步步摸清楚里边的套路。

问题一:容器是怎么跟docker主机联通的?

首先我们来运行一个容器,以nginx为例:

docker run -d --name nginx01 -p 80:80 nginx

暂停一下,先安装几个工具,以便我们更好的查看网络情况,首先在主机上安装bridge-utils,方便查看设备和网卡的关系:

yum install bridge-utils -y

在容器中安装查看ip的命令和ping命令

apt-get update

apt-get install inetutils-ping -y

apt-get install net-tools -y

继续!!!
首先,我们在容器内部连接一下主机

 docker exec -it nginx01 ping 192.168.150.133

在这里插入图片描述
可以联通,再用主机连接一下容器

#进入容器内部
docker exec -it nginx01 /bin/bash

ifconfig

在这里插入图片描述
退出返回主机

ping 172.17.0.2

在这里插入图片描述
没问题,依然能ping通,原因在哪呢,下边我们再用ip a看一下主机网络:
在这里插入图片描述
发现多了多了一个veth网卡。
在查看一下网卡详情,执行下边的命令:

brctl show

在这里插入图片描述
可以看到在docker0下挂着一个网卡,由此可见docker0创建了一对网卡,就像veth pair技术一样,让主机能够跟容器内部进行通信。
在这里插入图片描述

问题二:容器之间为什么能互相访问?

我们再运行一个nginx容器

docker run -d --name nginx02 -p 81:80 nginx

创建完成之后,会发现主机网络下,又多了一个网卡
在这里插入图片描述
docker0下也关联了两个网卡
在这里插入图片描述
同时,容器也可以互相ping通
在这里插入图片描述
原理:
在这里插入图片描述
这种网络连接方法我们称之为Bridge网桥模式,bridge也是docker中默认的网络模式,这个我们在文章开始也讲过。
如果你还有疑问,那么再执行一个命令,你就会明白了:

#查看bridge网络详情
docker network inspect bridge

在这里插入图片描述
这里显示的就是docker中所有容器的网络详情,这些容器都是默认使用bridge进行桥接。
容器中是可以访问互联网的,也是docker主机网络通过NAT进行转换的,NAT是通过iptables实现的。
在这里插入图片描述

问题三:不同网络下的容器互相访问及原理

首先我们来创建自定义网络

docker network create nginx-net --subnet=172.18.0.0/24

在这里插入图片描述
再运行一个新的nginx指定自定义网络

docker run -d --name custom-net-nginx --network nginx-net nginx

查看自定义网络详情,可以看到网络下关联着刚创建的容器
在这里插入图片描述
现在用默认网络下的nginx01 ping 自定义网络下的 custom-net-nginx(172.18.0.2)

docker exec -it nginx01 ping 172.18.0.2

显然是不通的,根本就不在一个网段下。
那么及指定nginx01到自定义网络下,命令如下:

docker network connect nginx-net nginx01

再次ping,发现可以ping通了:
在这里插入图片描述
并且还可直接通过别名ping

docker network inspect nginx-net

注意:通过别名ping只有自定义网络可以,默认的网络不行
原因:
官方解释:默认桥接网络bridge存在缺陷,不建议在生产环境中使用,只能通过 IP 地址进行通信,除非它们使用 legacy–link标志链接,但是–link也即将过时,不推荐使用。
用户定义的网桥提供容器之间的自动 DNS 解析。
下边是官方解释截图:
在这里插入图片描述
在这里插入图片描述
好啦,言归正传,那为什么connect之后,两个网络下的容器就能联通了,那么下边我们查看一下自定义网络详情就明白了:
在这里插入图片描述
当执行connect命令之后,docker会默认在自定义网络下创建容器连接,也就是说此时的nginx01同时拥有两个网段,进入nginx01容器内部你就会看到:
在这里插入图片描述

问题四:跨主机容器之间互相访问的方法和原理?

在我们使用docker swarm的时候,我们会发现,swarm集群建立之后,各节点主机上的容器之间也能互相访问。
创建swarm集群之后,会默认创建两个网络bridge和overlay网络:
在这里插入图片描述
对应容器中也会看见有两个网段,分别对应bridge和overlay。
在这里插入图片描述
overlay的网络就是实现docker多主机的分布式网络,能够实践容器多机通信也是因为它,具体原理可能就是类似 veth pair吧,详情请自行研究。

总结

其实从上边这么多的案例和讲解,也不难看出来,实现容器之间的通信原理就是建立网络,关联容器,让容器处在一个网段下即可,话虽简单,但需要理解透彻才能牢记。
其实容器内部也是能访问外网的,我们也可以在内部直接通过外网访问其他容器或者其他节点容器,但是内网更快,更省流量,这就是差别,也是追求的不同。

猜你喜欢

转载自blog.csdn.net/zwjzone/article/details/125321228