如何通过Python/Node.js脚本检查Docker容器内应用的TCP端口开放状态
容器内应用端口校验实现方案
所有脚本默认在目标Docker容器A内部运行,适配精简容器镜像的零额外依赖场景
通用逻辑流程
- 第一步:读取当前容器系统Hostname,作为校验过程的容器标识输出
- 第二步:对目标TCP端口发起轻量本地连接,判断端口是否处于正常可服务状态
- 第三步:任意端口校验失败时直接返回非0退出码;全部校验通过时返回0退出码,输出明确的测试通过提示
方案1:Bash 脚本实现
适配基础镜像内置bash环境,无需安装任何额外工具:
#!/bin/bash set -euo pipefail # 获取容器Hostname CONTAINER_HOSTNAME=$(hostname) echo "当前校验容器Hostname: $CONTAINER_HOSTNAME" # 待校验端口配置:<端口号>:<对应应用名称> CHECK_TARGETS=( "8080:应用B" "8081:应用C" ) check_all_pass=true for target in "${CHECK_TARGETS[@]}"; do port=${target%%:*} app_name=${target##*:} # 利用bash内置/dev/tcp能力发起连接,2秒超时自动断开 if timeout 2 bash -c "echo > /dev/tcp/127.0.0.1/$port" 2>/dev/null; then echo "✅ $app_name 对应端口 $port 校验通过" else echo "❌ $app_name 对应端口 $port 连接失败,端口未正常开放" check_all_pass=false fi done # 输出最终结果并返回对应退出码 if $check_all_pass; then echo "🎉 所有应用端口校验完成,测试通过" exit 0 else echo "⚠️ 存在端口校验失败项,测试未通过" exit 1 fi
注:
/dev/tcp为bash独有的内置特性,若容器使用ash/dash等精简shell,可将连接检测逻辑替换为nc -z -w2 127.0.0.1 $port实现同等校验。
方案2:Python 脚本实现
适配容器内置Python3运行环境,仅依赖标准库,无需安装第三方包:
#!/usr/bin/env python3 import socket import os import sys # 获取容器Hostname container_hostname = os.uname().nodename print(f"当前校验容器Hostname: {container_hostname}") # 待校验端口配置:(端口号, 对应应用名称) check_targets = [ (8080, "应用B"), (8081, "应用C") ] check_all_pass = True for port, app_name in check_targets: try: # 建立TCP连接,设置2秒超时阈值 with socket.create_connection(("127.0.0.1", port), timeout=2): print(f"✅ {app_name} 对应端口 {port} 校验通过") except (socket.timeout, ConnectionRefusedError, OSError): print(f"❌ {app_name} 对应端口 {port} 连接失败,端口未正常开放") check_all_pass = False # 输出最终结果并返回对应退出码 if check_all_pass: print("🎉 所有应用端口校验完成,测试通过") sys.exit(0) else: print("⚠️ 存在端口校验失败项,测试未通过") sys.exit(1)
注:脚本兼容Python3.6及以上所有版本,无环境兼容问题。
方案3:Node.js 脚本实现
适配容器内置Node.js运行环境,仅依赖Node内置模块,无需安装npm包:
#!/usr/bin/env node import net from 'node:net'; import os from 'node:os'; # 获取容器Hostname const containerHostname = os.hostname(); console.log(`当前校验容器Hostname: ${containerHostname}`); // 待校验端口配置 const checkTargets = [ { port: 8080, appName: '应用B' }, { port: 8081, appName: '应用C' } ]; // 单端口校验逻辑 const checkSinglePort = (port, appName) => { return new Promise((resolve) => { const client = new net.Socket(); // 设置2秒连接超时 const timeoutTimer = setTimeout(() => { client.destroy(); resolve({ success: false, port, appName }); }, 2000); client.connect(port, '127.0.0.1', () => { clearTimeout(timeoutTimer); client.destroy(); resolve({ success: true, port, appName }); }); client.on('error', () => { clearTimeout(timeoutTimer); resolve({ success: false, port, appName }); }); }); }; // 批量执行校验 const runBatchCheck = async () => { const checkResults = await Promise.all( checkTargets.map(target => checkSinglePort(target.port, target.appName)) ); let allPass = true; checkResults.forEach(result => { if (result.success) { console.log(`✅ ${result.appName} 对应端口 ${result.port} 校验通过`); } else { console.log(`❌ ${result.appName} 对应端口 ${result.port} 连接失败,端口未正常开放`); allPass = false; } }); // 输出最终结果并返回对应退出码 if (allPass) { console.log("🎉 所有应用端口校验完成,测试通过"); process.exit(0); } else { console.log("⚠️ 存在端口校验失败项,测试未通过"); process.exit(1); } }; runBatchCheck();
退出码使用说明
- 返回值为0时代表全量校验通过,可直接接入容器健康检查、CI流水线、服务启动探活等流程
- 返回值为1时代表存在校验失败项,可直接触发告警、失败重试、服务重启等后续动作
内容的提问来源于stack exchange,提问作者Coolbreeze
相关产品推荐
相关产品推荐

