在使用 Docker 时,遇到启动失败或无法连接 Docker 守护进程的情况是非常常见的。错误信息如:

```
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
```

或者:

```
-bash: cd: /var/run/docker.sock: No such file or directory
Failed to start Docker Application Container Engine.
```

同时,可能还会遇到如下输出:

```
cat /etc/docker/daemon.json 2>/dev/null || echo "No daemon.json found"
No daemon.json found
```

这些错误提示表明 Docker 守护进程没有启动,且必要的文件(如 `/var/run/docker.sock` 和 `/etc/docker/daemon.json`)丢失或损坏。本文将提供一种通过编写脚本自动修复这些问题的方法,帮助我们快速恢复 Docker 的正常运行。

### 错误分析

1. **无法连接到 Docker 守护进程**:
   这通常意味着 Docker 守护进程未启动,或者 `docker.sock` 文件丢失或权限问题。

2. **`/var/run/docker.sock` 丢失**:
   该文件是 Docker 客户端与 Docker 守护进程之间通信的 Unix socket 文件。如果它丢失或损坏,Docker 客户端无法正常工作。

3. **`/etc/docker/daemon.json` 文件丢失**:
   `daemon.json` 是 Docker 配置文件,包含 Docker 守护进程的启动配置。如果该文件丢失,Docker 可能无法加载配置,导致启动失败。

### 修复步骤

我们可以通过编写一个简单的修复脚本 `fix_docker.sh` 来自动修复这些问题。该脚本将执行以下操作:

- 检查并重启 Docker 服务。
- 创建缺失的配置文件 `/etc/docker/daemon.json`。
- 确保 Docker socket 文件 `/var/run/docker.sock` 存在。
- 输出 Docker 服务的状态信息以便进一步调试。

### 编写修复脚本 `fix_docker.sh`

```bash
#!/bin/bash

# 设置日志文件

#!/bin/bash
echo "=== 修复 Docker Socket 激活问题 ==="

# 1. 停止服务
echo "1. 停止相关服务..."
systemctl stop docker docker.socket 2>/dev/null
pkill -f dockerd
sleep 2

# 2. 重置 systemd 限制
echo "2. 重置 systemd 限制..."
systemctl reset-failed docker docker.socket
systemctl unmask docker docker.socket

# 3. 确保 socket 目录存在
echo "3. 检查运行时目录..."
mkdir -p /var/run
chmod 755 /var/run

# 4. 启动 socket 服务
echo "4. 启动 docker.socket..."
systemctl start docker.socket
systemctl enable docker.socket

# 5. 检查 socket 文件
echo "5. 检查 socket 文件..."
sleep 2
if [ -S /var/run/docker.sock ]; then
    echo "✓ Docker socket 创建成功"
    ls -la /var/run/docker.sock
else
    echo "✗ Docker socket 未创建,尝试手动修复..."
    # 手动启动 dockerd 创建 socket
    /usr/bin/dockerd &
    sleep 3
    pkill -f dockerd
fi

# 6. 启动 Docker 服务
echo "6. 启动 Docker 服务..."
systemctl start docker

# 7. 检查结果
if systemctl is-active docker >/dev/null 2>&1; then
    echo "✓ Docker 启动成功"
    docker version
else
    echo "✗ Docker 启动失败,尝试替代方案..."
    # 使用非 socket 激活方式启动
    echo "尝试直接启动 dockerd..."
    nohup /usr/bin/dockerd -H unix:///var/run/docker.sock > /var/log/dockerd.log 2>&1 &
    sleep 5
    if [ -S /var/run/docker.sock ]; then
        echo "✓ Docker 通过直接启动成功"
        docker version
    else
        echo "✗ 所有启动方式都失败,请检查日志"
        journalctl -u docker.service -n 20 --no-pager
    fi
fi

### 脚本说明

1. **检查 Docker 服务状态**:
   - `systemctl is-active --quiet docker` 用于检查 Docker 服务是否正在运行。
   - 如果服务未运行,脚本尝试启动 Docker 服务。

2. **检查 `/var/run/docker.sock` 文件**:
   - 如果该文件不存在,脚本通过重启 Docker 服务来自动生成该文件。

3. **检查并恢复 `/etc/docker/daemon.json` 配置文件**:
   - 如果 `daemon.json` 文件缺失,脚本会创建一个默认的配置文件。

4. **重启 Docker 服务**:
   - 配置文件恢复后,脚本会重启 Docker 服务,确保配置生效。

5. **检查 Docker 服务状态**:
   - 最后,脚本会再次检查 Docker 服务的状态,并记录操作结果。

### 使用方法

1. **下载脚本**:
   将上面的脚本内容保存为 `fix_docker.sh` 文件。

chmod +x fix_docker.sh
./fix_docker.sh

2. **赋予执行权限**:
   在终端中执行以下命令,给脚本文件赋予执行权限:

   ```bash
   chmod +x fix_docker.sh
   ```

3. **运行脚本**:
   通过以下命令运行脚本:

   ```bash
   ./fix_docker.sh
   ```

4. **查看日志**:
   脚本执行过程中的日志会被记录到 `/var/log/fix_docker.log` 文件中,可以查看此文件了解修复过程。

### 总结与 验证修复

# 检查服务状态
systemctl status docker
systemctl status docker.socket

# 测试 Docker 功能
docker ps
docker version

# 检查 socket 文件
ls -la /var/run/docker.sock
  1. 运行修复脚本 → ./fix_docker.sh

  2. 检查 socket 文件 → ls -la /var/run/docker.sock

  3. 修改服务配置 → 如果前两步失败,编辑服务文件禁用 socket 激活

  4. 重新安装 Docker → 作为最后手段

这个问题的根本原因是 systemd 的 socket 激活机制配置错误,通过上述步骤应该能够解决。

通过编写 `fix_docker.sh` 修复脚本,可以快速地恢复 Docker 守护进程的正常运行。该脚本会检查并恢复缺失的配置文件和 socket 文件,自动重启 Docker 服务,并记录操作日志。通过这种方式可以在遇到 Docker 启动失败时,快速解决问题并确保 Docker 正常运行。

Logo

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

更多推荐