Ubuntu 20.04下用snap安装Docker的那些坑:为什么systemctl restart docker.service不工作?
最近在Ubuntu 20.04上配置开发环境,为了图省事,直接用snap install docker一条命令装好了Docker。本以为万事大吉,结果在尝试重启Docker服务时,熟悉的sudo systemctl restart docker.service命令却给了我当头一棒——终端冷冰冰地提示“Unit file docker.service does not exist”。相信不少从其他Linux发行版转过来,或者习惯用apt安装Docker的朋友,都遇到过这个让人困惑的瞬间。这不仅仅是命令失效那么简单,它背后是Ubuntu近年来力推的Snap包管理体系与传统Systemd服务管理机制之间的一次“理念碰撞”。对于追求高效、稳定且需要精细控制服务的开发者而言,理解这背后的“为什么”以及掌握正确的“怎么做”,远比记住几个命令更有价值。本文将带你深入这个问题的核心,不仅解决服务管理问题,更厘清Snap与Systemd的协作关系,让你在Ubuntu上驾驭Docker时更加得心应手。
1. 问题根源:Snap与Systemd的“服务管理权”之争
当你在Ubuntu 20.04上通过Snap安装Docker后,系统里其实存在两套服务管理体系在同时运作。一套是你熟悉的、统治着绝大多数Linux发行版的Systemd,它通过.service单元文件来定义和管理后台守护进程(daemon)。另一套则是Canonical(Ubuntu背后的公司)大力推广的Snap打包体系自带的运行时管理环境。
Snap的设计哲学是提供一个高度封装、自包含且安全的软件分发方式。一个Snap包将其运行所需的所有依赖(包括特定的库、运行时环境)都打包在一起,形成一个独立的“沙盒”。为了实现这种隔离和自管理,Snap拥有自己的一套服务管理机制。当你执行snap install docker时,Snap系统不仅安装了Docker的二进制文件,还自动创建并注册了管理Docker守护进程(dockerd)所需的Snap服务。
注意:这里的“服务”指的是Snap语境下的服务,它是一个由
snapd(Snap守护进程)管理的、在沙盒内运行的后台进程。它与Systemd管理的“系统服务”概念相似,但管理接口和生命周期完全独立。
因此,systemctl restart docker.service失败的根本原因在于:Systemd的单元文件目录(如/etc/systemd/system/或/lib/systemd/system/)中,根本不存在一个名为docker.service的文件。这个文件原本应由apt安装的Docker包提供。Snap安装的Docker,其服务定义被封装在Snap内部,由snapd直接管理。你可以通过以下命令验证这一点:
# 查找系统范围内是否存在docker.service单元文件
systemctl list-unit-files | grep docker
# 或者直接检查单元文件路径
ls /etc/systemd/system/docker.service 2>/dev/null || echo "文件不存在"
ls /lib/systemd/system/docker.service 2>/dev/null || echo "文件不存在"
执行后


3167

被折叠的 条评论
为什么被折叠?



