一、检查端口是否被占用
1.1 查看正在使用中的TCP和UDP端口:
ss -tuln
LISTEN:
表示端口正在监听连接,意味着这些端口已经被系统服务使用。比如,如果你看到 "tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN",这意味着8080端口被一个服务监听,并等待连接。
判断端口是否被占用:
- 如果你想知道8080端口是否被占用,你应该查找是否有行显示为
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN
或者tcp6 0 0 :::8080 :::* LISTEN
,这分别表示TCP IPv4或IPv6的8080端口正处于监听状态,即被某个服务占用。 - 如果没有这样的行出现,那么8080端口很可能没有被任何服务监听,也就是空闲的。
假设您决定使用端口
8080
(仅作为示例,实际需确认未被使用):检查端口是否可用:再次使用
ss -tuln | grep :8080
确认8080端口未被监听。如果运行这条命令没有任何输出,表示端口当前并没有被任何服务监听,因此它是可用的。
1.1 首先,进入您的Docker容器:
docker exec -it <container_name_or_id> /bin/bash
1.2 在容器内部,使用netstat
或lsof
检查端口是否被占用:
使用netstat
(如果容器内部有netstat
):
netstat -tuln | grep <port_number>
或者使用lsof(如果容器内部有lsof):
lsof -i :<port_number>
如果这些命令返回结果,则表示指定的端口已被占用。
二、实现端口映射
2.1 创建自定义网络
首先,创建一个自定义的Docker网络,这样可以更好地控制容器间的通信以及容器与外部网络的交互。自定义网络允许你为容器分配固定的IP地址。
docker network create --subnet=172.18.0.0/16 mynetwork
这个命令创建了一个名为mynetwork
的网络,使用了172.18.0.0/16作为子网。
2.2 启动容器并配置IP
接下来,分别启动两个容器,并在启动时加入刚刚创建的网络,并为每个容器指定一个静态IP地址。
启动容器1
docker run -d --name container1 --network=mynetwork --ip=172.18.0.2 -p 192.168.0.60:8081:80 your_image1
这里,-d
表示后台运行,--name container1
为容器命名,--network=mynetwork
指定容器加入自定义网络,--ip=172.18.0.2
为容器分配静态IP地址,-p 192.168.0.60:8081:80
表示宿主机的8081端口映射到容器的80端口,以允许外部访问。
启动容器2
docker run -d --name container2 --network=mynetwork --ip=172.18.0.3 -p 192.168.0.60:8082:80 your_image2
与容器1相似,只是分配了不同的静态IP(172.18.0.3)和宿主机端口映射(8082)。
2.3 验证和外部通信
- 验证容器IP: 可以通过
docker inspect --format '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container1
和相应的命令来检查容器的IP地址是否正确配置。 - 外部访问: 外部机(192.168.0.170)现在可以通过宿主机的IP和映射的端口(例如192.168.0.60:8081 和 192.168.0.60:8082)访问这两个容器中的服务。
注意事项:
- 确保宿主机的防火墙规则允许外部访问映射的端口。
- 容器中的应用需要绑定到
0.0.0.0
而非localhost,以确保可以从外部网络访问。 - 自定义网络的子网选择应避免与宿主机的网络冲突。
- 如果宿主机或网络配置有特殊要求,可能需要额外的网络配置或端口转发设置。
以上步骤完成后,你应该能够通过外部机直接与两个具有独立IP地址的Docker容器进行通信。
- 直接使用docker0: 简单快捷,适用于快速测试或对网络配置要求不高的场景。
- 创建自定义网络: 提供了更灵活的网络配置,包括静态IP分配、网络隔离和更直观的容器间通信管理,适合多服务部署、复杂网络架构或需要严格网络控制的场景。
-
自定义网络与外网访问:使用自定义网络(如
--network my-network
)时,容器间可以方便地相互通信,但默认情况下,自定义网络中的容器不直接暴露给外网。若希望外网访问这些容器,仍需通过宿主机端口映射实现。也就是说,即使在自定义网络中,也不必选择host
网络模式来使服务可被外网访问,只要正确配置端口映射即可。
为了使外网能够访问容器内的服务,一般建议使用默认的桥接网络(bridge
,这也是Docker默认的网络模式)或自定义网络,并通过-p
参数明确映射容器端口到宿主机的端口。这样既可以保持容器网络的隔离性,又能实现服务的外网可访问性,而且更加灵活和安全。除非有特殊需求,否则不建议直接使用host
网络模式。