1. Docker四种网络模式
1)bridge模式(默认)
Docker使用Linux虚拟网络技术在宿主机虚拟一个名为docker0的虚拟网桥。
Docker启动一个容器时会根据Docker0网桥的网段分配给容器一个IP地址(可通过:docker inspect 容器名/ID 查看容器地址),同时Docker网桥作为每个容器的默认网关,虚拟网桥的工作方式和物理交换机类似,因为在同一宿主机内的容器都接入同一个网桥,这样主机上的所有容器就通过交换机(docker0)连在了一个二层网络中直接通信。
当创建一个 Docker 容器的时候,同时会创建了一对 veth pair接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即 eth0;另一端在本地并被挂载到docker0 网桥,名称以 veth 开头(例如 vethAQI2QT)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。Docker 就创建了在主机和所有容器之间一个虚拟共享网络。
Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法通过直接容器IP访问到容器,如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主机。

示例:创建容器并指定bridge模式
格式:--net=bridge
[root@localhost ~]# docker run -id --name=nginx --net=bridge -p 81:80 nginx:1.20.2查看容器网络:
[root@localhost ~]# docker inspect nginx
...
"bridge": {
2)Host模式
在Host类型的网络中,容器不会虚拟出自己的网卡,而是与物理机共享网络,拥有物理机的IP地址和网卡信息,而容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
Host最大的优势就是网络性能比较好,不需要进行NAT,可以直接使用宿主机的IP地址/端口与外界通信。
示例:创建容器并指定Host模式
提示:此模式无法通过-p为容器指定端口,容器内部的服务使用的是宿主机端口,各个host模式的容器不能有端口冲突。
格式:--net=host
[root@localhost ~]# docker run -id --name=nginx_host --net=host nginx:1.20.2查看容器网络
[root@localhost ~]# docker inspect nginx_host
...
host": {
查看宿主机端口信息
[root@localhost ~]# netstat -ntlp访问宿主机地址:http://192.168.0.10/
3)Container模式
这个模式指定新创建的容器和已经存在的一个容器共享一个网络,而不是和宿主机共享。
新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。
同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo(回环) 网卡设备通信。
示例:创建容器并与其他容器公用网络
格式:--net=container:容器名/容器ID
[root@localhost ~]# docker run -id --name=ngx_container --net=container:nginx nginx:1.20.24)None模式
None类型的网络,即没有网络,Docker容器不会设置容器内网络的任何信息,不会对网络进行任何配置,但是我们自己可以给该容器添加配置,给予其网络环境。
示例:创建容器并使用None模式
格式:--net=none
[root@localhost ~]# docker run -id --name=nginx_none --net=none nginx:1.20.2查看容器网络
[root@localhost ~]# docker inspect nginx_none
...
"none": {
2. Docker自定义网络
自定义容器网络可使不同的集群使用不通的网络,保证了集群是安全和健康的。
查看所有docker网络:docker network ls
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
网络 ID 网络名称 网络模式 作用域
自定义docker网络:docker network create --driver bridge --subnet 192.168.1.0/24 --gateway 192.168.1.254 mynet
create #创建网络
--driver #定义网络模式
--subnet #定义网络IP
--gateway #指定网关
mynet #是自己定义的网络名称
示例:创建一个自定义网络
[root@localhost ~]# docker network create --driver bridge --subnet 192.168.1.0/24 --gateway 192.168.1.254 mynet
#创建容器并指定容器使用mynetwork网络
[root@localhost ~]# docker run -id --net mynetwork --ip 172.15.1.10 --name=myngx nginx:1.20.2创建容器使用自定义网络:--net=名称
[root@localhost ~]# docker run -id --name=ngx_mynet --net=mynet -p 82:80 nginx:1.20.2创建容器使用自定义网络并自定义容器IP:--ip 地址
[root@localhost ~]# docker run -id --name=ngx_mynet_v1 --net=mynet --ip 192.168.1.10 -p 83:80 nginx:1.20.2查看网络详细信息:docker network inspect 网络名称/ID
[root@localhost ~]# docker network inspect mynet容器加入网络:docker network connect 网络名 容器名
自定义网络和默认网络是不通的,这样就起到了隔离的作用,那如果我们想要打通这两个网络要使用 connect 将容器加入到该网络
[root@localhost ~]# docker network connect mynet nginx查看容器网络(该容器有两个网络)
[root@localhost ~]# docker inspect nginx
...
"bridge": { "mynet": {提示:打通后,默认网络和自定义网络就可以互相通信
删除网络:docker network rm 网络名
[root@localhost ~]# docker network rm mynet提示:如果有其他容器使用该网络,需要先清理容器。
3. Docker容器互联--link
容器之间如果想要通过容器名称进行通信的话,可以通过--link来实现容器互联(单方向互联)
格式:--link name:alias
name表示要链接的容器的名称
alias是别名(也可以不指定别名)
示例:启动centos_1容器
[root@localhost ~]# docker run -id --name=centos_1 centos:7启动centos_2容器,并与centos_1互联
[root@localhost ~]# docker run -id --name=centos_2 --link centos_1 centos:7进入容器验证(注意:是单方向互联)
[root@localhost ~]# docker exec -it centos_2 /bin/bash
[root@d6f1a8fd8cd2 /]# ping centos_1查看容器的/etc/hosts文件
[root@d6f1a8fd8cd2 /]# cat /etc/hosts
172.17.0.3 centos_1 c64ac9f7fbb0注:当容器创建并启动后,会自动在hosts文件里添加解析,对于容器来说,它自己知道自己的IP地址,在没有添加--link的时候是没有172.17.0.3的解析的,当添加--link的时候,这条会自动添加。
4. Docker容器跨主机通信
docker默认的自定义网络的类型就是bridge,但是跨主机的时候bridge就明显不可用的
原生的docker跨主机通信方案有macvlan和overlay两种。
4.1 什么叫Macvlan网络?
macvlan 本身是 linxu kernel 模块,其功能是允许在同一个物理网卡上配置多个 MAC 地址,即多个 interface,每个 interface 可以配置自己的 IP。macvlan 本质上是一种网卡虚拟化技术。
使用Macvlan需要注意以下几点: 容器直接连接物理网络,由物理网络负责分配IP地址,可能的结果是物理网络IP地址被耗尽,另一个后果是网络性能问题,物理网络中接入的主机变多,广播包占比快速升高而引起的网络性能下降问题;宿主机上的物理网卡(ens33)需要工作在 混乱模式 下;前面说到,工作在混乱模式下的物理网卡,其MAC地址会失效,所以,此模式中运行的容器并不能与外网进行通信,但是不会影响宿主机与外网通信;从长远来看bridge网络与overlay网络是更好的选择,原因就是虚拟网络应该与物理网络隔离而不是共享。
Macvlan本身不创建网络,本质上首先使宿主机物理网卡工作在‘混杂模式’,这样物理网卡的MAC地址将会失效,所有二层网络中的流量物理网卡都能收到。接下来就是在这张物理网卡上创建虚拟网卡,并为虚拟网卡指定MAC地址,实现一卡多用,在物理网络看来,每张虚拟网卡都是一个单独的接口。
4.2 什么叫做overlay网络?
overlay网络用于连接不同机器上的docker容器,允许不同机器上的容器相互通信,同时支持对消息进行加密。
字面意思就是叠加的网络,指的就是在物理网络层上再搭建一层网络,通过某种技术再构建一张相同的网络,这张称为逻辑网。
也就是说我们想要两台主机的容器进行通讯,首先这两台主机自己要可以通讯,然后在这个物理机的基础之上部署一张逻辑层的网络,他具有物理网络的所有特性,跟物理网络一模一样。
VLAN是什么,我们想要划分网络就叫做VLAN,VLAN只是单纯的对物理网络进行划分,隔离ip,Mac。VLAN是划分广播域的最基础概念。
vxlan是在物理网络基础之上构建出来的网络,这个网络可以通过 vxlan进行划分,ip,Mac只需要在一个vxlan中就可以进行通讯。
因此,Overlay网络实际上是目前最主流的容器跨节点数据传输和路由方案。
4.3 Overlan环境准备
注:每个节点安装Docker服务,每台宿主机的hostname必须不同。
4.4 运行consul服务
Docker Overlay 网络需要一个 key-value数据库用于保存网络状态信息, 包括 Network、Endpoint(节点)、IP 等。
Consul、Etcd 和 ZooKeeper 都是 Docker 支持的 key-vlaue 软件,我们这里使用 Consul。
在consul主机执行如下命令:
[root@consul ~]# docker run -d -p 8500:8500 -h consul --name consul --restart always progrium/consul -server -bootstrap
解释:
- -server -bootstrap #指定运行模式(该模式指定本机为server端)
- -h #设置容器主机名
--restart always #设置容器退出后自动自动容器4.5 Docker节点加入consul
修改其他节点配置文件,使得每一台都通过本机的2376(docker监听端口)端口被转发到192.168.0.12:8500,consul收集存储并使用这些信息实现网络一致。
docker10主机修改/usr/lib/systemd/system/docker.service文件,将文件中的ExecStart参数替换成如下参数(根据自己的环境修改consul地址)
[root@docker10 ~]# vim /usr/lib/systemd/system/docker.service
...
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376 --cluster-store=consul://192.168.0.12:8500 --cluster-advertise=ens32:2376
解释:
--cluster-store #指定consul地址
--clusteradvertise #指定本机网卡及端口重启服务
[root@docker10 ~]# systemctl daemon-reload
[root@docker10 ~]# systemctl restart docker直接将配置文件拷贝到docker11与consul主机即可
#拷贝到docker11主机
[root@docker10 ~]# scp /usr/lib/systemd/system/docker.service root@192.168.0.11:/usr/lib/systemd/system/docker.service
#拷贝到consul主机
[root@docker10 ~]# scp /usr/lib/systemd/system/docker.service root@192.168.0.12:/usr/lib/systemd/system/docker.servicedocker11重启docker服务
[root@docker11 ~]# systemctl daemon-reload
[root@docker11 ~]# systemctl restart dockerconsul重启docker服务
[root@consul ~]# systemctl daemon-reload
[root@consul ~]# systemctl restart docker4.6 访问consul
最后我们可以通过浏览器访问consul服务:http://192.168.0.12:8500/
不同主机的docker已经添加到了一起。
4.7 创建Overlan网络
在任意一个节点创建一个网络,我们在docker10创建一个网络
[root@docker10 ~]# docker network create -d overlay myovernet提示:网络默认使用的10.0.0.0/24网段,如果需要自定义网络地址通过下边命令创建。(别跟宿主机在同一个网络,容易发生地址冲突)
docker network create -d overlay --subnet 172.16.1.0/24 --gateway 172.16.1.254 myovernet4.8 验证Overlan网络
这时候每一个节点都会有这个网络
#docker10主机查看
[root@docker10 ~]# docker network ls
60210366228b myovernet overlay global
#docker11主机查看
[root@docker11 ~]# docker network ls
60210366228b myovernet overlay global
#consul主机查看
[root@consul ~]# docker network ls
60210366228b myovernet overlay globalOverlan默认的网段是10.0.0.0/24
[root@docker11 ~]# docker network inspect myovernet
{
"Subnet": "10.0.0.0/24",
"Gateway": "10.0.0.1"
}docker10、docker1、consul分别创建centos容器测试跨主机通信
[root@docker10 ~]# docker run -it --name=c10 --net=myovernet centos:7 /bin/bash
[root@docker11 ~]# docker run -it --name=c11 --net=myovernet centos:7 /bin/bash
[root@consul ~]# docker run -it --name=c12 --net=myovernet centos:7 /bin/bash测试连通性:docker自定义的网落是自带域名解析的,所以直接ping名字
[root@097d21377fcc /]# ping c11
[root@097d21377fcc /]# ping c12查看容器IP
[root@097d21377fcc /]# hostname -I
10.0.0.2 172.18.0.2
#注:10.0.0.2是容器内部的地址,172.18.0.2是容器与宿主机之间的网关,如果宿主机可以访问外网,容器借助该网关转可换成宿主机IP访问外网。
评论区