docker相关

Edunexus 部署排查手册

整理自一次完整的故障排查实战。当部署后服务起来了但外部访问异常时,按本文档顺序排查。


0. 部署完毕后的健康检查清单

bash 复制代码
# 1) 容器是否都 Up
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"

# 2) 业务端口是否在宿主机 LISTEN
sudo netstat -tlnp | grep -E ':(80|3306|6379|1883|8808|9000|18083) '

# 3) 容器内服务自检
docker exec platform_edunexus sh -c 'wget -qO- --timeout=3 http://127.0.0.1:8808/api/ 2>&1 | head -3' || true
docker exec platform_nginx nginx -t

任何一条不正常 → 进入下面对应章节。


1. 启动报错:Pool overlaps with other one on this address space

含义 :docker-compose 声明的 172.25.0.0/16 子网与宿主已有网络冲突(旧 compose 残留 / VPN / 公司内网)。

排查

bash 复制代码
docker network ls
# 找出实际占用 172.25 段的那个网络
docker network inspect $(docker network ls -q) 2>/dev/null | grep -B5 '172.25' | head -30
ip route | grep 172.25

解决

优先方案:清残留

bash 复制代码
docker-compose -f /edunexus/edunexus_deploy_v1.1/docker-compose.yaml down --remove-orphans
docker network prune -f

然后重跑 bootstrap_edunexus.sh。

真冲突:换子网

编辑 docker-compose.yaml,把 subnet: 172.25.0.0/16 换成 10.88.0.0/16,并把所有 ipv4_address: 172.25.0.x → 10.88.0.x,同时改 nginx.conf / application.yml / DetectSvr/conf.json / StreamSrv/conf.json 里的 172.25.0.*。


2. 启动报错:exec: "/opt/xxx/entrypoint.sh": permission denied

含义 :镜像内的 entrypoint.sh 没有 +x。常见于 EMQX、DetectSvr、StreamSvr。

临时绕过(不重建镜像)

在 docker-compose.yaml 该服务下加一行:

yaml 复制代码
  mqtt:
    entrypoint: ["sh", "/opt/emqx/entrypoint.sh"]

sh xxx.sh 不要求脚本本身 +x。然后:

bash 复制代码
docker-compose down && docker-compose up -d

根本修复(修源码再 build)

  1. 给宿主源文件加 +x:

    bash 复制代码
    chmod 755 avtronsys/Emqx/entrypoint.sh
  2. 在 Dockerfile 的 COPY 之后加:

    dockerfile 复制代码
    RUN chmod +x /opt/emqx/entrypoint.sh
    # 或一次扫一波
    RUN find /opt/avtronsys/StreamSrv -maxdepth 2 -name "*.sh" -exec chmod +x {} \;
  3. docker-compose build mqtt && docker-compose up -d mqtt


3. 端口 LISTEN 但 curl 返回 Connection reset by peer

症状 :netstat 看 docker-proxy 在 LISTEN,但 curl http://127.0.0.1:9000/ 报 Recv failure: 连接被对方重置。

这是 TCP 握手成功后被立刻 RST,不是防火墙(防火墙是 timeout/refuse),原因通常是 nginx 容器侧出问题。

排查 5 步走

bash 复制代码
# 1) 路由是否冲突(最可疑)
ip route
docker network inspect $(docker network ls -q) 2>/dev/null | grep -E 'Subnet|Gateway' | head

# 2) nginx 配置是否有效
docker exec platform_nginx nginx -t

# 3) nginx 实际加载的运行配置里有没有 listen 9000
docker exec platform_nginx nginx -T 2>/dev/null | grep -E "listen 9000|edunexus_backend"

# 4) 容器内真正监听的端口(无 ss/netstat 时用 /proc/net/tcp)
docker exec platform_nginx sh -c "cat /proc/net/tcp | awk 'NR>1 {print \$2}' | cut -d: -f2 | sort -u | while read p; do printf '%d\n' 0x\$p; done | sort -un"

# 5) nginx 错误日志
docker logs platform_nginx --tail 80

常见根因 A:nginx 配置文件被旧版本"粘"住

deploy 脚本如果用的是"目录已存在则跳过"逻辑,换 tar 重部署后老 conf 一直没被覆盖。

判定 :第 3 步 nginx -T 输出里没有 listen 9000 或 edunexus_backend,但宿主机源文件里有。

修复:

bash 复制代码
sudo cp -f /edunexus/edunexus_deploy_v1.1/avtronsys/Nginx/conf/nginx.conf /opt/avtronsys/Nginx/conf/nginx.conf
docker exec platform_nginx nginx -s reload

常见根因 B:nginx 版本不支持配置里的某些指令

判定:nginx -s reload 报 [emerg] "xxx" directive is not allowed here。

实例:

复制代码
[emerg] "keepalive_requests" directive is not allowed here in nginx.conf:4

nginx 1.13.3 不支持 upstream 块的 keepalive_requests / keepalive_timeout(需 1.15.3+)。

修复:要么把 nginx 镜像升到 1.27,要么删掉这些不支持的指令。

bash 复制代码
# 方案 1:临时删
sudo sed -i '/keepalive_requests/d; /keepalive_timeout 75s/d' /opt/avtronsys/Nginx/conf/nginx.conf
docker exec platform_nginx nginx -s reload

# 方案 2:长期升级镜像(修 Dockerfile)
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nginx:1.27-alpine

常见根因 C:前端 dist 目录没复制进容器

判定:

bash 复制代码
docker exec platform_nginx ls /opt/avtronsys/Nginx/frontend/edunexus/dist/ 2>&1
# → No such file or directory

原因同 A,部署脚本的"目录非空就跳过"判断把整个 frontend/ 拷贝直接跳了,新加的 edunexus/dist 一直没补。

修复:

bash 复制代码
sudo mkdir -p /opt/avtronsys/Nginx/frontend/edunexus
sudo cp -r /edunexus/edunexus_deploy_v1.1/avtronsys/Nginx/frontend/edunexus/dist \
           /opt/avtronsys/Nginx/frontend/edunexus/
sudo chmod -R 755 /opt/avtronsys/Nginx/frontend/
# nginx 不需要 reload,静态文件即时生效
curl -I http://127.0.0.1:9000/

4. 容器间网络连通性测试(nginx 容器没 ping/wget/curl)

nginx-slim / nginx:alpine 镜像精简,没 ping/wget/curl。借用别的容器测:

bash 复制代码
# mqtt 容器装了 netcat
docker exec platform_mqtt sh -c "nc -zv 172.25.0.7 8808 && echo OK"
docker exec platform_mqtt sh -c "nc -zv 172.25.0.2 9000"

# 从宿主机直打容器 IP(绕过 docker-proxy + nginx)
curl -sv http://172.25.0.7:8808/api/ 2>&1 | head -10

预期结果:

  • nc 返回 succeeded → 容器间网络通
  • curl 172.25.0.7:8808/api/ 返回 HTTP/1.1 401(无 token 时正常)

5. 防火墙 / 外部访问问题

如果本机 curl 127.0.0.1:9000 通了,但同网段别的机器 curl 192.168.10.x:9000 不通:

bash 复制代码
sudo ufw status
sudo iptables -L INPUT -n | head -20

如果 ufw active,放行:

bash 复制代码
sudo ufw allow 9000/tcp
sudo ufw allow 80/tcp
sudo ufw reload

VMware NAT 场景:如果 VM 用 NAT 模式,要在 VMware 配置里把 host 的对应端口转发到 VM。Bridged 模式则不需要。


6. nginx 日志中频繁 502

典型日志:

复制代码
connect() failed (113: No route to host) while connecting to upstream "http://172.25.0.6:8089/..."
connect() failed (111: Connection refused) while connecting to upstream "http://172.25.0.7:8013/..."

含义 :nginx.conf 里有大量 server 块(8070/8090/8091/...)指向未部署的旧服务(EDU V1 在 172.25.0.6:8089、EDU V2 在 :8013、iclass 在 172.25.0.8/0.11)。

Edunexus 单服务部署只用 :9000,其他端口的 502 可以忽略 或直接从 nginx.conf 删掉那些 server 块减噪。


7. SQL 数据库相关

重新导入 SQL(清空 data 目录)

bash 复制代码
# 完全清空 mysql 数据卷以重新触发 /docker-entrypoint-initdb.d/*.sql
docker-compose down -v        # -v 删命名卷
sudo rm -rf /opt/avtronsys/Mysql/data/*
docker-compose up -d mysql
docker logs platform_mysql -f # 看到 "ready for connections" 即完成首次初始化

验证 edunexus 库已建

bash 复制代码
docker exec platform_mysql mysql -uroot -p'Avt@2024!' -e "SHOW DATABASES; USE edunexus; SHOW TABLES;" 2>&1 | tail -30

8. 一键全清重来(核选项)

部署彻底搞乱,想推倒重来:

bash 复制代码
cd /edunexus/edunexus_deploy_v1.1

# 1) 停掉容器并删掉命名卷
docker-compose down -v
docker network prune -f

# 2) 清掉宿主机映射目录(注意:这会丢 mysql/redis/emqx 数据)
sudo rm -rf /opt/avtronsys/{Nginx,Mysql,Emqx,Redis,Edunexus,DetectSvr,StreamSrv}

# 3) 解压最新 tar 包覆盖项目目录(如果换了新 tar)
cd /edunexus
rm -rf edunexus_deploy_v1.1
tar -xf edunexus_deploy_v1.1.tar
cd edunexus_deploy_v1.1

# 4) 一键重装
sudo bash bootstrap_edunexus.sh

9. 排查常用命令速查

bash 复制代码
# 容器
docker ps -a
docker logs <name> --tail 80 -f
docker exec -it <name> sh
docker inspect <name> | grep -E 'IPAddress|Mounts|Ports' -A2

# 网络
docker network ls
docker network inspect <network>
ip route
sudo netstat -tlnp | grep <port>
ss -lntp | grep <port>

# nginx 专用
docker exec platform_nginx nginx -t            # 校验配置
docker exec platform_nginx nginx -T            # 打印生效配置
docker exec platform_nginx nginx -s reload     # 热加载

# 容器内端口(nginx-alpine 没 ss/netstat 时)
docker exec platform_nginx sh -c "cat /proc/net/tcp | awk 'NR>1 {print \$2}' | cut -d: -f2 | sort -u | while read p; do printf '%d\n' 0x\$p; done | sort -un"

# 跨容器探测(mqtt 容器有 netcat)
docker exec platform_mqtt nc -zv <container_ip> <port>

10. 已知配置不一致(仅参考,不影响 Edunexus 自身)

如果业务确实需要 DetectSvr / StreamSvr 把数据回写到 Edunexus,需要改这些业务配置:

文件 当前值(指向旧 EDU/IClass) 应改为(指向 Edunexus)
avtronsys/DetectSvr/conf.json platformIp/Port 172.25.0.6:8089 172.25.0.7:8808
avtronsys/DetectSvr/conf.json sql.database zypt、zhjs edunexus
avtronsys/StreamSrv/conf.json EDUplatformIp/Port 172.25.0.6:8089 172.25.0.7:8808
avtronsys/StreamSrv/conf.json IClassplatformIp/Port 172.25.0.8:8088 视业务需求决定
avtronsys/StreamSrv/conf.json sql.database zypt edunexus

改完重启对应容器:

bash 复制代码
docker-compose restart detectserver streamserver

附:本次实战的"路径依赖"陷阱

部署脚本最坑的不是语法错误,而是 "幂等"判断写错位置:

bash 复制代码
# 这个判断会让"换了新版本配置但旧目录还存在"的情况下,新配置永远不生效
if [ ! -d /opt/avtronsys/Nginx/conf ] || [ ! -f /opt/avtronsys/Nginx/conf/nginx.conf ]; then
  sudo cp -f new.conf /opt/avtronsys/Nginx/conf/nginx.conf
else
  echo "已存在,跳过"  # ← 灾难的源头
fi

最佳实践 :配置类文件(nginx.conf / application.yml)每次部署强制覆盖 ;只有用户数据(mysql data、redis dump、emqx mnesia)才需要"已存在则保留"。当前 deploy_edunexus.sh 已按此原则修正。

相关推荐
honsor1 分钟前
以太网温湿度传感器|动环监控核心采集设备,协议、组网、Zabbix接入实战
linux·服务器·ubuntu
十碗阳春面5 分钟前
阿里云 Ubuntu 22.04 部署 Flarum 论坛:从空白服务器到中文界面、公网 IP 访问
服务器·ubuntu·阿里云
PellyKoo17 小时前
【Ubuntu】GTX 1080 Ti 显卡占用为0但功率高达60W的排查与解决
linux·运维·ubuntu
wzg20161 天前
ubuntu 离线安装 docker-compose
linux·ubuntu·docker
如若1232 天前
Windows SSH + Headscale/Tailscale 组网及免密登录完整配置教程
运维·windows·ubuntu·ssh·内网穿透
菌菌的快乐生活2 天前
Rufus + Ubuntu 24.04 Server(中山大学镜像)通用安装教程
ubuntu
垆边人似月.2 天前
Ubuntu 配置 Samba 共享文件夹并映射到 Windows 完整指南
linux·windows·ubuntu
用户8351414049493 天前
把日志和寄存器值喂给AI做故障定位,我的实际问法
linux·ubuntu
进击的荆棘3 天前
MySQL——在ubuntu环境下安装MySQL
数据库·mysql·ubuntu
易点云徐源4 天前
HP 暗影精灵 PRO 16 安装双系统后,开机直接进入 Windows,按 F9 才能进入 Ubuntu:GRUB 菜单不显示的处理方法
linux·运维·ubuntu