终端输入 systemctl status docker,你服务 active (running),但输入 docker psdocker info 时,终端返回:“Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

问题现象

典型症状表现:

  1. 执行 systemctl status dockersystemctl is-active docker,输出结果显示服务正在正常运行 (active (running))。

  2. 执行任何 docker 命令 (如 docker ps, docker info, docker pull),都会立即失败,并提示无法连接到 Docker 守护进程。

  3. 尝试在命令行手动运行 dockerd,可能会立刻报错退出,或者即使看起来正在运行,docker 客户端依然无法连接。

  4. 尝试pkill掉docker进程依然没有用。

根本原因分析:两个“Docker”在系统里冲突

这个问题的根源在于,你的 Linux 系统上很可能同时安装了两个不同来源的 Docker 版本,导致了严重的冲突。

  1. 系统自带的版本 (docker.io)

    • 许多 Linux 发行版(如 Debian, Ubuntu)的官方软件库中,提供了一个名为 docker.io 的软件包。

    • 这个版本通常比较旧,但它会作为标准的系统服务被 systemd 注册和管理。

    • 因此,systemctl 命令看到和控制的,正是这个 docker.io 服务。

  2. Docker 官方版本 (docker-ce)

    • 我们按照 Docker 官方文档或通用教程安装的,通常是来自 Docker 官方仓库的社区版(Community Edition),包名通常是 docker-ce

    • 这是一个更新、功能更全的版本,也是我们希望在命令行中实际使用的版本。

当这两个版本并存时,冲突就产生了。systemctl 启动了旧的 docker.io 服务,它占用了 Docker 的通信接口 (/var/run/docker.sock)。而你在命令行中执行的 docker 客户端(来自 docker-ce)尝试连接这个接口时,由于版本不匹配、权限问题或配置冲突,导致连接失败。最终,系统就陷入了这种“精神分裂”的矛盾状态。

终极解决方案:彻底清理并进行纯净安装

要解决这个问题,最可靠的方法就是“大扫除”——将系统上所有与 Docker 相关的软件包和配置彻底清除,然后只安装我们需要的唯一版本。

注意: 以下操作会删除您系统上所有的 Docker 镜像、容器和卷。请在操作前确保没有需要保留的数据。

第一步:停止并禁用旧服务

首先,让 systemctl 停止它正在管理的所有 Docker 服务。

Bash

sudo systemctl stop docker.service
sudo systemctl stop docker.socket
sudo systemctl disable docker.service

第二步:完全卸载所有 Docker 相关的软件包

执行以下命令,purge 会在卸载的同时清除相关的配置文件。

Bash

sudo apt-get purge -y docker-ce docker-ce-cli containerd.io docker.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras

第三步:清理所有残留的数据和目录

确保 Docker 的数据目录、配置目录和运行时目录都被彻底删除。

Bash

sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
sudo rm -rf /etc/docker
sudo rm -rf /etc/apt/sources.list.d/docker.list

第四步:进行一次干净的 Docker 官方版本安装

现在,我们的系统已经回到了没有 Docker 的纯净状态。我们按照官方推荐的步骤,只安装 docker-ce

  1. 更新软件源并安装依赖:

    Bash

    sudo apt-get update
    sudo apt-get install -y ca-certificates curl gnupg
    
  2. 添加 Docker 官方的 GPG 密钥:

    Bash

    sudo install -m 0755 -d /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    sudo chmod a+r /etc/apt/keyrings/docker.gpg
    
  3. 添加 Docker 官方的软件仓库:

    Bash

    echo \
      "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
      "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
      sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    
  4. 最后,安装 Docker Engine:

    Bash

    sudo apt-get update
    sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
    

验证

安装完成后,您的系统里就只存在唯一一个、纯净的 Docker CE 版本了。此时,即使是在不支持 systemctl 的 LXC 环境中,你也可以通过手动方式启动并验证它:

Bash

# 在后台启动 dockerd
sudo dockerd &

# 等待几秒后检查
sleep 5
docker info

如果 docker info 能够成功输出 Client 和 Server 的完整信息,那么恭喜你,这个“幽灵”般的冲突问题已经被彻底解决了!

总结

Linux 系统中,软件包来源的多样性是一把双刃剑。当遇到看似无法解释的“灵异”问题时,不妨回退一步,检查是否存在版本冲突。有时候,最快的捷径就是推倒重来——进行一次彻底的清理和标准化的重新安装,这往往能解决掉 99% 由于环境不一致导致的问题。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐