拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Ubuntu 24.04 装好驱动后如何安装 Docker 并映射硬件设备

最近不少人在 Ubuntu 24.04 上部署开发环境时会遇到一个很实际的顺序问题硬件平台装好了驱动比如 170hx 这类嵌入式视觉主机的串口、USB 转串口芯片、调试器或者 GPU 相关驱动接下来想装 Docker 跑服务结果发现 Docker 要么装不上要么装上了容器里却看不到设备、拉镜像卡到怀疑人生。如果你也卡在这个阶段这篇文章适合你。先说结论在 Ubuntu 24.04 上安装 Docker 本身是一件很标准的事情难度不高真正容易踩坑的是“系统已经装好驱动之后”这个状态。驱动会抢占内核模块、修改 udev 规则Docker 则依赖容器运行时与 systemd 服务管理这两套逻辑如果没理顺你会看到各种权限错误、设备不可见和网络超时。读完本文你能掌握四件事在 Ubuntu 24.04 上正确安装 Docker Engine理解驱动与容器运行时的关系学会把串口、调试器等设备映射进容器并验证以及一套常见的排错思路避免反复重装系统。1. 为什么驱动装好后再装 Docker 更容易踩坑很多教程默认你的系统是一台“干净”的 Ubuntu但现实不是这样。尤其是嵌入式、视觉开发和硬件调试相关的机器驱动安装往往是第一步安装 USB 转串口芯片驱动比如 CH340、CP2102、FT232安装调试器驱动比如 ST-Link、J-Link安装视觉模块相关驱动比如摄像头、图像采集卡安装 GPU 驱动比如 NVIDIA 系列用于视觉推理或渲染。这些驱动在系统里做了不少“底层动作”加载内核模块、注册 udev 规则、修改设备节点权限。表面上看它们和 Docker 没有直接关联但 Docker 容器的运行依赖/dev设备节点、/var/run/docker.sock通信套接字、网络命名空间和 cgroup 权限体系。一旦设备的属主、权限和套接字权限不一致就会出现“Docker 装好了但容器跑起来什么都用不了”的尴尬局面。另一个问题是依赖冲突。Ubuntu 24.04 自带的软件源里可能已经有docker.io包它和 Docker 官方源提供的docker-ce包是两套不同的构建体系。如果你在装驱动时已经顺手装了docker.io后续再安装官方 Docker 就会遇到包冲突。很多人在这一步直接卡死。所以这里真正要注意的不是哪条安装命令没用熟而是要先理解驱动负责“让内核认识硬件”Docker 负责“让容器共享内核能力”。前者在后后者在上顺序错了后面全乱。2. Ubuntu 24.04 安装 Docker Engine 的前置准备在输入安装命令之前建议先花两分钟确认系统状态这几个步骤能避免大多数低级问题。2.1 确认系统版本Ubuntu 24.04 是 LTS 版本官方长期支持到 2029 年。先确认你的系统确实是 24.04lsb_release -a cat /etc/os-release如果输出中VERSION_ID24.04就可以继续。如果是从 22.04 升级到 24.04 的系统建议额外留意一下内核版本和系统源是否干净uname -r升级过来的系统有时会残留旧内核模块驱动加载容易出问题。2.2 确认是否已经安装过 Docker这一步非常关键。很多机器里其实已经装过 Docker只是你自己忘了或者驱动安装脚本自动拉取了依赖which docker dpkg -l | grep -i docker如果存在旧版本使用官方脚本安装前先清掉旧包sudo apt remove docker docker-engine docker.io containerd runc需要说明的是/var/lib/docker这个目录下面可能还保留着旧的镜像和数据。如果你确认不需要旧数据可以一并删除如果里面有重要数据建议先备份再操作。2.3 更新软件源与安装依赖更新系统索引并安装后续添加 Docker 官方源所需要的工具sudo apt update sudo apt install -y ca-certificates curl gnupg如果你的服务器访问 Ubuntu 官方源很慢也可以换成国内镜像源。Ubuntu 24.04 的源配置可能同时存在于/etc/apt/sources.list或/etc/apt/sources.list.d/ubuntu.sources具体以你的系统文件为准替换成阿里云、腾讯云等镜像站地址即可。这里多说一句换源不是必须步骤但如果你在执行apt update时经常超时优先检查网络环境和源配置而不是直接盲目重装。3. 使用官方 apt 仓库安装 Docker Engine在 Ubuntu 上安装 Docker我推荐使用 Docker 官方 apt 仓库而不是直接执行apt install docker.io。原因是官方仓库更新及时并且会附带containerd、buildx、compose插件后续做镜像构建和多容器编排时不需要额外折腾。3.1 添加 Docker 官方 GPG 密钥sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod ar /etc/apt/keyrings/docker.gpg这里的作用是把 Docker 官方仓库的 GPG 密钥安装到系统里后续apt校验包时能确保包来自官方。3.2 添加 Docker 软件源echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release echo $VERSION_CODENAME) stable | \ sudo tee /etc/apt/sources.list.d/docker.list /dev/null执行完成后建议检查一下写入的源文件内容确认源地址和系统版本代号正确cat /etc/apt/sources.list.d/docker.list3.3 安装 Docker 核心组件sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin安装完成后启动 Docker 并设置开机自启sudo systemctl enable --now docker sudo systemctl status docker如果看到active (running)说明服务已经正常运行。3.4 验证 Docker 安装docker --version docker compose version docker infodocker info会输出大量系统信息包括 Docker 根目录、存储驱动、镜像加速配置等。重点看Server Version和Storage Driver是否正常。如果Client有输出但Server报错说明 Docker 守护进程没有正常运行优先检查journalctl -u docker日志。3.5 将当前用户加入 docker 组每次执行 docker 命令都加sudo很繁琐。更常见的做法是把用户加入docker组sudo usermod -aG docker $USER执行后必须重新登录或重启机器组权限才会生效。这里提醒一句加入docker组等价于授予了用户接近 root 的权限生产环境要谨慎使用。如果是多用户共用的服务器建议使用专门的运维账号而不是给所有人开通。3.6 配置镜像加速器如果你发现拉取镜像很慢或者总是超时可以在/etc/docker/daemon.json中配置镜像加速。你所在的云服务商控制台一般会提供一个专属加速地址请填写你自己的地址不要照抄网络上的公共地址{ registry-mirrors: [https://your-mirror-id.mirror.example.com] }修改完成后重启 Dockersudo systemctl daemon-reload sudo systemctl restart docker然后可以通过docker info确认镜像加速是否生效。到这里Docker 本身已经安装完成。4. 驱动与容器运行时的关系设备映射与 GPU 加速前面说过驱动装好之后真正要处理的问题是“如何让容器使用宿主机已识别的硬件”。这个概念如果不理解后面的所有操作都会很拧巴。4.1 容器共享内核但不共享设备列表Docker 容器和宿主机共享同一个 Linux 内核也就是说驱动只要在宿主机上加载了容器理论上就能使用对应的硬件能力。但容器看不见所有设备节点。默认情况下容器有自己的/dev文件系统宿主机上的/dev/ttyUSB0、/dev/video0等设备不会自动出现在容器里。要想让容器访问某个设备需要在启动容器时显式映射设备docker run --device /dev/ttyUSB0:/dev/ttyUSB0把宿主机的设备节点映射进容器后容器进程访问这个节点就相当于直接访问物理设备。4.2 驱动安装会影响设备节点权限你在 170hx 这类平台上安装的串口芯片驱动、调试器驱动通常不只是让内核识别设备还会创建/dev/ttyUSB0、/dev/stlink等节点并设置属主和权限。如果你的驱动安装脚本修改了 udev 规则设备节点可能只对特定用户或 USB 插拔时的默认属主可见。这种情况下即使你把设备映射进容器容器内的用户也可能没有权限打开它。解决方案有两种在启动容器时使用--user指定容器内用户并确保该用户在容器内有设备读写权限在宿主机上调整 udev 规则允许特定组访问设备节点。这里更推荐后者因为容器内的用户体系是隔离的靠容器内调整权限比较别扭。4.3 GPU 与视觉平台的特殊情况如果你的视觉平台需要 GPU 直通仅仅映射/dev/nvidia0是不够的。NVIDIA 的容器方案需要额外安装nvidia-container-toolkit让 Docker 在启动容器时自动注入 GPU 设备、驱动库和运行时工具。大致步骤是# 安装 nvidia-container-toolkit具体安装方式以官方为准 sudo apt install -y nvidia-container-toolkit # 重启 Docker 使配置生效 sudo systemctl restart docker # 启动容器时添加 --gpus 参数 docker run --rm --gpus all your-image nvidia-smi如果你没有接触过 GPU 容器不要着急这个属于进阶内容。先跑通基础设备映射再逐步加 GPU 能力会更稳。对于嵌入式视觉平台串口、摄像头、USB 调试器的设备映射反而是更常见、更优先的需求。5. 完整示例在 Ubuntu 24.04 中用 Docker 运行带 USB 串口设备的容器为了让你看到一个完整闭环我用一个最小示例演示在容器里运行一个 Python 程序读取宿主机上的 USB 转串口设备并打印设备基本信息。5.1 项目文件结构先创建一个工作目录并准备以下文件serial-demo/ ├── Dockerfile ├── serial_test.py └── requirements.txt5.2 Python 串口检测脚本文件路径serial_demo/serial_test.py#!/usr/bin/env python3 import serial.tools.list_ports ports serial.tools.list_ports.comports() if not ports: print(NO_SERIAL_PORTS_FOUND) raise SystemExit(1) for port in ports: print(DEVICE: {} - {}.format(port.device, port.description))这个脚本的作用不是复杂收发而是检查容器里能否枚举到串口设备。如果容器里看不到设备程序会直接提示NO_SERIAL_PORTS_FOUND非常容易定位问题。5.3 requirements.txt文件路径serial_demo/requirements.txtpyserial3.55.4 Dockerfile文件路径serial_demo/DockerfileFROM ubuntu:24.04 RUN apt-get update apt-get install -y \ python3 \ python3-pip \ rm -rf /var/lib/apt/lists/* WORKDIR /app COPY requirements.txt . RUN pip3 install --no-cache-dir -r requirements.txt COPY serial_test.py . CMD [python3, /app/serial_test.py]这里有一点需要说明容器内不需要重新安装串口芯片驱动。驱动已经加载在宿主机内核里容器只是通过设备节点访问硬件。所以 Dockerfile 中只安装 Python 和 pyserial不需要处理内核模块。5.5 构建镜像在serial_demo目录下执行cd serial_demo docker build -t serial-demo .构建完成后可以用docker images确认镜像存在。5.6 确认宿主机上的串口设备节点容器启动前先在宿主机上确认设备已经识别到lsusb ls -l /dev/ttyUSB* /dev/ttyACM*一般 USB 转串口设备会显示为/dev/ttyUSB0或者/dev/ttyACM0。如果你的设备是 ST-Link、J-Link 调试器设备名可能是/dev/stlink或/dev/ttyACM0以实际输出为准。如果宿主机都看不到设备先不要启动容器优先排查驱动。5.7 启动容器并映射设备假设宿主机上的串口设备是/dev/ttyUSB0docker run --rm --device /dev/ttyUSB0:/dev/ttyUSB0 serial-demo正常情况下会输出类似DEVICE: /dev/ttyUSB0 - USB Serial这个输出说明容器内部已经可以访问宿主机上的串口设备。6. 运行结果与验证方法设备映射类的容器问题验证思路比代码本身更重要。建议按下面顺序逐层确认。6.1 验证容器内设备节点如果程序没有输出可以先用交互模式进入容器手动查看设备节点docker run -it --rm --device /dev/ttyUSB0:/dev/ttyUSB0 serial-demo /bin/bash ls -l /dev/ttyUSB0如果ls能看到设备说明映射成功如果看不到说明--device参数没有生效。6.2 验证设备可读写除了能看到设备还要确认容器内用户有权限访问docker run -it --rm --device /dev/ttyUSB0:/dev/ttyUSB0 serial-demo /bin/bash cat /dev/ttyUSB0正常情况不会报Permission denied。如果报错说明设备节点权限有问题返回宿主机检查 udev 规则。6.3 查看容器配置可以用docker inspect查看设备的 cgroup 权限配置docker ps docker inspect container_id | grep -A10 Cgroup这里能看到容器允许访问的设备列表快速确认设备映射是否真的写入了容器配置。6.4 查看宿主内核日志如果设备映射没问题但数据异常可以回到宿主机查看内核日志dmesg | tail -50 journalctl -k --since 5 minutes ago优先看 USB 设备枚举、tty 注册、驱动报错等信息。7. 常见问题与排查思路下面这些问题是 Ubuntu 24.04 上“先装驱动、后装 Docker”最常见的坑建议收藏备用。问题现象可能原因排查方式解决方案docker: permission denied当前用户不在 docker 组执行groups $USER加入 docker 组重新登录无法连接/var/run/docker.sockDocker 守护进程未启动systemctl status docker启动并设置开机自启拉取镜像慢或超时未配置镜像加速或网络不稳定docker info查看 Registry Mirrors配置云服务商提供的加速地址容器内看不到/dev/ttyUSB0启动容器时未映射设备查看docker inspect的设备列表添加--device参数容器内能看到设备但打不开设备节点权限不足在容器内执行ls -l /dev/ttyUSB0调整宿主机 udev 规则或映射用户权限摄像头/dev/video0不可用未映射摄像头设备或驱动未加载宿主机检查ls /dev/video*添加--device /dev/video0NVIDIA GPU 在容器内不可见未安装 nvidia-container-toolkit在容器内运行nvidia-smi安装 toolkit 并添加--gpus参数Docker 服务启动失败与已有系统包冲突或内核模块问题journalctl -u docker清理旧包、检查内核模块升级内核后驱动丢失驱动依赖的内核模块未自动重建dkms status重新构建 DKMS 模块排查时有一个基本原则先确认宿主机设备正常再检查 Docker 配置最后才查容器内环境。很多人一看到容器里没设备就以为要在容器里重装驱动这是一个很大的误解。8. 最佳实践与工程建议8.1 设备映射最小化在启动容器时只映射你真正需要的设备不要图省事直接加--privileged。--privileged会让容器拥有宿主机几乎所有内核权限一旦容器被攻破风险非常大。正确写法是docker run --device /dev/ttyUSB0:/dev/ttyUSB0 --device /dev/video0:/dev/video0 your-image这种写法每个设备都明确映射方便审计也便于排错。8.2 用 Docker Compose 管理复杂设备配置如果设备数量多命令行的--device会变得很长建议使用 Docker Compose。下面是一个docker-compose.yml示例services: vision-app: image: serial-demo devices: - /dev/ttyUSB0:/dev/ttyUSB0 - /dev/video0:/dev/video0 environment: - PYTHONUNBUFFERED1 restart: unless-stopped启动方式docker compose up -d docker compose logs -f用 Compose 管理设备映射、环境变量和重启策略比手敲长命令更稳也更适合团队协作。8.3 不要随意挂载 Docker 套接字不建议为了在容器内管理 Docker就轻易把/var/run/docker.sock挂载进普通业务容器。这会赋予容器操作宿主机 Docker 的能力安全边界被打破。如果你确实需要类似能力优先考虑专门的运维容器和最小权限方案。8.4 慎用 latest 标签无论是基础镜像还是业务镜像尽量使用明确版本标签不要随手写latest。同一个latest在不同时间拉取可能得到完全不同的镜像内容导致环境不可复现。更推荐使用带哈希的镜像摘要或者具体版本号这样升级时可控。8.5 定期清理无用镜像与日志嵌入式开发机磁盘通常比较紧张。构建镜像时容易产生大量悬空镜像可以定期清理docker system df docker system prune -f容器日志默认会不断增长建议在/etc/docker/daemon.json中配置日志轮转{ log-driver: json-file, log-opts: { max-size: 10m, max-file: 3 } }这能避免日志写满磁盘。8.6 驱动与内核升级的节奏如果你经常升级内核建议把涉及内核模块的驱动如 GPU、一些 USB 芯片驱动用 DKMS 管理。否则内核升级后驱动模块可能没有自动重建容器里的设备映射会全部失效。升完内核后先确认dkms status正常再重启系统。9. 结语与后续方向如果你的 170hx 平台刚装好驱动现在想做容器化开发第一步不要急着去拉 MySQL、Redis、Nginx 这些镜像而是先跑通一个最小的设备映射示例。把/dev/ttyUSB0、摄像头、GPU 这些硬件资源从宿主机“传”进容器后面部署任何服务都会顺畅很多。Docker 安装只是起点。对于 24.04 刚上手的开发者下一步可以重点学习三块内容Docker Compose 多服务编排、镜像构建优化、以及容器日志和资源限制。等到你需要在多台机器上部署同样环境时再接触镜像仓库和编排平台会更有针对性。这篇文章里的命令建议收藏备用。尤其是第 7 章的排查表格遇到设备映射问题先对照检查能省掉大量“重装系统”的时间。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门