Ubuntu 24.04 安装 Docker 及驱动设备透传实践指南
发布时间:2026/9/8 4:31:28 作者:尧图编辑部 阅读量:1,286

如果你刚在一台 170hx 平台上装完底层驱动系统里已经躺着一堆 USB 转串口、显卡、网卡的设备节点接下来最想做的事一定是把开发环境理顺。这时候手工去装 Java、MySQL、Redis、Node.js一个个配环境变量、调版本折腾一晚上换台机器又要重来一遍。而 Docker 要解决的正是驱动装好之后应用环境怎么不再污染系统这个下一步问题。本文以 Ubuntu 24.04 装机后的场景为例完整记录从环境检查、源配置、Docker Engine 安装到镜像加速、硬件设备透传、常见踩坑的全过程。读完之后你不仅能在一台刚装好驱动的 170hx 平台上把 Docker 跑起来还能搞清楚容器和底层驱动之间到底该谁管谁。1. 这篇文章真正要解决的问题很多人会有一种错觉驱动装好了系统能识别硬件了开发环境就顺理成章了。但真正把开发工具链铺开的时候你会发现新的麻烦系统是干净的 Ubuntu 24.04默认软件源在国内下载速度很慢。为了跑某个老项目需要装特定版本的 Python、JDK、数据库版本冲突避无可避。驱动在系统层已经加载但如果环境变量、系统库被某个应用的安装过程改坏驱动也会跟着出问题。换一台机器部署同一个项目所有依赖又要重新装一遍而且大概率装出来的结果还不完全一样。这些问题的共同根源在于应用环境直接和操作系统绑定在一起。而 Docker 把应用、依赖、配置、启动命令一起打包成镜像在共享宿主机内核的基础上做进程级隔离正好可以把系统层和应用层分开管理。对于 170hx 这类紧凑型高性能平台尤其明显。硬件资源有限又不能像大服务器那样随便开虚拟机浪费资源底层驱动加载到内核之后要尽量少去改动系统层的库和配置。容器机制天然适合这种场景驱动留在宿主机应用待在容器里两边各司其职。这篇文章不是单纯贴一遍 Docker 官方安装命令而是按照驱动装完之后的真实环境来写。我们会先确认系统与内核状态再选用合适的安装源然后配置国内镜像加速最后把 USB 串口设备、目录挂载这些和驱动相关的细节一起讲清楚。适合刚接触 Docker 的新手也适合已经装上但遇到设备透传问题的读者。2. 核心概念Docker、容器与宿主机驱动的关系理解 Docker 和驱动的关系比记住安装命令更重要。因为很多人在 170hx 这类平台上装完 Docker 后发现容器里看不到硬件设备第一反应就是去容器里装驱动这是一个很典型的误区。Docker 是一个容器运行时它利用 Linux 内核的 namespace 和 cgroup 技术把进程、文件系统、网络、资源限制隔离开来。容器和宿主机共享同一个内核这一点决定了底层驱动的边界驱动是内核模块必须在宿主机内核里加载。容器不能也不需要重新安装底层驱动。容器要访问某个硬件设备需要把宿主机的设备文件“透传”进容器常见方式是用--device参数或-v /dev/ttyUSB0:/dev/ttyUSB0这类挂载方式。也就是说宿主机驱动是否装好直接决定容器能否使用对应硬件。这也就是为什么在 170hx 平台安装驱动之后再安装 Docker反而是一个更符合实际顺序的做法。镜像Image和容器Container也要区分清楚。镜像是一个只读模板包含应用代码、运行环境、依赖库容器是镜像运行时的实例可以启动、停止、删除。你可以把镜像理解为“安装包解压后的系统盘镜像”容器理解为一台正在运行的轻量机器。还有一个常被忽略的概念是 Docker 守护进程dockerd。用户通过docker命令行工具和守护进程通信守护进程负责管理镜像、容器、网络和存储。安装 Docker 时我们需要同时装好客户端和守护进程并确保守护进程开机自启。3. 环境准备与前置检查在 170hx 平台上开始安装前先花三分钟确认环境能避免后面很多莫名其妙的错误。3.1 确认系统版本与内核Ubuntu 24.04 的版本代号是 nobleDocker 官方源对它支持得很好。执行下面命令lsb_release -a uname -r uname -m预期看到类似结果Distributor ID: Ubuntu Description: Ubuntu 24.04 LTS Release: 24.04 Codename: noble 6.8.0-xx-generic x86_64如果你的系统是从 22.04 升级上来的系统里可能残留旧版本 Docker 或旧的 apt 源配置建议走完 3.2 的清理步骤。3.2 清理旧版本 Docker如果之前装过 Docker并且版本很老需要先卸载sudo apt-get remove docker docker-engine docker.io containerd runc sudo apt purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin卸载不会自动删除/var/lib/docker目录这是保存镜像和容器数据的地方。如果你确认不需要旧数据可以手动清理sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerd这一步在新装系统上通常不需要执行环境变量、系统库和驱动的兼容性问题往往比 Docker 安装本身更耗时间。3.3 检查网络与 DNS安装过程需要从软件源下载软件包国内网络环境建议先确认 DNS 解析正常ping -c 3 mirrors.aliyun.com ping -c 3 download.docker.com如果 ping 不通先解决网络问题再继续。DNS 配置在/etc/resolv.conf但如果你用了 systemd-resolved修改前最好了解清楚机制否则重启后会被覆盖。3.4 确认硬件设备状态因为本文背景是“170hx 平台安装驱动之后”建议先确认设备节点是否存在。比如 CH340/CP2102 这类 USB 转串口驱动装好后通常会有ls -l /dev/ttyUSB* ls -l /dev/ttyACM*能看到/dev/ttyUSB0这样的设备节点说明驱动加载成功。这一步记录的信息后面做设备透传时会用到。4. Docker Engine 安装的三种方式Ubuntu 上安装 Docker 主要有三条路线官方 apt 源、国内镜像 apt 源、官方安装脚本。我的建议是能用 apt 源就用 apt 源安装脚本适合快速验证但可控性稍差。4.1 方式一官方 apt 源安装通用推荐先安装依赖工具sudo apt-get update sudo apt-get install -y ca-certificates curl添加 Docker 官方 GPG keysudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod ar /etc/apt/keyrings/docker.asc添加 apt 源echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release echo $VERSION_CODENAME) stable | \ sudo tee /etc/apt/sources.list.d/docker.list /dev/null系统会自动识别 Ubuntu 24.04 的代号 noble。执行安装sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin这里把docker-buildx-plugin和docker-compose-plugin一起装掉后续不管是多阶段构建还是编排多个容器都不用再单独补工具。4.2 方式二阿里云镜像源安装国内更快官方源在部分网络环境下可能连接超时此时可以把源中的域名替换为阿里云镜像。GPG key 的下载也可以替换sudo curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod ar /etc/apt/keyrings/docker.asc添加源echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.asc] https://mirrors.aliyun.com/docker-ce/linux/ubuntu \ $(. /etc/os-release echo $VERSION_CODENAME) stable | \ sudo tee /etc/apt/sources.list.d/docker.list /dev/null然后同样执行apt-get update和安装命令。如果你平时习惯用清华、中科大镜像思路完全一样只改域名即可。4.3 方式三官方安装脚本快速但不透明Docker 官方提供了一键脚本curl -fsSL https://get.docker.com | bash脚本会自动检测系统版本并配置源。问题在于脚本执行过程是黑盒一旦失败不好排查而且默认不帮你处理国内镜像加速。所以它更适合临时验证环境不建议在需要长期维护的 170hx 平台上作为首选方式。安装完成后先确认 Docker 守护进程状态sudo systemctl enable --now docker sudo systemctl status docker能通过systemctl status看到 active (running)说明安装成功。5. 配置镜像加速、开机自启与非 root 用户管理Docker 装好之后第一件事不是急着拉镜像而是把基础体验调好。国内拉取 Docker Hub 镜像慢是新手最容易劝退的坎。5.1 配置 registry mirror 镜像加速Docker 守护进程支持配置镜像加速地址配置文件是/etc/docker/daemon.json。阿里云容器镜像服务会为每个账号分配一个专属加速地址格式通常如下{ registry-mirrors: [https://xxxx.mirror.aliyuncs.com] }实际使用时把xxxx替换成自己账号对应的 ID。如果你没有阿里云账号也可以使用一些公开镜像加速服务但稳定性和速度不如专属地址。配置完成后重启守护进程sudo systemctl daemon-reload sudo systemctl restart docker验证加速是否生效docker info在输出里找到Registry Mirrors一节能看到你配置的地址就说明生效了。5.2 设置开机自启系统重启后 Docker 要能自动拉起sudo systemctl enable docker sudo systemctl is-enabled docker输出enabled表示开机自启已经生效。5.3 当前用户加入 docker 组docker命令默认需要 root 权限。为了避免每条命令都加sudo可以把当前用户加入 docker 组sudo usermod -aG docker $USER newgrp docker执行完重新登录终端再执行docker version如果客户端和守护进程版本都能正常输出说明权限配置完成。注意加入 docker 组等同于获得 root 级别的容器管理权限在多人共用的服务器上要谨慎最好结合 sudo 权限审计一起管理。6. 驱动安装后的 Docker 设备透传实践这是本文和普通 Docker 教程差异最大的地方。170hx 平台在装完驱动后最典型的诉求就是把宿主机已经识别到的设备接入容器让容器里的应用直接操作硬件。6.1 USB 转串口设备透传假设你在宿主机上已经看到/dev/ttyUSB0现在想让容器里的程序能读写这个串口最简单的方式是docker run -it --rm \ --device/dev/ttyUSB0 \ ubuntu:24.04 bash进入容器后检查ls -l /dev/ttyUSB0如果能看到设备节点说明透传成功。但在很多情况下直接映射会遇到权限问题。因为容器内进程的 UID/GID 和宿主机设备文件的权限不一致。更稳妥的方式是把设备文件和权限一起传入docker run -it --rm \ --device/dev/ttyUSB0:/dev/ttyUSB0 \ -v /dev/ttyUSB0:/dev/ttyUSB0 \ ubuntu:24.04 bash注意--device负责创建设备节点-v负责确保设备文件可见二者一起使用是常见的组合方式。如果容器内仍然没有权限可以在宿主机上把当前用户加入dialout组sudo usermod -aG dialout $USER newgrp dialout然后重启 docker 守护进程再启动容器。6.2 串口调试工具容器化示例假设你需要在容器里使用 minicom 或 picocom 调试设备可以写一个简单的 Dockerfile# 文件路径~/serial-debug/Dockerfile FROM ubuntu:24.04 RUN apt-get update apt-get install -y --no-install-recommends \ picocom \ rm -rf /var/lib/apt/lists/* CMD [picocom, /dev/ttyUSB0, -b, 115200]构建并运行cd ~/serial-debug docker build -t serial-debug:latest . docker run -it --rm --device/dev/ttyUSB0 serial-debug:latest这样做的好处是调试工具打包进镜像换一台机器只要驱动识别到/dev/ttyUSB0就能用同一个镜像继续调试不用重新安装工具链。6.3 GPU 等加速设备透传如果 170hx 平台带有 NVIDIA 独立显卡并且宿主机已经安装好 NVIDIA 驱动那么容器内要用 GPU需要额外安装nvidia-container-toolkit。宿主机上执行distribution$(. /etc/os-release;echo $ID$VERSION_ID) curl -s -L https://nvidia.github.io/libnvidia-container/gpgkey | sudo apt-key add - curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | \ sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list sudo apt-get update sudo apt-get install -y nvidia-container-toolkit sudo nvidia-ctk runtime configure --runtimedocker sudo systemctl restart docker然后运行容器时使用--gpus all参数docker run --rm --gpus all nvidia/cuda:12.0-base nvidia-smi如果你的 170hx 平台不是 NVIDIA 显卡而是其他加速芯片思路仍然类似宿主机驱动先行再通过容器运行时把对应设备透传进去。核心原则是不要试图在容器里重新安装底层驱动。7. 完整示例跑通 Nginx 和 MySQL设备透传验证完成后我们再跑一个最常见的场景用 Docker 部署 Nginx 和 MySQL。这个流程可以覆盖拉镜像、端口映射、数据卷、启动管理等最常用的 Docker 操作。7.1 拉取镜像docker pull nginx:stable docker pull mysql:8.0如果你的网络环境还没有配置镜像加速这里会明显变慢甚至报 timeout 错误。这也是第 5 节配置加速的意义所在。7.2 启动 Nginxdocker run -d \ --name web-server \ -p 8080:80 \ -v /home/$USER/nginx/html:/usr/share/nginx/html:ro \ --restart unless-stopped \ nginx:stable参数解释-d后台运行。--name指定容器名方便后续管理。-p 8080:80把宿主机的 8080 端口映射到容器内的 80 端口。-v把宿主机目录挂载到容器内:ro表示只读。--restart unless-stopped容器异常退出时自动重启除非手动停止。验证curl http://localhost:8080能看到 Nginx 默认欢迎页就算成功。7.3 启动 MySQLMySQL 需要数据持久化直接把数据放在容器里容器删除数据就没了这是绝对要避免的docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDyour_password \ -v /home/$USER/mysql-data:/var/lib/mysql \ mysql:8.0注意生产环境不要用这种明文密码方式建议使用--env-file或密钥管理工具。创建环境文件# 文件路径~/mysql-env/mysql.env MYSQL_ROOT_PASSWORDyour_password MYSQL_DATABASEapp_db MYSQL_USERapp_user MYSQL_PASSWORDapp_password然后启动docker run -d \ --name mysql8 \ -p 3306:3306 \ --env-file ~/mysql-env/mysql.env \ -v /home/$USER/mysql-data:/var/lib/mysql \ mysql:8.0用客户端确认连接docker exec -it mysql8 mysql -uroot -p输入密码后能进入 MySQL 命令行说明容器运行正常。7.4 查看容器日志与状态排查问题时最常用的一组命令docker ps -a docker logs -f web-server docker logs --tail 100 mysql8 docker exec -it mysql8 bashdocker logs -f可以实时查看输出docker exec可以进入容器内部检查进程和文件系统。记住这四条命令大部分启动失败问题都能定位到原因。8. 运行结果与效果验证在 170hx 平台上验证 Docker 是否真正可用可以从三个层面进行守护进程、容器运行、设备透传。第一层查看 Docker 版本和基本信息docker version docker infodocker version能同时确认客户端和服务端都正常常见的Cannot connect to the Docker daemon错误在这一步就会暴露。第二层运行一个最小测试容器docker run --rm hello-world--rm参数表示容器退出后自动删除不会留下垃圾文件。如果能输出 Hello from Docker 的欢迎信息说明整个容器生命周期没问题。第三层验证前面配置的镜像加速是否生效docker info | grep -A 2 Registry Mirrors docker pull nginx:stable如果拉取速度能接受说明网络配置成功。如果拉取速度仍然很慢检查 daemon.json 是否放在了正确路径、是否使用了systemctl restart docker重启。如果运行失败第一步不要急着去改代码。先看docker logs再看docker ps -a里的状态最后看/var/log/syslog或journalctl -u docker。从外层到内层逐步定位比盲目搜索错误信息更高效。9. 常见问题与排查思路安装和使用过程中下列问题出现频率最高。问题现象可能原因排查方式解决方案apt 安装时报错无法解析 download.docker.com网络无法访问官方源ping download.docker.com、检查 DNS改用阿里云镜像源添加 apt 源后 update 报 GPG 错误公钥文件路径或权限不对重新下载 key检查/etc/apt/keyrings/docker.asc是否存在且可读sudo apt-get install -y ca-certificates后重新添加 keyCannot connect to the Docker daemon守护进程未启动或已崩溃systemctl status docker、journalctl -u dockersudo systemctl start docker检查配置语法docker 命令需要反复 sudo当前用户不在 docker 组groups $USERsudo usermod -aG docker $USER后重新登录docker pull 镜像速度极慢未配置镜像加速docker info查看 Registry Mirrors配置 daemon.json 并重启容器内看不到 /dev/ttyUSB0未使用设备透传参数宿主机ls -l /dev/ttyUSB0启动容器时添加--device/dev/ttyUSB0容器能进入但无法读写串口宿主机设备权限不足查看/dev/ttyUSB0的权限和用户组将用户加入 dialout 组或使用--device映射磁盘空间增长过快镜像和悬空层堆积docker system df用docker system prune -a清理无用资源MySQL 容器启动失败数据目录权限不对或端口冲突docker logs mysql8确认 3306 端口未被占用数据目录权限调整为 755这里特别强调权限问题。很多设备透传失败不是 Docker 配置问题而是 Ubuntu 24.04 下/dev/ttyUSB0属于 root 和 dialout 组普通用户没有访问权限。把用户加入 dialout 组是一个常见解法但注意这个组权限较大生产环境需要按需配置。10. 最佳实践与工程建议Docker 能跑起来只是第一步怎么长期用得干净、稳定、安全才是工程上真正见功夫的地方。10.1 数据卷与持久化分离容器是易失的删除重建是常态。所有需要保存的数据比如数据库文件、日志、上传目录都必须通过 volume 或 bind mount 挂载到宿主机。前面启动 MySQL 的示例已经把数据目录挂载出来这是值得长期坚持的习惯。10.2 镜像命名与标签规范不要只在本地盲目打latest标签。建议命名包含项目名和服务名标签包含语义化版本号docker build -t project-backend:1.2.0 . docker build -t project-backend:1.2.0-arm64 .在 170hx 这类特定架构平台上标签中标记架构信息对后续迁移和排错很有帮助。10.3 尽量使用非 root 用户运行容器基础镜像默认以 root 身份运行但这是危险的。创建容器用户能够降低被攻击后的权限扩散风险# 文件路径~/myapp/Dockerfile FROM ubuntu:24.04 RUN useradd -m -u 1000 appuser USER appuser CMD [bash]同样的理念也适用于宿主机不要长时间用 root 操作 Docker普通用户加入 docker 组已经足够管理常规容器。10.4 控制日志大小容器日志如果不限制长时间运行后会占满磁盘。在daemon.json中加入{ log-driver: json-file, log-opts: { max-size: 20m, max-file: 5 }, registry-mirrors: [https://xxxx.mirror.aliyuncs.com] }然后重启 Docker新容器日志就会被限制在 100MB 以内。10.5 网络模式选择默认 bridge 网络适合大多数场景如果容器需要同时被外部访问并且你不想维护复杂端口映射host 网络模式可以省去映射开销但会让容器与宿主机网络完全共享需要权衡安全性。多容器协作时直接使用自定义 network 加容器名互相访问文件格式上推荐使用 Docker Compose 管理。10.6 升级与回滚Docker 本身更新较快关注 Alpine 或 bookworm 这类稳定基础镜像的小版本变化。升级镜像前务必先打标签备份旧镜像并且确认数据卷兼容然后再切换。如果需要回滚用旧镜像重新启动一个新容器即可这也正是容器化部署比传统安装更灵活的地方。11. 总结与后续学习方向到这里一套完整的 Ubuntu 24.04 安装 Docker 驱动透传 基础应用部署 流程已经跑通。核心收获可以概括成三点第一底层驱动必须留在宿主机容器只做设备透传不要在容器里重装驱动第二安装 Docker 用 apt 源加镜像加速的方式最可控第三容器管理的关键词是数据卷、权限和日志这三件事做对了后续维护成本会直线下降。把这篇文章收藏备用然后建议继续深入三块内容一是 Docker Compose它能把多个容器编排在一起一条命令启动整套开发环境二是 Dockerfile 多阶段构建它可以大幅缩小镜像体积三是监控与资源限制在 170hx 这类硬件资源有限的平台上合理设置 CPU 和内存上限能让多个容器稳定共存。驱动和 Docker 的组合本质上是把硬件能力和应用交付解耦。硬件环境准备好一次应用环境就可以随意重建。装好驱动只是第一步让开发环境变得可复制、可迁移、不互相污染才是一个真正好用开发机该有的样子。