我们在使用docker run创建Docker容器时,可以用--net选项指定容器的网络模式,Docker有以下4种网络模式:
· host模式,使用--net=host指定。
· container模式,使用--net=container:NAME_or_ID指定。
· none模式,使用--net=none指定。
· bridge模式,使用--net=bridge指定,默认设置。
下面分别介绍一下Docker的各个网络模式。
1 host模式
默认docker容器运行会分配独立的networknamspace隔离子系统(bridge模式)。
而基于host模式,容器将不会获得一个独立的networknamespace,而是和宿主机共用,容器将不会虚拟出自己的网卡等信息,而是使用宿主机的IP和端口。
例:我们在10.10.101.105/24的机器上用host模式,启动一个web应用的Docker容器,监听tcp80端口。当我们在容器中查看网络环境时,看到的都是宿主机上的信息。而外界访问容器中的应用,则直接使用10.10.101.105:80即可,不用任何NAT转换,就如直接跑在宿主机中一样。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
2 container模式
就是容器之间共享一个networknamespace,而不是和宿主机共享。也就是说新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享网络环境。同样,两个容器除了网络方面相同之外,其他的包括文件系统,进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。
3 none模式
这个模式和前两个不同。在这种模式下,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
4 bridge模式
bridge模式是docker默认的网络模式,该模式宿主机会为每一个容器自动分配一个networknamespace,默认会将docker容器连接到一个虚拟网桥交换机docker0上。下面着重介绍一下此模式。
bridge模式的拓扑
4-1 新建docker0虚拟网桥,连接容器。
当Docker server启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机(docker0)连在了一个二层网络中。
4-2 分配网桥IP和容器IP
Docker从RFC1918定义的私有IP网段中,选择一个和宿主机不同的IP和子网,分配给docker0。连接docker0的容器再从这个子网中,分配一个未占用的IP使用。具体如下:
4-2-1 在主机上创建一对虚拟网卡veth pair设备。一端放入新创建容器中,命名为eth0。另一端放在主机中,命名类似veth65f9,并加入docker0网桥,可以通过brctl show命令查看。
brctl show
4-2-2 从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。
如:Docker将172.17.42.1/16分配给docker0网桥(在主机上使用ifconfig命令是可以看到docker0的,可以认为它是网桥的管理接口,在宿主机上作为一块虚拟网卡使用)。单机环境下的网络拓扑如下,主机地址为10.10.101.105/24。
此时容器IP与宿主机是可以通信的,宿主机也可以访问容器中的ip地址,在bridge模式下,连接同一网桥的容器之间可以相互通信,同时容器可以访问外网,但是其他物理机不能访问docker容器IP,需要通过NAT将容器的IP的port映射为宿主机的IP和port
container网络模式用法:
docker-compose.yml
用法:
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
例:
version: '3'
services:
cm_mysql57:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=root
ports:
- "3306:3306"
cm_phpfpm72:
image: "php:7.2-fpm"
# build:
# context: ./php/
ports:
- "9000:9000"
- "80:80"
volumes:
- "/mnt/www:/mnt/www"
links:
- cm_mysql57:mysql
extra_hosts:
- "api.catmes.test:127.0.0.1"
- "symfony.test:127.0.0.1"
depends_on:
- cm_mysql57
cm_nginx:
image: "nginx"
# ports:
# - "80:80"
volumes:
- "/mnt/www:/mnt/www"
- "/root/vhost:/etc/nginx/conf.d"
# links:
# - cm_phpfpm72:phpfpm
depends_on:
- cm_phpfpm72
# extra_hosts:
# - "phpfpm:127.0.0.1"
network_mode: "service:cm_phpfpm72"
DockerFile获取宿主机IP写入容器的hosts
RUN /sbin/ip route|awk '/default/ { print $3,"\tdockerhost" }' >> /etc/hosts
【原创】Docker四种网络模式: https://www.cnblogs.com/gispathfinder/p/5871043.html
聊一聊Docker网络通信 https://blog.51cto.com/11880730/2115614
Docker容器与宿主机同网段互相通信 http://www.louisvv.com/archives/695.html
Docker内如何访问本机(宿主机) https://blog.csdn.net/u010416101/article/details/80534013