CentOS7使用docker 启动容器后 , 宿主机连接访问不到容器的端口

本文详细介绍了CentOS7下Docker容器网络配置的问题,包括docker0网桥、容器IP、路由检查等。当宿主机无法访问容器端口时,通过检查网络配置、修改docker0默认网段以及使用--net=host模式解决问题。同时提供了两种解决方案,一种是手动调整网络设置,另一种是利用--net=host启动容器,使其直接使用宿主机IP。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CentOS7使用docker 启动容器后 , 宿主机连接访问不到容器的端口

注意第一种方法是在网上找的 , 我并没有执行成功 , 但是他分析的很不错,
可以参考第二种方法

首先需要明确docker的网桥模式,网桥工作在二层(OSI堆栈),是通用网络设备的一种,可以设置IP地址。有了IP地址,Linux便可通过路由表或IP表,在网络层定位网桥,这就相当于有了一个虚拟网卡,即docker0。docker0默认的地址划分:IP(172.17.0.1/16),在启动容器时,docker会在宿主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备,容器启动时,Docker引擎将veth pair设备的一端放在新创建的容器中,并命名为eth0。另一端放在宿主机中,以veth***这样类似的名字命名,并将这个网络设备加入到docker0网桥中,可以通过brctl show命令查看,从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。

方法一:

1. 首先检查宿主机的网络配置

需要先安装网桥管理工具包

yum install bridge-utils -y

1)检查网桥brctl show

[root@localhost ~]# brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.000000000000       no
2) 检查ip 
[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:85:de:4a brd ff:ff:ff:ff:ff:ff
    inet 192.168.137.130/24 brd 192.168.137.255 scope global dynamic eno16777736
       valid_lft 1627sec preferred_lft 1627sec
    inet6 fe80::20c:29ff:fe85:de4a/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
    link/ether 02:42:32:06:66:2d brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:32ff:fe06:662d/64 scope link
       valid_lft forever preferred_lft forever

可以看到docker创建的虚拟网卡docker0的网段为172.17.0.1/16

3)查看路由: ip route

[root@localhost ~]# ip route
default via 192.168.137.2 dev eno16777736  proto static  metric 100
172.17.0.0/16 dev docker0  proto kernel  scope link  src 172.17.0.1
192.168.137.0/24 dev eno16777736  proto kernel  scope link  src 192.168.137.130  metric 100

即172.17.0.0/16网段的包均通过docker0网桥来转发.

  1. 再来查看容器的ip: docker exec -it <容器名称> ip a
[root@localhost ~]# docker exec -it mn  ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN   
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00  
    inet 127.0.0.1/8 scope host lo  
       valid_lft forever preferred_lft forever  
129: eth0@if130: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP   
    link/ether 02:42:ac:11:0a:02 brd ff:ff:ff:ff:ff:ff  
    inet 172.17.0.0/16 brd 172.17.10.255 scope global eth0  
       valid_lft forever preferred_lft forever  

可以看到虚拟网卡eth0的ip为172.17.0.0

  1. 查看容器内的路由: docker exec -it c_name ip route
[root@localhost ~]# docker exec -it mn ip route
default via 172.17.10.1 dev eth0   
172.17.0.0/16 dev eth0 scope link  src 172.17.0.1

由此可知172.17.0.0网段的包均走容器内的eth0,默认网关为172.17.10.1

  1. 如果容器中无法ping通外网,首先查看能否ping通网关。如果网关都无法ping通,说明网桥或网段有问题。这里就可以用tcpdump来查看。比如监控上面第一步的网桥接口tcpdump -i vethaef304e -nn,正常的网络包应答如下:bash-4.4# ping -c 1 8.8.8.8
[root@localhost ~]#  tcpdump -i vethaef304e -nn 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode  
listening on vethaef304e, link-type EN10MB (Ethernet), capture size 262144 bytes  
17:17:16.282976 IP 172.17.10.2 > 8.8.8.8: ICMP echo request, id 2304, seq 0, length 64  
17:17:16.325812 IP 8.8.8.8 > 172.17.10.2: ICMP echo reply, id 2304, seq 0, length 64  
17:17:21.297595 ARP, Request who-has 172.17.10.1 tell 172.17.10.2, length 28  
17:17:21.297656 ARP, Reply 172.17.10.1 is-at f2:29:f4:5b:3d:f2, length 28  

异常时就只有request who-has包,没有reply

  1. 问题解决

查看网桥,路由和ip均没发现问题,试试修改docker0的默认网段,居然成功了,步骤如下:

1) 删除原有配置

service docker stop  
ip link set dev docker0 down  
brctl delbr docker0  
iptables -t nat -F POSTROUTING  
  1. 创建新的网桥
brctl addbr docker0  
ip addr add 172.17.10.1/24 dev docker0  
ip link set dev docker0 up  
  1. 修改docker配置,在/etc/docker/daemon.json中追加bip如下,注意json的格式,bip前面需要有,root@XXXXXX~# cat /etc/docker/daemon.json
vim /etc/docker/daemon.json
{
  "insecure-registries":["x.x.x"],
  "bip": "172.17.10.1/24"
}  

4)重启docker: systemctl restart docker

[root@localhost ~]# systemctl  restart  docker

方法二:

docker容器自动分配的ip为172.17.0.0/24网段的ip,开发用的物理机和这个容器不在一个网段,根本没法访问到,这时候网上查到docker有一种网络模式是–net=host,就是让容器直接使用宿主服务器的ip,这样开发用的物理机就能够访问这个容器的接口了

在执行启动命令的时候 , 加一个属性 --net=host

docker run --name mn -p 80:80 -d --net=host nginx

<think>嗯,用户启动Docker容器访问不到页面,这个问题可能有多种原因。首先,我需要回忆一下Docker网络相关的基础知识。当容器运行时,如果服务绑定在容器内部的localhost(127.0.0.1),那么外部是无法访问的,因为localhost指的是容器本身,而不是宿主机的网络。这时候需要确认应用是否绑定到了0.0.0.0,这样服务才能监听所有接口,允许外部连接。 接下来,端口映射是否正确也是个关键点。用户可能在运行容器使用了-p参数,但有没有正确指定宿主端口容器端口呢?例如,-p 8080:80是将宿主机的8080端口映射到容器的80端口。如果这里配置错误,比如宿主端口写错或者容器端口不对,自然无法访问。 然后,防火墙或安全组的问题也不能忽视。即使Docker正确映射了端口宿主机的防火墙设置可能会阻止外部访问。需要检查iptables、ufw或者云服务提供商的安全组规则,确保相应端口是开放的。 另外,容器内部的应用是否真的在运行呢?有时候容器虽然启动了,但应用可能因为配置错误、依赖缺失等问题而崩溃。这时候可以docker logs查看容器的日志,确认应用是否正常启动,有没有报错信息。 还有Docker的网络模式。如果容器使用了host网络模式,端口可能会直接绑定到宿主机,但其他模式如bridge可能需要正确的端口映射。另外,多个容器之间的网络信是否受阻,比如是否在同一个自定义网络中,或者是否有网络策略限制。 用户的浏览器缓存或者本地DNS问题也可能导致无法访问,尝试使用curl或者wget测试,排除浏览器的问题。同时,检查宿主机能否访问容器端口,比如在宿主机上执行curl localhost:宿主机端口,看看是否有响应。 最后,如果以上都确认无误,可能需要更深入的排查,比如Docker守护进程的状态,或者宿主机的网络配置是否存在异常。这时候可能需要查看Docker的详细日志或者系统的网络状态来进一步诊断。</think>当Docker容器启动无法访问页面时,可能涉及以下原因及排查步骤: --- ### 一、基础原因排查 #### 1. **应用未监听0.0.0.0** - **现象**:容器内应用仅绑定到`127.0.0.1`(本地回环地址)。 - **验证方法**:进入容器检查应用监听地址: ```bash docker exec -it 容器名 bash netstat -tuln | grep 端口号 ``` - **解决**:修改应用配置,使其绑定到`0.0.0.0`。 #### 2. **端口映射错误** - **现象**:宿主机端口未正确映射到容器端口。 - **验证方法**:检查容器端口映射: ```bash docker ps --format "table {{.Names}}\t{{.Ports}}" ``` - **解决**:启动容器时确保使用`-p 宿主机端口:容器端口`,例如: ```bash docker run -d -p 8080:80 nginx ``` #### 3. **防火墙或安全组拦截** - **现象**:宿主机防火墙或云服务器安全组阻止访问。 - **验证方法**: - 本地测试:`curl localhost:宿主机端口` - 外部测试:从另一台机器访问`宿主IP:端口` - **解决**: - 关闭防火墙(临时):`systemctl stop firewalld`(CentOS)或 `ufw disable`(Ubuntu)。 - 云服务器需配置安全组放行端口。 --- ### 二、进阶排查 #### 1. **容器内应用未正常运行** - **验证方法**:查看容器日志: ```bash docker logs 容器名 ``` - **解决**:根据日志修复应用配置或依赖问题。 #### 2. **Docker网络模式问题** - **现象**:使用`--network=host`时端口冲突,或自定义网络配置错误。 - **验证方法**:检查容器网络模式: ```bash docker inspect 容器名 | grep NetworkMode ``` - **解决**:改用默认的`bridge`模式,或确保自定义网络配置正确。 #### 3. **多容器信问题** - **现象**:容器过服务名无法访问(例如Docker Compose环境)。 - **解决**: - 确保容器在同一自定义网络中。 - 使用Docker Compose时,服务名自动解析为容器IP。 --- ### 三、快速验证流程 1. **宿主机本地访问**: ```bash curl http://localhost:宿主机端口 ``` - 若成功,说明容器端口映射正常。 2. **容器内部访问**: ```bash docker exec -it 容器名 curl http://localhost:容器端口 ``` - 若失败,应用未正常运行或未监听端口。 3. **外部网络访问**: ```bash telnet 宿主IP 宿主机端口 ``` - 若不,检查防火墙或安全组。 --- ### 四、常见案例 #### 案例1:Nginx容器无法访问 - **原因**:Nginx默认监听IPv6地址`[::]:80`,但部分环境不支持。 - **解决**:修改Nginx配置为`listen 0.0.0.0:80;`。 #### 案例2:Spring Boot应用无响应 - **原因**:应用启动参数未指定`--server.address=0.0.0.0`。 - **解决**:启动命令添加: ```bash java -jar app.jar --server.address=0.0.0.0 ``` --- 过上述步骤逐步排查,常可定位问题根源。如果仍无法解决,建议提供`docker run`命令、应用日志及网络配置细节进一步分析。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值