一、概述
Docker
容器每次重启后容器
ip
是会发生变化的。
这也意味着如果容器间使用
ip
地址来进行通信的话,一旦有容器重启,重启的容器将不再能被访问到。
而
Docker
网络就能够解决这个问题。
Docker
网络主要有以下两个作用:
- 容器间的互联和通信以及端口映射
- 容器
IP
变动时候可以通过服务名直接网络通信而不受到影响
因此只要是处于同一个
Docker
网络下的容器就可以使用服务名进行直接访问,而无需担心重启。
这也是
Docker
网络最基本和常用的应用场景。
二、Docker的四种网络模式
网络模式命令指定方式描述bridge–network bridge为每一个容器分配、设置
ip
,并将容器连接到
docker0
虚拟网桥上,这也是默认网络模式host–network host容器不会创建自己的网卡,配置
ip
等,而是使用宿主机的
ip
和端口container–network 容器名称或id新创建的容器不会创建自己的网卡和配置自己的
ip
,而是和一个指定的容器共享
ip
、端口范围none–network none容器有独立的
Network namespace
,但并没有对其进行任何网络设置
如果觉得–network太长了也可以使用简写-net,效果是一样的
而
Docker
安装完成时,一般会自动创建三个网络:
NETWORK ID NAME DRIVER SCOPE
40547f9137a5 bridge bridge local
b40bdb8f0356 hosthostlocal
0c7f9938f868 none null local
可以使用下列命令查看:
docker network ls
2.1 桥接模式–bridge
Docker
服务启动 时,默认会创建一个名称为
docker0
网桥(其上有一个名称为
docker0
内部接口)。
该桥接网络的名称为
docker0
,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。
Docker
会 默认指定
docker0
的
ip
地址和子网掩码,让主机和容器之间可以通过网桥相互通信。
1)桥接模式原理图
2)桥接模式解析
Docker
使用Linux
桥接的方式,在宿主机虚拟一个Docker
容器网桥(docker0
)。Docker
每启动一个容器时会根据Docker
网桥的网段分配给容器一个ip
地址。同时Docker
网桥是每个容器的默认网关。同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。docker run
创建容器的时,未指定network
的容器默认的网络模式就是bridge
,使用的就是docker0
。在宿主机ifconfig
,就可以看到docker0
和自己创建的network
:-eth0
,eth1
……代表网卡一,网卡二……-lo
代表127.0.0.1(localhost
)-inet addr
表示网卡的ip
地址- 网桥
docker0
会创建一对对等虚拟设备接口:一个叫veth
,另一个叫eth0
,成对匹配。- 整个宿主机的网桥模式都是docker0
,类似一个交换机有一堆接口,每个接口叫veth
,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫veth pair
);- 每个容器实例内部也有一块网卡,每个接口叫eth0
;-docker0
上面的每个veth
匹配某个容器实例内部的eth0
,两两配对。
2.2 主机模式–host
不创建任何网络接口,直接使用宿主机的
ip
地址与外界进行通信,不再需要额外进行
NAT
转换。
在主机模式下不能publish port。
1)主机模式原理图
2)主机模式解析
容器将不会获得一个独立的
Network Namespace
, 而是和宿主机共用一个
Network Namespace
。
容器将不会虚拟出自己的网卡而是使用宿主机的IP和端口。
容器共享宿主机网络
ip
,这样的好处是外部主机与容器可以直接通信。
小拓展:
Docker
启动时指定
--network=host
或
-net=host
,如果还指定了
-p
映射端口,此时就会有如下警告:
NARNING: Published ports are discarded when using host network mode
并且通过
-p
设置的参数将不会起到任何作用,端口号会以主机端口号为主,重复时则递增。
可以选择无视这个警告或者使用
Docker
的其他网络模式,例如
--network=bridge
2.3 容器模式–container
1)容器模式原理图
2)容器模式解析
新建的容器和已经存在的一个容器共享一个网络
ip
配置而不是和宿主机共享。
新创建的容器不会创建自己的网卡,配置自己的
ip
,而是和一个指定的容器共享
ip
、端口范围等。
两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。
2.4 none模式
在
none
模式下,并不为
Docker
容器进行任何网络配置。
也就是说,这个
Docker
容器没有网卡、
ip
、路由等信息,只有一个
lo
接口。
lo标识代表禁用网络功能,即:127.0.0.1,本地回环的意思
需要我们自己为Docker容器添加网卡、配置IP等。
三、常用命令
在学习
Docker
各种网络模式前,先要了解
Docker
网络的常用命令。
2.1 查看网络
docker network ls
2.2 创建网络
# 基础用法docker network create 网络名称
# 创建网络时是可以添加一系列参数的:# --driver:驱动程序类型# --gateway:主子网的IPV4和IPV6的网关# --subnet:代表网段的CIDR格式的子网# mynet:自定义网络名称docker network create --driver=bridge --gateway=192.168.137.1 --subnet=192.168.137.0/16 mynet
不指定任何选项的时候默认的–driver(网络模式)也是bridge(桥接)
但是gateway和subnet会自动生成
2.3 查看网络数据源
docker network inspect 网络名称
2.4 将容器连接到指定网络
docker network connect 网络名称 容器名称
2.5 断开容器的网络
docker network disconnect 网络名称 容器名称
2.6 删除所有不在使用的网络
docker network prune
2.7 删除一个或多个网络
docker network rm 网络名称
四、使用示例
4.1 创建容器时挂载网络
1)创建一个桥接类型的网络
docker network create --driver=bridge --gateway=192.168.137.1 --subnet=192.168.137.0/16 myNet1
2)创建并运行容器时指定网络
docker run --name containerName -p80:80 -d--network myNet1 myNginx
3)不想用时可以断开网络
docker network disconnect myNet1 myNginx
4.2 容器已存在时连接到新网络
1)创建一个桥接类型的网络
docker network create --driver=bridge --gateway=192.168.137.1 --subnet=192.168.137.0/16 myNet2
2)为容器连接新的网络
# 执行后myNginx容器的网络就变成了myNet2docker network connect myNet2 myNginx
3)不想用时可以断开网络
docker network disconnect myNet2 myNginx
4.3 使用docker-compose给一组容器挂载网络
有如下
docker-compose.yml
文件。
一般来说此时使用如下面命令编排的一组容器时会默认创建一个网络,并且这组容器全部都会加入到网络当中。
docker-compose up -d
这也是这一组容器之间可以直接使用服务名去直接通信的原因。
version:'3'services:nginx:image: nginx:alpine
container_name: nginx-dev
environment:- TZ=Asia/Shanghai
ports:-"80:80"volumes:- /usr/local/docker/workspace/nginx/html:/usr/share/nginx/html
- /usr/local/docker/workspace/nginx/conf/nginx.conf:/etc/nginx/conf.d/default.conf
mysql:image: mysql:8container_name: mysql-dev
environment:- TZ=Asia/Shanghai
- MYSQL_ROOT_PASSWORD=89225300
- MYSQL_DATABASE=nacos_config
- MYSQL_USER=gddst
- MYSQL_PASSWORD=123456
ports:-"3306:3306"volumes:- /usr/docker/docker/workspace/mysql/data:/var/lib/mysql
- /usr/docker/docker/workspace/mysql/mysql.cnf:/etc/mysql/conf.d/mysql.cnf
- /usr/docker/docker/workspace/mysql/initdb:/docker-entrypoint-initdb.d
但是如果想要显示的指定网络,可以参考如下配置:
networks:mynet:driver: bridge
ipam:config:-subnet:"192.168.0.101/16"gateway: 192.168.0.100
配置好网络后,在每个服务下可以指定使用的网络,这里就以
nginx
为例:
version:'3'services:nginx:image: nginx:alpine
container_name: nginx-dev
environment:- TZ=Asia/Shanghai
ports:-"80:80"volumes:- /usr/local/docker/workspace/nginx/html:/usr/share/nginx/html
- /usr/local/docker/workspace/nginx/conf/nginx.conf:/etc/nginx/conf.d/default.conf
networks:- mynet
networks:mynet:driver: bridge
ipam:config:-subnet:"192.168.0.101/16"gateway: 192.168.0.100
这样容器编排时,所有容器都会加入到
mynet
这个自定义网络当中了。
版权归原作者 流水武qin 所有, 如有侵权,请联系我们删除。