Docker网络讲解与实战
一、Docker网络基础
1. 默认网络模式:Bridge(桥接模式)
Docker网络默认是bridge,即桥接模式。所有容器都默认连接到这个网络,每个容器都分配了一个内部IP地址,一般是172.17开头的,在这个内部子网里面,容器可以通过内部IP地址互相访问,但容器网络与宿主机的网络是隔离的。

2. 创建自定义子网
使用以下命令创建出子网,默认情况下,创建出来的子网也是属于桥接模式的一种。
docker network create
可以指定容器加入不同的子网,同一个子网的容器可以互相通信,而跨子网则不可以通信。

3. 创建子网的好处
同一个子网的容器,可以使用容器的名字互相访问,而不必使用内部IP地址。
4. 查看创建的网络
sudo docker network ls
二、自定义子网实战案例
1. 创建自定义子网
创建一个叫做network1的子网:
sudo docker network create network1
2. 创建MongoDB容器
创建并运行一个mongodb容器。
这里使用--network,指定它加入network1子网:
sudo docker run -d \
--name my_mongodb \
-e MONGO_INITDB_ROOT_USERNAME=gwt \
-e MONGO_INITDB_ROOT_PASSWORD=gwt123 \
--network network1 \
mongo
启动mongodb的时候没有使用-p参数进行端口映射,这时候使用宿主机是无法访问到这个mongodb的。
3. 创建MongoDB Express容器
再启动一个mongo_express容器,这个容器是mongodb的网页客户端,同样将它加入到network1子网中:
sudo docker run -d \
--name my_mongodb_express \
-p 8081:8081 \
-e ME_CONFIG_MONGODB_SERVER=my_mongodb \
-e ME_CONFIG_MONGODB_ADMINUSERNAME=gwt \
-e ME_CONFIG_MONGODB_ADMINPASSWORD=gwt123 \
--network network1 \
mongo-express
因为my_mongodb_express和my_mongodb这两个容器是属于同一个子网的,所以它们之间是可以互相访问的。
其中,my_mongodb_express容器做了一个-p 8081:8081端口映射,且这里-e ME_CONFIG_MONGODB_SERVER=my_mongodb传递的环境变量没有传数据库容器在子网的IP地址,而是直接把名字告诉了它。
4. 浏览器访问验证
在浏览器中输入服务器的IP地址进行访问,端口是刚刚配置的8081。
首次访问时要进行登录,默认账号是:admin,密码是:pass

5. 常见问题排查
问题1:容器莫名退出
当容器莫名退出时,第一件事是查看日志:
sudo docker logs my_mongodb_express
问题2:浏览器无法访问
若在浏览器中无法访问(很大可能是防火墙问题,端口未开放)
排查步骤:
第一步:在服务器上确认端口正在监听
sudo ss -tlnp | grep 8081
如果有输出(显示0.0.0.0:8081),说明Docker监听正常,问题在防火墙。
第二步:检查防火墙状态
# Ubuntu使用ufw
# 查看防火墙开放的端口
sudo ufw status
第三步:开放8081端口
sudo ufw allow 8081/tcp
sudo ufw reload
快速验证:
在服务器本机执行:
curl -I http://127.0.0.1:8081
- 如果有响应 → 防火墙问题,开放端口即可
- 如果拒绝连接 → mongo-express本身有问题,查看日志
三、网络拓扑结构分析
1. DNS机制
两个容器分配在同一个子网里面,它们可以互相通信。
这里注意到,启动第二个容器my_mongodb_express的时候,没有告诉第二个容器关于第一个容器在子网里面的IP地址,而是仅仅告诉了它第一个容器的名字,借助于Docker内部的DNS机制,通过名字就可以在子网内进行互相访问。

2. 验证DNS机制
在此进入到第二个容器:
sudo docker exec -it my_mongodb_express /bin/sh
然后在容器中执行ping命令:
ping my_mongodb
输出:
/app # ping my_mongodb
PING my_mongodb (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.058 ms
64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.080 ms
64 bytes from 172.18.0.2: seq=2 ttl=64 time=0.873 ms
64 bytes from 172.18.0.2: seq=3 ttl=64 time=0.078 ms
64 bytes from 172.18.0.2: seq=4 ttl=64 time=0.059 ms
可以看到其中打印出了第一个容器的IP地址:172.18.0.2
这表示Docker子网内部有一个DNS机制,可以把名字转换成IP地址。
3. 完整网络拓扑
之前做了一个端口映射,让浏览器可以访问到my_mongodb_express,然后my_mongodb_express又可以通过内部子网访问到my_mongodb,这样达成最终的效果。

四、其他网络模式
1. Host模式
以上让我们看到了默认的桥接模式和创建子网的桥接模式。
另外一种网络模式 - host模式
Docker容器直接共享宿主机的网络,容器直接使用宿主机的IP地址,而且无需-p参数进行端口映射。容器内的服务直接运行在宿主机的端口上。通过宿主机的IP和端口就能访问到容器。
host模式可以解决一些非常棘手的网络问题。
(1) 使用host模式启动nginx
sudo docker run -d --network host nginx
(2) 进入容器查看IP地址
sudo docker exec -it 容器ID /bin/sh
在容器内部查看ip地址需要安装一些工具:
apt update
apt install iproute2
# 查看ip地址
ip addr show
可以看到,与我的宿主机ip地址一致。

从中可以看出,Docker容器使用host模式它直接共享了宿主机的网络空间。
2. None模式
none模式完全禁用网络,适合对安全隔离要求极高的场景。
五、常用网络命令
docker network ls # 查看所有网络
docker network inspect bridge # 查看网络详情(含容器IP)
docker network create mynet # 创建自定义网络
docker network connect mynet 容器名 # 把已有容器加入网络
docker network disconnect mynet 容器名 # 从网络移除容器
docker network rm networkID/子网名 # 删除自定义子网

1592

被折叠的 条评论
为什么被折叠?



