#!/bin/bash # Docker容器内RTSP连接测试脚本 set -e # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' print_info() { echo -e "${GREEN}[INFO]${NC} $1" } print_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } # 在Docker容器内测试RTSP连接 test_rtsp_in_docker() { print_info "==========================================" print_info "Docker容器内RTSP连接测试" print_info "==========================================" # 确保容器正在运行 if ! docker ps | grep -q jtjai_media; then print_error "jtjai_media容器未运行,请先启动容器" return 1 fi print_info "容器状态: ✅ 运行中" # 在容器内执行网络诊断 print_info "容器内网络环境:" docker exec jtjai_media bash -c " echo '=== 网络配置 ===' ip addr show | grep inet echo '' echo '=== DNS配置 ===' cat /etc/resolv.conf echo '' echo '=== 路由表 ===' ip route show echo '' " # 测试从容器内访问RTSP URLs print_info "测试容器内RTSP连接..." # 读取配置文件中的RTSP URLs local urls=($(grep -o '"rtsp://[^"]*"' config.json | sed 's/"//g')) for url in "${urls[@]}"; do print_info "测试RTSP URL: $url" # 解析主机和端口 local host=$(echo $url | sed -n 's|rtsp://\([^:]*\):\([0-9]*\)/.*|\1|p') local port=$(echo $url | sed -n 's|rtsp://\([^:]*\):\([0-9]*\)/.*|\2|p') if [[ -n "$host" && -n "$port" ]]; then print_info "目标: $host:$port" # 在容器内测试连接 if docker exec jtjai_media timeout 10 nc -z $host $port 2>/dev/null; then print_info "✅ 容器内端口连接成功" else print_error "❌ 容器内端口连接失败" fi # 测试DNS解析 if docker exec jtjai_media nslookup $host > /dev/null 2>&1; then print_info "✅ 容器内DNS解析成功" else print_error "❌ 容器内DNS解析失败" fi else print_error "无法解析RTSP URL格式: $url" fi echo "" done } # 比较宿主机和容器的网络差异 compare_network() { print_info "==========================================" print_info "宿主机vs容器网络对比" print_info "==========================================" echo "🖥️ 宿主机网络信息:" echo " 外网IP: $(timeout 5 curl -s ifconfig.me || echo '获取失败')" echo " DNS: $(cat /etc/resolv.conf | grep nameserver | head -1 | awk '{print $2}')" echo " 网关: $(ip route | grep default | awk '{print $3}')" echo "" if docker ps | grep -q jtjai_media; then echo "🐳 容器网络信息:" docker exec jtjai_media bash -c " echo ' 容器IP: '$(ip addr show eth0 2>/dev/null | grep 'inet ' | awk '{print $2}' || echo 'host模式') echo ' DNS: '$(cat /etc/resolv.conf | grep nameserver | head -1 | awk '{print $2}') echo ' 网关: '$(ip route | grep default | awk '{print $3}' || echo 'host模式') " 2>/dev/null || echo " 网络模式: host模式" else print_warn "容器未运行,无法获取容器网络信息" fi echo "" } # 提供解决方案建议 provide_solutions() { print_info "==========================================" print_info "常见解决方案" print_info "==========================================" echo "如果遇到连接问题,可以尝试以下方案:" echo "" echo "1. 🌐 使用host网络模式 (推荐)" echo " - 修改docker-compose.yml添加: network_mode: host" echo " - 或使用: docker run --network host" echo "" echo "2. 🔧 调整超时设置" echo " - 增加config.json中的connection_timeout_seconds" echo " - 增加read_timeout_seconds" echo "" echo "3. 🛠️ 检查防火墙设置" echo " - 确保RTSP端口(通常554或自定义端口)未被阻止" echo " - 检查iptables规则" echo "" echo "4. 🌍 DNS配置" echo " - 在docker-compose.yml中添加public DNS:" echo " dns:" echo " - 8.8.8.8" echo " - 114.114.114.114" echo "" echo "5. 📡 网络驱动" echo " - 如果使用bridge网络,考虑切换到host模式" echo " - 或创建自定义网络" echo "" } # 主函数 main() { echo "" print_info "Docker RTSP连接诊断工具" echo "" # 检查Docker是否安装 if ! command -v docker &> /dev/null; then print_error "Docker未安装" exit 1 fi # 比较网络环境 compare_network # 测试容器内连接 test_rtsp_in_docker # 提供解决方案 provide_solutions print_info "诊断完成!" } # 执行主函数 main