勘察日期:2026-09-08
目标主机:192.168.31.130(Jetson Orin Nano 实训台,主机名 ld-desktop)
勘察方式:SSH 只读远程采集,未做任何改动
文档位置:/Users/ido/ido2026/101.Business/Dev/python/VisualTechLab/一、硬件环境
| 项目 | 详情 |
|---|---|
| **设备型号** | NVIDIA Jetson Orin Nano 超级版开发套件(Engineering Reference Developer Kit Super) |
| 架构 | aarch64 / ARM64(Tegra 嵌入式平台,非普通 x86 PC) |
| CPU | 6 核 ARM Cortex-A78AE,最高 1.73 GHz,最低 115 MHz |
| GPU | 集成 NVIDIA Ampere 架构(Orin nvgpu,1024 CUDA 核心),容器内可见 `GPU 0: Orin` |
| 内存 | 7.4 GiB(8 GB 版本),zram 交换分区 3.7 GiB(6 个 zram 设备,各 635 MB) |
| 存储 | 238.5 GB NVMe SSD,根分区 `/` 为 ext4 共 233 GB,已用 51 GB(23%),剩余 171 GB |
| 网络 | 有线网口 `enP8p1s0`,IP `192.168.31.130/24`;WiFi(wlP1p1s0)、CAN 总线存在但未启用;Docker 网桥 `3.7.33.1/24` |
| 系统温度 | 约 52 ℃,当前 1 分钟负载 0.06(基本空闲) |
| 运行时长 | 已开机约 2 小时 |
外接实训硬件(从软件栈与设备节点推断)
这是一台 AI 机器人视觉实训台,包含以下外接硬件:
| 硬件 | 驱动/软件 | 设备节点/证据 |
|---|---|---|
| 实训箱本体(AI 一体箱) | —— | 箱体尺寸:长 70cm × 宽 55cm × 高 10cm(承载全部外接硬件,统一参数) |
| 奥比中光 Orbbec RGB-D 深度相机 | pyorbbecsdk、OrbbecViewer | `/opt/pyorbbecsdk`、OrbbecSDK 库、容器内 `/dev/dri/renderD128/129` |
| 大恒图像 GigE 工业相机 | Galaxy SDK、gxipy | `/opt/Galaxy_Linux-armhf_*`、`camera.py`(gxipy)、`/opt/device_app/.../train_2dcamera.py` |
| 灵巧手/舵机(串口控制) | UartAssist(pyserial) | `/opt/uhandclient`、`uart_assist.py`(serial.Serial /dev/ttyUSB*) |
| 传送带(PLC 控制) | BeltOperator(PLC 协议) | `/opt/plcclient`、`belt_operator.py`(TCP 连接 PLC) |
| 机械臂(myCobot) | mycobot_stack + StackAlgorithm | `mycobot_stack.py`、`StackAlgorithm.py` |
| Sipeed 语音模块(麦克风阵列) | SipeedMicRecorder | `sipeed_assist.py`(sounddevice 音频采集) |
| 图形化编程 MyBlockly | myblockly AppImage | `/opt/myblockly-arm64-latest.AppImage` |
容器运行时已直通 USB 总线(--device /dev/bus/usb),勘察时可见:
/dev/video0、/dev/video1(2 路摄像头)/dev/ttyACM0(USB 串口,灵巧手/PLC 控制器)/dev/dri/card0/1、renderD128/129(GPU/显示渲染节点)
二、软件环境
2.1 宿主机(ld-desktop)
| 项 | 版本/值 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS(Jammy Jellyfish) |
| 内核 | 5.15.148-tegra(NVIDIA L4T / JetPack 6.x 定制内核) |
| Python | 3.10.12(系统自带) |
| Docker Engine | 29.7.1(Community),API 1.55,OS/Arch linux/arm64 |
| Docker Compose | v5.3.1 |
| Docker 存储驱动 | overlay2,cgroup v2(systemd driver) |
| Docker 数据目录 | `/data/docker`(**占 43 GB**,其中镜像 23 GB) |
| NVIDIA Container Runtime | 已安装(`nvidia` 是默认 runtime 之一),GPU 容器可用 |
| systemd 服务 | `device_app.service`(Flask 门户)—— 勘察时 `inactive`,但门户进程 pid 5048/5050 由 run.sh 直接拉起在运行 |
2.2 宿主机 Python 关键包
Flask 2.2.5
Flask-SocketIO 5.6.1
python-socketio 5.16.3
docker 7.1.0 # 通过 Docker SDK 启停容器
opencv-contrib-python 4.11.0.86
opencv-python 4.11.0.86
torch 2.8.0
torchaudio 2.8.0
torchvision 0.23.0注意:宿主机跑门户和设备演示,不直接跑深度学习推理(推理在容器里)。
2.3 当前运行的实验容器
| 项 | 值 |
|---|---|
| 容器名 | `jovial_brown` |
| 镜像 | `39.101.211.60:5000/ld/jetson-orin-nano-gpu:v1`(23.1 GB) |
| 基础镜像 | `nvcr.io/nvidia/l4t-ml:r36.2.0-py3`(NVIDIA L4T ML) |
| 运行时 | `nvidia`(GPU 直通),特权模式 true |
| 资源限制 | CPU 4 核,内存 6 GB |
| 启动入口 | `/opt/startup.sh` |
| 默认启动命令 | `nvidia-smi`(仅用来保活) |
| 当前实验 | `voicecommand`(语音指令) |
| 当前用户 | `user1` |
容器内环境:
| 项 | 版本 |
|---|---|
| OS | Ubuntu 22.04.5 LTS(中文 locale zh_CN.utf8) |
| Python | 3.10.12 |
| CUDA | 12.2(nvcc V12.2.140) |
| torch | 2.1.0 |
| torchvision | 0.16.0+fbb4cc5 |
| torchaudio | 2.1.0+6ea1133 |
| tensorflow | 2.14.0+nv23.11(NVIDIA 版) |
| onnxruntime-gpu | 1.16.3 |
| onnx | 1.16.0 |
| opencv-contrib-python | 4.11.0.86 |
| numpy | 1.26.0 |
| scipy | 1.15.3 |
| matplotlib | 3.10.9 |
| Flask | 2.2.5 |
| pyserial | 3.5 |
| pyzbar | 0.1.9 |
| pillow | 12.3.0 |
| JupyterLab | 3.6.6(中文语言包 4.5.post3) |
容器内服务端口映射(宿主机→容器):
| 服务 | 宿主机端口 | 容器端口 | URL / 用途 |
|---|---|---|---|
| SSH | 32772 | 22 | root 登录(密码 `123456`) |
| VNC(TigerVNC) | 32773 | 5901 | 远程桌面(密码 `123456`) |
| noVNC(网页桌面) | 32774 | 6901 | `http://192.168.31.130:32774/vnc.html?autoconnect=true&...password=123456` |
| JupyterLab | 32775 | 8888 | `http://192.168.31.130:32775/lab`(无 token,allow-root) |
容器挂载:
| 宿主机路径 | 容器路径 | 用途 |
|---|---|---|
| `/dev/bus/usb` | `/dev/bus/usb` | USB 设备直通(摄像头/串口/语音模块) |
| `/data/docker4bd/private/user1` | `/data/personal` | 用户工作目录(notebook_dir,rw) |
2.4 本地镜像列表
| 仓库 | Tag | Image ID | 大小 | 备注 |
|---|---|---|---|---|
| `39.101.211.60:5000/ld/jetson-orin-nano-gpu` | v1 | 11e6ca36291f | 23.1 GB | **当前在使用** |
| `jetson-orin-nano-gpu` | v1 | 11e6ca36291f | 23.1 GB | 同镜像的本地标签 |
| `jetson-gpu` | novnc | 522f9126d91c | 23 GB | 旧版(5 周前) |
| `jetson-gpu` | vnc | de51e4ff5acb | 20.4 GB | 旧版(5 周前) |
| `nvcr.io/nvidia/l4t-ml` | r36.2.0-py3 | 997c78d663fc | 18.9 GB | NVIDIA 官方基础镜像(2 年前) |
Docker 资源占用:镜像 23.1 GB、容器 61 MB、无命名卷、无 Build Cache。
三、业务架构
3.1 整体架构图
学生浏览器(Chrome)
│ http://192.168.31.130:8080 ← Flask 门户首页 /login
▼
┌────────────────────────────────────────────────────────────┐
│ 宿主机门户:/opt/device_app/web.py (Flask + SocketIO) │
│ 监听 0.0.0.0:8080,root 运行 │
│ 账号:user1 / user2,密码均为 123456(见 config.py) │
│ │
│ 登录后 → 选实验 → 点"启动实验" → SocketIO 异步: │
│ 1) 停掉当前用户正在跑的容器(stop_all_containers) │
│ 2) 拷贝实验模板:/opt/device_data/<实验>/ │
│ → /data/docker4bd/private/<user>/<实验>/ │
│ 3) docker run 新容器: │
│ - nvidia runtime, privileged, --device /dev/bus/usb │
│ - 内存 6G,CPU 4 核 │
│ - 环境变量 EXPERIMENT_LD, USERNAME_LD, VNC_PASSWORD │
│ 4) 返回 noVNC URL + JupyterLab URL 给前端 │
│ │
│ 状态文件:/opt/device_data/<user>_docker.txt(JSON) │
│ 容器编排配置:/opt/device_app/docker_supervise/config/ │
│ default.xml │
└────────────────────────────────────────────────────────────┘
│ 32772~32775 端口转发
▼
┌────────────────────────────────────────────────────────────┐
│ 实验容器(每学生/每实验一个,同时只跑一个) │
│ - 中文桌面(Xtigervnc + noVNC) │
│ - JupyterLab 3.6(/data/personal 为工作目录) │
│ - SSHD(root/123456) │
│ - Python 3.10 + CUDA 12.2 + 全套 AI 库 │
│ - 学生通过浏览器 noVNC 桌面或 JupyterLab 做实验 │
└────────────────────────────────────────────────────────────┘
│ USB/串口/Dri 直通
▼
实训硬件(相机/灵巧手/PLC/传送带/机械臂/语音模块)3.2 宿主机目录结构
/opt/
├── device_app/ 211 MB ← Flask 门户(主程序 web.py,20 KB)
│ ├── web.py Flask 路由与容器编排逻辑
│ ├── config.py 账号、镜像地址、模式(offline/online)
│ ├── run.sh 启动脚本(PYTHONPATH 注入)
│ ├── device_app.service systemd 单元
│ ├── docker_supervise/ Docker SDK 封装(common / sections / config)
│ │ └── config/default.xml 容器创建参数模板(端口、挂载、镜像)
│ ├── projects/ 早期 12 个实验模板(与 device_data 重复)
│ ├── static/ templates/ 门户前端
│ ├── toolsutil.py 工具函数
│ └── desktop.png 桌面快捷方式图标
│
├── device_data/ 203 MB ← 18 个实验模板库(当前版本)
│ ├── <实验目录>/ 每个实验 = PDF + main_ui.py + .ipynb + 辅助模块
│ ├── resource/ 公共资源(images/、json/)
│ └── user1_docker.txt 当前 user1 的容器状态 JSON
│
├── device_demo/ 45 MB ← 设备演示 Web(web.py 44 KB)
│ ├── web.py 直接操控传送带/相机/色块/机械臂/语音训练
│ ├── belt_operator.py PLC 传送带控制
│ ├── camera.py 大恒相机封装(gxipy)
│ ├── color_block.py 色块识别
│ ├── uart_assist.py 串口舵机/灵巧手控制
│ └── ...(train_*.py 训练脚本等)
│
├── pyorbbecsdk/ ← 奥比中光深度相机 SDK(Python 绑定)
├── uhandclient/ ← 灵巧手客户端
├── plcclient/ ← PLC 客户端
├── Galaxy_Linux-*/ ← 大恒工业相机 GigE SDK
├── OrbbecViewer_*/ ← 奥比中光 Viewer 工具
├── yolov/ voice_model/ ← YOLOv、语音模型
├── desktopMonitor/ ← 桌面监控程序
├── installfile/ ← 系统安装文件
├── nvidia/ ← NVIDIA JetPack/L4T 相关
└── myblockly-*.AppImage ← 图形化编程
/data/
├── docker/ 43 GB ← Docker 数据根目录(镜像、容器层)
├── docker4bd/ 764 KB ← 实验工作区(宿主机侧)
│ ├── public/ 公共资源挂载点(空)
│ ├── project/ 项目挂载点(空)
│ └── private/
│ └── user1/
│ └── voicecommand/ ← 语音指令实验(当前运行中,含 PDF + main_ui.py + voice.wav)
└── tee/ ← TEE 安全目录3.3 Flask 门户路由清单(web.py)
| 路由 | 方法 | 功能 |
|---|---|---|
| `/login` | GET | 登录页 |
| `/login_user` | GET/POST | 登录验证(user1/user2,密码 123456) |
| `/` | GET | 主界面(实验列表) |
| `/viewer` | GET | PDF 课件预览 |
| `/pdfjs/<path>` | GET | PDF.js 静态资源 |
| `/start_docker` | POST/GET | **启动实验容器**(核心逻辑) |
| `/stop_docker` | POST/GET | 停止实验容器 |
| `/container_list` | POST/GET | 查询容器列表 |
| `/container_status` | POST/GET | 查询容器运行状态(noVNC/JupyterLab URL) |
| `/image_list` | POST/GET | 查询镜像列表 |
| `/upload_file` | POST | 上传文件到实验目录 |
| `/logout` | GET | 登出 |
| `/start_install` | POST/GET | 安装/拉取镜像(在线模式) |
| `/images/<path>` | GET | 镜像相关静态资源 |
启动参数从 config.py + docker_supervise/config/default.xml 合并而来。
3.4 外呼依赖连通性
| 目标 | 用途 | 勘察时状态 |
|---|---|---|
| `39.101.211.60:5000` | 私有 Harbor 镜像仓库 | ❌ **不可达**(HTTP 000,可能已关机/不在网络) |
| `192.168.31.10` | apiServer + fileServer(教案/文件) | ❌ **不可达** |
当前 config.py 配置 mode_type = "offline",所以外呼失败不影响使用(镜像已本地存在,课件已在 device_data 中)。
四、实验清单:共 18 个实验
每个实验目录位于 /opt/device_data/,结构统一:
<实验名>/
├── <hash>.pdf 实验指导书(PDF,10-20MB)
├── main_ui.py 实验主程序(Tkinter 桌面 UI)
├── *.ipynb Jupyter Notebook(教学讲解)
├── *_assist.py 硬件辅助模块(串口/相机/语音)
├── tool_util.py / tools_util.py 工具函数
├── images/ Log/ 图片素材/日志
└── requriment.txt 依赖声明(拼写错误,原作者笔误)4.1 按主题分类
| 分类 | 目录名 | 中文名 | 体积 |
|---|---|---|---|
| **视觉-AI 人脸** | facedetector | 02人脸检测 | 17 MB |
| facialcontourdetection | 03面部轮廓检测 | 17 MB | |
| facialdepth | 06面部深度检测(深度相机) | 17 MB | |
| **视觉-AI 手部** | handdetector | 01手部检测 | 8.3 MB |
| handrecognition | 13手势识别 | 8.5 MB | |
| fingerguessing | 15猜拳游戏 | 17 MB | |
| doublehandaddition | 14双手加法(手势算数) | 8.2 MB | |
| **视觉-AI 姿态/人体** | posedetector | 04姿态检测 | 17 MB |
| **视觉-AI 工业识别** | workpiecerecognize | 10工件识别 | 5.8 MB |
| intelligentsorting | 11智能分拣(含机械臂) | 1.7 MB | |
| barcoderecognition | 07条形码识别 | 19 MB | |
| qrcoderecognition | 08二维码识别 | 19 MB | |
| carnumberrecognition | 09车牌识别 | 19 MB | |
| **视觉-相机标定** | camerafocallength | 05相机焦距标定 | 17 MB |
| **语音-AI** | voicecommand | 18语音指令控制(灵巧手) | 720 KB |
| speechrecognition | 16语音识别 | 828 KB | |
| voiceenglishtranslation | 17语音英语翻译 | 664 KB | |
| **机器人** | robotstack | 12机器人码垛 | 1.1 MB |
| **公共资源** | resource | images/、json/(被各实验引用) | 13 MB |
共 18 个有效实验 + 1 个公共资源目录,合计 约 203 MB。
4.2 视觉类实验普遍偏大的原因
- 每个都捆绑一份 PDF 实验指导书(8-18 MB)
- 多数含 .ipynb notebook 讲解
- 部分含预训练模型/样例图片(如 facedetector 的 Orbbec SDK 二进制是原作者误放)
4.3 硬件抽象层(HAL)现状
原作者已把硬件调用封装成独立的 Python 类,业务逻辑不直接碰底层——这是后续做模拟(Mock)教学环境的有利条件:
| 硬件 | 封装类 | 主要接口 |
|---|---|---|
| 灵巧手/舵机(串口) | `UartAssist` | `open_serial()`、`control_mult_servo_move(t, angles)`、`control_full_action_stop()`、`reset_hand()`、`close_serial()` |
| 传送带(PLC) | `BeltOperator` | `open_connect()`、`start_run()`、`stop_run()`、`write_speed(v)`、`read_speed()`、`write_direction(d)`、`read_status()` |
| 大恒工业相机 | `Camera(gxipy)` | `open_cam_device()`、`start_acquisition()`、`getImg()`、`close_cam_device()` |
| 深度相机 | `orbbec_camera_*.py` + pyorbbecsdk | 获取 RGB + 深度帧 |
| 语音麦克风 | `SipeedMicRecorder` | `init_device()`、`start_record(fname)`、`stop_record()`、`is_recording()` |
| 机械臂码垛 | `mycobot_stack` + `StackAlgorithm` | 位姿/抓取指令/码垛坐标计算 |
注:uart_assist.py和tools_util.py在多个实验目录下各有一份副本(代码有细微差别),不是单例共享模块。
五、默认账号与密码(⚠️ 教学默认值,勿暴露公网)
| 服务 | 账号 | 密码 |
|---|---|---|
| 门户(web.py:8080) | user1 / user2 | `123456` |
| 容器 SSH(32772) | root | `123456` |
| VNC(5901) | — | `123456` |
| noVNC(6901) | — | `123456` |
| JupyterLab(8888) | (allow-root,无 token) | — |
| Harbor(default.xml) | admin | `LD_harbor_210720`(仓库不可达) |
六、监听端口一览
| 端口 | 进程 | 用途 |
|---|---|---|
| 22 | sshd | 宿主机 SSH |
| 53 | systemd-resolved | 本地 DNS |
| 111 | rpcbind | RPC 端口映射 |
| 631 | cupsd | 打印服务 |
| **8080** | python (web.py) | **Flask 实验门户** |
| 32772 | docker-proxy | 容器 SSH |
| 32773 | docker-proxy | 容器 VNC |
| 32774 | docker-proxy | 容器 noVNC 网页桌面 |
| 32775 | docker-proxy | 容器 JupyterLab |
| 13486 | dockerd | Docker 远程 API(tcp://192.168.31.130:13486,供 docker_supervise 调用) |
七、可行性评估:拉到本地 & 模拟教学环境
7.1 各部分内容的可迁移性
| 内容 | 位置 | 体积 | 能否拉到 Mac/普通 Ubuntu | 能否在非 Jetson 机器上运行 |
|---|---|---|---|---|
| 门户代码 device_app | `/opt/device_app` | 211 MB | ✅ rsync 直接拉 | ✅ 纯 Flask,可直接运行(需改 Docker SDK 调用) |
| 18 个实验课件+代码 | `/opt/device_data` | 203 MB | ✅ rsync 直接拉 | ✅ Notebook/PDF 可阅读;纯 CPU 算法代码可跑;Orbbec/gxipy 等 aarch64 二进制装不上 |
| 设备演示系统 | `/opt/device_demo` | 45 MB | ✅ rsync 直接拉 | ❌ 直接依赖实训台硬件 |
| **Docker 实验镜像** | `/data/docker` | **23.1 GB** | ✅ 可 `docker save` 离线搬运 | ❌ **无法在 Mac/普通 x86 PC 运行**:镜像基于 NVIDIA L4T/Tegra,CUDA 绑定 Jetson GPU;即使是 M 芯片 Mac(同为 arm64)也没有 N 卡,容器内 GPU 推理全废 |
| 学生作业数据 | `/data/docker4bd/private/` | <1 MB | ✅ 直接拉 | — |
7.2 核心结论
1. 纯文档/代码级别复刻(460 MB):rsync 几分钟完成,适合备课、改课件、离线阅读 notebook。
2. 完整 GPU 实验环境:只能在另一台 Jetson 设备(Orin/Xavier/Nano,JetPack 6.x + nvidia-container-toolkit)上还原;Mac/x86 Ubuntu 都跑不了那个 23 GB 镜像。
3. 模拟教学环境(Hardware-in-the-Loop Mock):完全可行,且代码结构支持——只需在硬件抽象层之上加一套 Mock 驱动实现,让学生发"传送带启动/手势张开"等指令时,Mock 返回预设状态和数据。
八、模拟教学环境建设方案(讨论方向)
8.1 为什么可行
原作者已将所有硬件调用封装在独立驱动类(UartAssist、BeltOperator、Camera、SipeedMicRecorder、mycobot_stack)中,业务代码(实验 main_ui.py、notebook、AI 识别)通过这些类的方法签名间接访问硬件。这意味着:
按相同类名、相同方法签名实现一套"假驱动",业务代码一行不改即可在普通 Ubuntu 上运行;由配置开关切换real/mock模式。
8.2 三层模拟深度
| 层级 | 描述 | 教学价值 | 工作量 |
|---|---|---|---|
| **L1 接口级 Mock** | 方法调用返回预设状态/ACK;状态机维护内部变量(speed、direction、servo angles) | 验证指令链路、协议、状态机逻辑 | 小 |
| **L2 数据级回放** | Mock 相机不生成假图,而是**回放现场已录的真实图片/视频/音频**(device_data 内已有 voice.wav、images/ 等素材);识别算法(OpenCV/ONNX/Whisper)跑真模型,输出真结果 | 算法实验可完整运行(人脸/手势/条码/车牌),学生看到真识别框 | 中 |
| **L3 数字孪生可视化** | Web 页面 2D/3D 展示传送带转动、色块移动、机械臂动作、相机视野;与 L1/L2 联动 | 演示效果好,替代 noVNC 桌面的"看设备动"诉求 | 较大 |
8.3 推荐路线
1. 第一步:拉代码 —— rsync 把 /opt/device_app、/opt/device_data、/opt/device_demo(共 ~460 MB)同步到本地 VisualTechLab/ 目录
2. 第二步:单实验打样 —— 建议选 voicecommand(最简单,验证架构)或 intelligentsorting(传送带+相机+机械臂全链路,最能暴露问题)
3. 第三步:抽出 HAL 层 —— 建 hal/real/ 与 hal/mock/ 两套实现,一个全局 SIMULATION_MODE 开关
4. 第四步:逐个实验适配 —— 18 个实验复用同一套 HAL,打样完成后其余实验适配成本快速下降
5. 第五步(可选):数字孪生可视化 + 故障注入(模拟丢包/设备离线/识别失败)
8.4 模拟覆盖度估算
- 可完整模拟(无需硬件):语音类 3 个、视觉识别类 8-10 个(用回数据/预置模型)、条码/二维码/车牌识别 —— 约 13-14 个实验
- 可部分模拟(算法可跑,但硬件交互需简化):双手加法、猜拳、智能分拣、机器人码垛 —— 约 4 个
- 无法纯软件模拟(必须真机):相机焦距标定、深度测量、机械臂碰撞/公差、硬件接线故障排查 —— 约 2-3 个
总体模拟覆盖率约 75-80%,足以支撑课前预习、课下复习、算法反复练习、批量学生无设备自学等场景。
8.5 模拟环境不需要 23GB Jetson 镜像
在普通 Ubuntu(x86_64 或 arm64 Mac)上所需的只是:
- Python 3.10
- CPU 版 torch / onnxruntime / opencv-python / flask / flask-socketio / pyserial / pyzbar / faster-whisper
- 课件代码(~460 MB)
- 预置模型 + 回放素材(按需下载)
总磁盘占用预计 < 3 GB(不含模型)。
九、建议的后续动作(待讨论确认)
- [ ] 用 rsync 把
/opt/device_app、/opt/device_data、/opt/device_demo同步到本地VisualTechLab/remote/ - [ ] 选定第一个 Mock 打样实验(voicecommand 或 intelligentsorting)
- [ ] 在本地
VisualTechLab/simulator/搭建 HAL 框架,接入 Mock 实现 - [ ] 跑通第一个闭环实验后,批量适配其余实验
- [ ] (可选)数字孪生可视化页面
- [ ] (可选)镜像离线备份:
docker save出 23GB 镜像归档存移动硬盘,以防设备故障
附录:勘察时使用的非侵入式命令(仅读)
# 连通性
ping 192.168.31.130
nc -zv 192.168.31.130 22
# 硬件/系统
lscpu; free -h; df -hT; lsblk; ip -brief addr; dmidecode -s system-product-name
# Docker
docker ps -a; docker images; docker volume ls; docker network ls; docker system df;
docker inspect jovial_brown; docker exec jovial_brown bash -c '...'
# 业务目录
ls -la /opt/device_app; ls -la /opt/device_data; ls -la /data/docker4bd;
grep -n "@app.route" /opt/device_app/web.py; ss -tlnp所有采集均通过 SSH 以只读查询为主,未在对端写入或修改任何文件(除之前按你指示配置了 dev 账号的 SSH 公钥与 sudo NOPASSWD)。
十、二次验证补充信息(Workbody P0验证)
以下信息来自 Workbody 自动化探测脚本的二次验证,对首次勘察结果进行补充确认。
10.1 Docker 远程 API 可达性
- Docker daemon 监听
tcp://192.168.31.130:13486(首次勘察已记录) - P0 验证确认:从远端 Python 容器通过 TCP 访问该端口可成功调用 Docker API(list_containers、list_images 等接口均正常返回)
- 这意味着 liveservice 容器有两种方式管理宿主机 Docker:
- 挂载
/var/run/docker.sock(推荐,更安全、不暴露 TCP 端口) - 通过 TCP 连接
192.168.31.130:13486(已验证可行,但需确保端口仅内网访问)
10.2 容器内 Docker sock 访问
- P0 验证确认:容器内挂载
/var/run/docker.sock后,可正常调用 Docker SDK 管理宿主机容器,包括:
- 启动 / 停止实验容器
- 查询容器状态
- 获取容器日志
- 动态端口映射
- 验证方式:在 Python 测试容器内安装 docker 包,挂载 sock 后成功 list / containers / create / start
10.3 离线环境确认
- 服务器无法访问外部网络:
39.101.211.60:5000(私有 Harbor 仓库)不可达;192.168.31.10(教案 / 文件服务器)不可达;公网不通(无 Internet 连接) - 部署影响:不能依赖
docker pull或apt install从外网获取资源,必须采用"本地 build → docker save → scp 传输 → docker load"的离线部署流程 - 好消息:实验镜像
jetson-orin-nano-gpu:v1(23GB)已在本地,PostgreSQL 镜像可以在本地 Mac(arm64)pull 后一起打包传输
10.4 磁盘资源余量确认
- 根分区 233GB,已用 51GB(23%),剩余 171GB 可用
- Docker 数据目录
/data/docker占 43GB(镜像 23GB + 容器层) - 新增 PostgreSQL 数据预计占用 < 1GB;新增 liveservice 镜像预计 < 500MB;学生数据(代码 + 成绩 + 日志)预计一学期 < 5GB
- 磁盘余量充足,无需额外扩容
10.5 Python 与 pip 环境
- 宿主机 Python 3.10.12,pip 可用;但离线环境下 pip install 无法从 PyPI 下载包
- 进一步确认全 Docker 化部署的必要性:所有 Python 依赖打包进 Docker 镜像,不需要在宿主机 pip install
- 本地 Mac(arm64)build 镜像 → 传输到 Jetson → 直接运行,零依赖
10.6 原厂容器参数模板确认
/opt/device_app/docker_supervise/config/default.xml包含完整的容器创建参数:镜像名、runtime、CPU/内存限制、端口映射范围、设备直通、环境变量、工作目录挂载- 该模板可被 liveservice 直接读取或复刻,确保容器启动参数与原厂完全一致
- 原厂容器启动逻辑位于
/opt/device_app/web.py的start_docker路由函数中
10.7 systemd 服务状态补充
device_app.servicesystemd 单元文件存在,但勘察时服务状态为 inactive- 实际的 Flask 门户进程(pid 5048/5050)由
/opt/device_app/run.sh直接拉起,未通过 systemd 管理 - 部署影响:liveservice 部署时需要决定如何处理原厂 web.py 进程(停掉并由 liveservice 替代,或改端口共存)