ip a
查看到docker0网络(安装docker时自动创建),容器默认都是通过docker0这个接口进行通信。也可以通过docker0去和本机的以太网接口连接,这样容器内部才能访问互联网。
# 查看docker 网络
docker network ls
# 查看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
因为容器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的场景:
在企业开发环境中,我们有一个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