Docker:容器bridge模式网络使用

bridge网络

ip a

查看到docker0网络(安装docker时自动创建),容器默认都是通过docker0这个接口进行通信。也可以通过docker0去和本机的以太网接口连接,这样容器内部才能访问互联网。

# 查看docker 网络
docker network ls

在这里插入图片描述
我们看到有bridge网络

# 查看bridge网络详情。主要关注Containers节点信息。
docker network inspect bridge

Containers为空,如果不为空就是docker run不指明网络模式,就是默认是bridge模式,即容器自动关联到bridge网络。
实践证实

docker run -itd --name nginx1 nginx:1.19.3-alpine

# 查看bridge网络详情。主要关注Containers节点信息。发现nginx1容器默认使用bridge网络
docker network inspect bridge

# 查看docker100主机网络。发现多出一块网卡veth62aef5e@if8
ip a

Docker 创建一个容器的时候,会执行如下操作:
• 创建一对虚拟接口/网卡,也就是veth pair,分别放到本地主机和新容器中;
• 本地主机一端桥接到默认的 docker0 或指定网桥上,并具有一个唯一的名字,如 vetha596da4;
• 容器一端放到新容器中,并修改名字作为 eth0,这个网卡/接口只在容器的名字空间可见;
• 从网桥可用地址段中(也就是与该bridge对应的network)获取一个空闲地址分配给容器的 eth0,并配置默认路由到桥接网卡 vetha596da4。
完成这些之后,容器就可以使用 eth0 虚拟网卡来连接其他容器和其他网络。
如果不指定–network,创建的容器默认都会挂到 docker0 上,使用本地主机上 docker0 接口的 IP 作为所有容器的默认网关。
查看容器里的网段

# 第一种方式:
docker exec -it nginx1 sh

ip a

# 第二种方式:
docker exec -it nginx1 ip a

发现除了回环lo网段还有一个其他网段 eth0
验证宿主机新生产的网段与容器内的网段eth0是否是一对

# 安装brctl
yum install -y bridge-utils

brctl show

在这里插入图片描述
发现docker0与新生成的网段vetha596da4是绑定的,证明成功。

多容器之间通讯

docker run -itd --name nginx1 nginx:1.19.3-alpine
docker run -itd --name nginx2 nginx:1.19.3-alpine

# 查看bridge网络详情。主要关注Containers节点信息,
# 发现了nginx1和nginx2的信息包括分配的IP地址
docker network inspect bridge
# 在宿主机上ping,172.17.0.2是分配给nginx1容器的IP地址,
# 结果能ping通
ping 172.17.0.2
# 进入容器
docker exec -it nginx2 sh
# 在容器中ping宿主机ip地址
# 结果能ping通
ping 192.168.198.100

# 在容器中ping外网ip地址
# 结果能ping通
ping www.baidu.com

# 在容器中ping另个容器nginx2的ip地址
# 结果能ping通
ping 172.17.0.3

# 在容器中ping另个容器nginx2的name
# 结果不能ping通
ping nginx2

需求是能通过容器name直接进行网络通信

因为容器IP地址会发生变化(通过ip地址进行通信行不通,通过容器name)

docker stop nginx1 nginx2

# 先启动nginx2,在启动nginx1
# 以前是先启动nginx1,在启动nginx2
docker start nginx2
docker start nginx1

# 发现容器分配的ip地址发生变化
docker network inspect bridge

解决

第一种

docker run命令的link参数
–link=[]: 添加链接到另一个容器;不推荐使用该参数

docker rm -f nginx2

docker run -itd --name nginx2 --link nginx1 nginx:1.19.3-alpine

docker exec -it nginx2 sh

# 在容器里都能ping通包括nginx1
# 172.17.0.2分配给nginx1的ip地址
ping 172.17.0.2
ping www.baidu.com
# 能ping通
ping nginx1

# 退出容器
exit

docker exec -it nginx1 sh
# 在容器里都能ping通不包括nginx2
# 172.17.0.3分配给nginx2的ip地址
ping 172.17.0.3
ping www.baidu.com
# 不能ping通
ping nginx2

说明

  • 上面link命令,是在nginx2容器启动时link到nginx1容器,因此,在nginx2容器里面可以ping通nginx1容器名,link的作用相当于添加了DNS解析。这里提醒下,在nginx1容器里去ping nginx2容器是不通的,因为link关系是单向的,不可逆。
  • 实际工作中,docker官网已经不推荐我们使用link参数。
  • docker用其他方式替换掉link参数

使用link的场景
在企业开发环境中,我们有一个mysql的服务的容器mysql_1,还有一个web应用程序web_1,肯定web_1这台容器肯定要连接mysql_1这个数据库。前面网络命名空间的知识告诉我们,两个容器需要能通信,需要知道对方的具体的IP地址。生产环境还比较好,IP地址很少变化,但是在我们内部测试环境,容器部署的IP地址是可能不断变化的,所以,开发人员不能在代码中写死数据库的IP地址。这个时候,我们就可以利用容器之间link来解决这个问题。下面,我们来介绍如何通过容器名称来进行ping,而不是通过IP地址。

第二种

新建bridge网络

# 新建bridge网络
docker network create -d bridge my-bridge

brctl show

在这里插入图片描述
发现新建了一个网卡

# 发现多个一个my-bridge
docker network ls
# 发现Gateway网关与bridge不一样,分配的网段不一样
docker network inspect my-bridge
docker run -itd --name nginx3 --network lagou-bridge nginx:1.19.3-alpine

brctl show

docker network inspect lagou-bridge

把一个运行中容器连接到my-bridge网络

docker network connect my-bridge nginx2

docker network inspect my-bridge

docker exec -it nginx2 sh
# 能ping通
ping nginx3

docker exec -it nginx3 sh
# 能ping通
ping nginx2

你可能感兴趣的:(docker,docker,桥接模式,网络)