3.1 网络配置(上篇)

本次实验有两个主要任务:
- 将容器内部的端口暴露给主机,使外部能够访问容器内的服务
- 创建自定义桥接网络,并验证不同网络配置下容器间的互通性
准备工作
在开始实验前,我们需要清理环境,删除所有现有的容器和本地镜像:
# 停止所有运行中的容器
docker stop $(docker ps -q)
# 删除所有容器
docker rm $(docker ps -a -q)
# 删除所有本地镜像
docker rmi $(docker images -q)
关键命令
创建网桥
docker network create [参数] <网络名称>
常用参数:
--driver
:指定网络驱动类型,如bridge、overlay等
查看网络详细信息
docker network inspect <网络名或ID>
或者:
docker inspect <网络ID>
进入后台运行的容器
docker exec [参数] <容器名或ID> <命令>
例如:
docker exec -it 容器名 /bin/bash # 对于基于Debian/Ubuntu的容器
docker exec -it 容器名 ash # 对于基于Alpine的容器
运行容器时映射端口
docker run -p 主机端口:容器端口 <镜像名>
也可以使用 -P
参数映射所有需要暴露的端口。
实验过程
任务一:端口映射
Docker容器默认情况下是隔离的,外部无法直接访问容器内的服务。端口映射允许我们将容器内的端口映射到主机上,使外部能够访问容器内的服务。
1.1 发布特定端口
通过 -p
参数,我们可以将容器内的特定端口映射到主机的指定端口。
1.准备镜像
docker pull harbor.seahi.me/stu/mysite:v0.2
2.将容器内的80端口映射给主机的999端口
docker run --rm -d --name mysite -p 999:80 harbor.seahi.me/stu/mysite:v0.2
--rm
:容器停止后自动删除-d
:后台运行容器--name mysite
:指定容器名称-p 999:80
:将容器内的80端口映射到主机的999端口
3.验证端口映射
首先,查看容器状态:
docker ps
从输出中可以看到,容器正在运行,并且端口映射已经建立(0.0.0.0:999->80/tcp)。
接下来,打开浏览器访问服务器IP和映射的端口号:
成功访问表明端口映射工作正常。
4.停止容器
docker stop mysite
由于我们使用了--rm
参数,容器停止后会自动删除。
1.2 发布所有暴露端口
使用 -P
参数可以自动将容器中所有暴露的端口(通过Dockerfile中的EXPOSE指令定义)映射到主机上的随机端口。
1.运行容器并自动映射端口
docker run --rm -d --name mysite -P harbor.seahi.me/stu/mysite:v0.2
2.查看映射的端口
docker port mysite
可以看到,Docker将容器内的80端口映射到了主机上的一个随机端口(在这个例子中是32768)。
3.验证端口映射
打开浏览器,输入服务器IP地址和随机分配的端口:
4.停止容器
docker stop mysite
任务二:创建自定义桥接网络
Docker默认为每个容器提供网络隔离,但有时我们需要容器之间能够相互通信。自定义网络允许我们控制容器之间的网络连接。
1.准备镜像
docker pull alpine
2.创建自定义桥接网络
docker network create --driver bridge alpine-web
这个命令创建了一个名为
alpine-web
的桥接网络。
3.查看创建结果
docker network ls
可以看到,除了Docker默认的网络外,我们的alpine-web
网络已经创建成功。
4.查看网络的详细信息
docker network inspect alpine-web
输出结果:
[
{
"Name": "alpine-web",
"Id": "3323f21068548656f75acfb8f03d6dc9253b1029b1622e8a9cd04388ace6eaf1",
"Created": "2025-03-14T21:53:20.254563882+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
注意Containers
字段为空,表示当前没有容器连接到这个网络。
5.运行4个测试容器
我们将创建四个容器,并将它们连接到不同的网络,以测试网络连接性:
# alpine1 和 alpine2 连接到 alpine-net
docker run -dit --network alpine-web --name alpine1 alpine ash
docker run -dit --network alpine-web --name alpine2 alpine ash
# alpine3 连接到 bridge
docker run -dit --network bridge --name alpine3 alpine ash
# alpine4 容器同时连接到 bridge 和 alpine-web
docker run -dit --network alpine-web --name alpine4 alpine ash
docker network connect bridge alpine4
-d
:后台运行容器-it
:交互式运行--network
:指定容器连接的网络ash
:在容器中运行的命令(Alpine的shell)
验证容器状态:
docker ps -a
所有容器应该都处于"Up"状态。如果有异常状态的容器,可以删除后重新创建。
6.查看网络详细信息
查看alpine-web
网络:
docker network inspect alpine-web
可以看到,alpine-web
网络中连接了三个容器:alpine1、alpine2和alpine4。
查看默认bridge
网络:
docker network inspect bridge
bridge
网络中连接了两个容器:alpine3和alpine4。
**7.验证容器之间的网络互通性:通过容器名
Docker的自定义网络提供了DNS解析功能,允许容器通过名称相互访问。我们来测试这一功能:
进入alpine1容器:
docker exec -it alpine1 ash
在容器内尝试ping其他容器:
ping alpine2
ping alpine3
ping alpine4
可以看到,alpine1可以通过容器名成功访问alpine2和alpine4,这是因为它们都连接到了同一个自定义网络alpine-web
。
退出容器:
exit
8.验证容器之间的网络互通性:通过IP地址
进入 alpine2 容器:
docker exec -it alpine2 ash
通过 IP 地址 ping 容器 alpine1:
ping -c 3 172.18.0.5 # 请使用你环境中alpine1的实际IP
可以看到,连接到同一网络的容器可以通过IP地址相互访问。
作业
- 验证alpine3和alpine4、alpine1、alpine2的互通性(分别通过容器名和IP地址)
- 验证alpine4和alpine1、alpine2的互通性(分别通过容器名和IP地址)
- 连接到不同桥接网络的容器是不能通过容器名互通的,但可能通过IP地址互通
- 连接到多个桥接网络的容器,可以和这些网络的所有容器通信(至少通过IP地址)