docker的网络连接
为什么需要Docker网络?
先看下图是不使用docker的网络示意图
网络存在的问题:
1、使用宿主机网络因为需要转发请求,影响网络效率
2、使用宿主机网络需要绑定IP后期迁移机器需要更改IP
Docker的网络模式:
Docker的网络模式有:bridge模式(桥接)、host模式、container模式、none模式、overlay模式
Docker网络模式 | 配置 | 说明 |
---|---|---|
host模式 | –net=host | 容器和宿主机共享Network namespace。 |
container模式 | –net=container:NAME_or_ID | 容器和另外一个容器共享Network namespace。 kubernetes中的pod就是多个容器共享一个Network namespace。 |
none模式 | –net=none | 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等。 |
overlay模式 | -- driver overlay | Docker跨主机通信模式,使用分布式计算机架构后需要使用overlay网络模式 |
bridge模式 | –net=bridge | 默认为该模式,默认情况下容器会自动加入到docker0这个网桥下面 |
bridge模式(桥接)
Bridge模式下容器有自己的网络IP,默认会和Docker0网桥建立连接,默认情况下的容器网络是bridge网络
bridge模式特点:
1、容器拥有自己的IP
2、默认和Docker0网桥建立连接,通过Docker0可以互相通信
3、如果外部访问需要暴露端口映射才能访问(因为他们是通过Docker0网桥建立互相通信的,而Docker0是虚拟网卡)
查看当前ip,并找到Docker0,启动一个容器会自动加人到docker0这个网桥中
ip addr
查看docker的网络有哪些,找到name是bridge的就是docker0
docker network ls
查看docker0网桥的详细信息
docker inspect 【docker0的网络id】
Host网络
Host网络共享宿主机的网络,不会有自己的虚拟网卡,相当于宿主机启动了一个服务
Host网络的特点:
1、共享的是宿主机的网络(不再跟docker0进行网络桥接了,直接跟物理机网卡建立连接)
2、不需要映射端口号
3、会占用端口号(因为它和和物理机网卡直接建立连接所以会直接占用物理机的端口号)
启动容器并用host创建网络:
docker.run -d \
-v /tmp/data/logs:/logs --net=host \
--name learn-docker-storage \
learn-docker-storage:0.0.2
创建之后发现他不需要端口映射它也不会加入到docker0的网桥中,相当于在物理机直接启动一个服务
Container模式(容器模式)
Container模式会共享容器的网络,两个容器可以通过127.0.0.1来进行通讯,但是端口号不能冲突
Container模式的特点:
1、容器之间共享网络
2、容器之间访问使用127.0.0.1加端口进行访问
None模式
None模式容器不会分配IP信息,容器不会和Docker0建立连接,外部也不能访问到容器
None模式的特点:
1、没有网络IP
2、外部不能访问容器
3、虽然none模式没有网络IP,但它有网络管理和虚拟网卡,可以针对网卡进行单独的配置
Overlay模式
Overlay模式是一个跨主机网络,允许多个服务器之间的容器就像是本地一样互相访问
Overlay网络特点:
1、支持跨主机网络,支持多台服务器之间进行通讯
2、多服务器之间无缝访问(集群间的网络连接就像本地连接一样)
![](/i/l/?n=24&i=blog/3482053/202412/3482053-20241227144509236-1877124879.png =300X666 )
docker的网络优化
网络优化的意义:
原本的网络是需要宿主机进行转发的,这样的请求方式效率比较低,并且容器内的应用与宿主机是绑定的
优化思路:
1、不使用宿主机网络可以提高网络速度
2、容器直接进行网络连接
措施:
自定义网络:通过自定义来连接我们自己的网络
自定义网络
--network=learn-docker-network \
1、自定义网络可以使用网络内部的IP进行访问
2、网络IP会随着容器的重启而变更(容器销毁再重建网络ip会发生变化)
3、可以使用容器名称来进行访问服务,可以避免IP变动问题(不使用IP进行访问改为域名)
Pom配置由原本的IP方式换成域名访问
修改前:
<mysql.addr>192.168.81.152:3306</mysql.addr>
<nacos.addr>192.168.81.152:8848</nacos.addr>
修改后:
<mysql.addr>mysql:3306</mysql.addr>
<nacos.addr>nacos:8848</nacos.addr>-->
运行容器:
修改前:
docker run-d \
-p 3306:3306
-v /tmp/etc/mysql:/etc/mysql/mysql.conf.d/ \
-v /tmp/data/mysql:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
--name mysql \
mysql:5.7.34
修改后:(使用自定义网桥来进行互相通讯,不需要借助宿主机的网桥完成通讯,所以他就不需要暴露端口了)
docker run -d \
-v /tmp/etc/mysql:/etc/mysql/mysql.conf.d/ \
-v /tmp/data/mysql:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
--name mysql --network=learn-docker-network \
mysql:5.7.34
查看docker网络情况:
查看docker网络
docker network ls
查询自定义的网络信息
docker inspect【网络ID】
测试网络连通性:
进入nacos:
docker exec ti nacos /bin/bash
ping命令测试网络是否能够通讯
五大模式总结
1.host模式:
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好。
2.container模式:
这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过io网卡设备通信。
3.none模式:
使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
这种网络模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器创建时通过--network=none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。
4.overlay模式:
容器在两个跨主机进行通信的时候,是使用overlay network这个网络模式进行通信,如果使用host也可以实现跨主机进行通信,直接使用这个物理的ip地址就可以进行通信。overlay它会虚拟出一个网络比如10.0.9.3这个ip地址,在这个overlay网络模式里面,有一个类似于服务网关的地址,然后把这个包转发到物理服务器这个地址,最终通过路由和交换,到达另一个服务器的ip地址。
5.bridge模式:
当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看。
bridge模式是docker的默认网络模式,不写--net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用 iptables -t nat -vnL查看。