Linux Docker 服务管理与排查实战指南(新手速查版)

适用人群:Linux 运维新手、后端开发、DevOps 初学者


1. 核心概念:区分"Docker 服务"与"容器"

在开始之前,需要明确两个概念,避免混淆:

  • Docker 服务 (Daemon) :指 Docker 引擎本身(dockerd)。如果它挂了,所有容器都会停止。
  • 容器 (Container):指运行在 Docker 里的具体应用(如 Nginx、MySQL、Nacos、你的业务代码)。

新手提示:通常我们说"查看 Docker 运行",既可能指查看引擎是否活着,也可能指查看里面的业务容器是否正常。下文将分开讲解。


2. 基础篇:查看 Docker 引擎状态

2.1 检查 Docker 引擎是否存活

这是最基础的命令,用于确认服务器上的 Docker 软件本身是否在运行。

bash 复制代码
# 查看详细的服务状态(推荐)
sudo systemctl status docker

# 快速判断(脚本常用)
systemctl is-active docker

输出解读:

  • active (running):正常,Docker 引擎正在运行。
  • inactive (dead):未启动,需要执行 sudo systemctl start docker
  • failed:启动失败,需要查看日志排查:sudo journalctl -u docker.service -n 50

2.2 验证 Docker 客户端连接

如果 systemctl 显示正常,但执行 docker 命令报错,可以用此命令验证。

bash 复制代码
docker info

输出解读:

  • 如果输出一大堆关于 Containers、Images、Storage Driver 的信息,说明连接正常。
  • 如果报错 Cannot connect to the Docker daemon,说明服务虽然启动了但 socket 文件有问题或权限不足。此时可尝试将当前用户加入 docker 用户组:sudo usermod -aG docker $USER,然后重新登录。

2.3 Docker 服务管理命令速查

操作 命令 说明
启动 Docker sudo systemctl start docker 启动 Docker 引擎
停止 Docker sudo systemctl stop docker 停止引擎(会停止所有容器)
重启 Docker sudo systemctl restart docker 修改配置后常用
设置开机自启 sudo systemctl enable docker 防止服务器重启后服务丢失
查看 Docker 日志 sudo journalctl -u docker.service 排查引擎启动失败等问题

3. 进阶篇:查看与管理容器(业务服务)

这是日常工作中最高频的操作区域。

3.1 查看容器运行状态(黄金命令)

不要只用 docker ps,建议养成使用格式化输出的习惯,信息更直观。

bash 复制代码
# 查看所有容器(包括已退出的),并格式化输出
docker ps -a --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Image}}\t{{.Ports}}"

参数拆解:

  • -a / --all:显示所有容器,不仅仅是正在运行的。
  • --format:自定义输出列。这里我们按顺序展示:容器ID、名字、状态、镜像、端口映射。

输出示例与解读:

CONTAINER ID NAMES STATUS IMAGE PORTS
a1b2c3d4e5f6 nginx-web Up 2 hours nginx:latest 0.0.0.0:80->80/tcp
1854247741c4 mysql-db Exited (1) 5 mins ago mysql:8.0 3306/tcp
f9e8d7c6b5a4 app-backend Restarting (1) 10s ago myapp:v1 ...

状态关键字速查表:

状态关键字 含义 健康度
Up x hours 正在运行中 正常
Up x hours (healthy) 正在运行且通过健康检查 非常健康
Up x seconds 刚启动不久 需观察是否稳定
Exited (0) 正常退出(任务完成或手动停止) 视情况而定
Exited (1) / (137) 异常退出(报错或被系统杀掉) 异常
Restarting 正在反复重启 严重异常
Created 已创建但未启动 未运行
Paused 已暂停 需确认
Dead 无法恢复 异常

3.2 快速筛选特定状态的容器

当服务器上有几十个容器时,直接筛选更高效。

bash 复制代码
# 1. 只看"活着"的容器(默认等价于 docker ps)
docker ps

# 2. 只看"死掉"的容器(Exited)
docker ps -a --filter "status=exited"

# 3. 只看"反复重启"的容器(最危险)
docker ps -a --filter "status=restarting"

# 4. 只看"已创建未启动"的容器
docker ps -a --filter "status=created"

3.3 查看容器日志(排查神器)

当发现容器状态异常时,日志是唯一的真相("黑匣子")。

bash 复制代码
# 查看最后 50 行日志(实时滚动)
docker logs -f --tail 50 <容器名或ID>

# 查看特定时间段的日志
docker logs --since "2023-10-27T10:00:00" <容器名>
3.3.1 容器名和 ID 从哪里来?

在使用 docker logs 之前,你需要知道目标容器的"身份证号"。

  • 容器名 (NAMES)
    • 来源 :通常在启动容器时通过 --name 参数手动指定。例如:docker run --name my-nginx -d nginx
    • 特点 :人类可读,方便记忆。如果你没指定,Docker 会自动生成一个随机的名字(如 happy_turing)。
  • 容器 ID (CONTAINER ID)
    • 来源 :Docker 自动生成的唯一标识符,一串十六进制字符(如 a1b2c3d4e5f6...)。
    • 特点 :在命令行中,通常只需要输入前 3-4 位(短 ID)即可唯一识别,无需输入全称。
3.3.2 怎么找到我要查的容器名或 ID?

如果你忘记了名字,可以通过以下命令查找:

bash 复制代码
# 方法一:列出所有容器,人工查找
docker ps -a

# 方法二:模糊搜索(比如记得名字里带 "mysql")
docker ps -a | grep mysql

# 方法三:只获取 ID(适合配合其他命令使用)
docker ps -aq --filter "name=mysql"

# 方法四:查看某个容器的详细信息(包含完整的 ID、启动命令、挂载等)
docker inspect <容器名或ID>

实战技巧:

  • 如果你想找跟 "mysql" 有关的容器:docker ps -a | grep mysql
  • 如果你只想获取容器 ID(用于脚本):docker ps -q
  • 如果你想看某个容器的完整信息(包括启动命令、环境变量、挂载目录等):docker inspect <容器名>
3.3.3 常用日志查看命令

假设你要排查的容器名为 my-app(或者用 ID a1b2 代替):

bash 复制代码
# 1. 基础查看:查看最后 100 行日志(最常用)
docker logs --tail 100 my-app

# 2. 实时跟踪:像看直播一样看日志输出(排查启动卡住时很有用)
docker logs -f my-app
# 按 Ctrl + C 退出实时模式

# 3. 带时间戳:查看日志发生的具体时间
docker logs -t --tail 50 my-app

# 4. 搜索错误:结合 grep 只看报错信息
docker logs my-app 2>&1 | grep -i "error"

# 5. 查看特定时间之后的日志
docker logs --since "2023-10-27T10:00:00" my-app

# 6. 查看特定时间之前的日志
docker logs --until "2023-10-27T12:00:00" my-app

# 7. 同时查看多个容器的日志
docker logs --tail 20 my-app1 && docker logs --tail 20 my-app2

技巧2>&1 的意思是将"标准错误输出"合并到"标准输出"中,防止有些程序的报错信息打印在另一条流里而被 grep 漏掉。

实战排查流程(四步法):

  1. 抓日志docker logs --tail 100 <容器名>
  2. 搜关键词docker logs <容器名> 2>&1 | grep -iE "error|exception|panic|fatal"
  3. 缩小时间范围 :如果故障发生在某个时间点,用 --since 参数缩小范围
  4. 进入容器:如果日志看不出问题,进入容器内部检查

3.4 进入容器内部调试

有时候光看日志不够,需要进入容器内部检查配置文件、网络、文件等。

bash 复制代码
# 进入容器的 bash 终端(容器需支持 bash)
docker exec -it <容器名> /bin/bash

# 进入容器的 sh 终端(轻量级,多数基础镜像支持)
docker exec -it <容器名> /bin/sh

# 在宿主机上执行容器内的命令(不需要进入容器)
docker exec <容器名> ps aux
docker exec <容器名> cat /etc/hostname
docker exec <容器名> env  # 查看容器内的环境变量

参数拆解:

  • -i / --interactive:保持标准输入打开。
  • -t / --tty:分配一个伪终端。
  • exec:在运行中的容器内执行命令。

3.5 资源占用监控

当服务器变慢时,查看是哪个容器在"抢资源"。

bash 复制代码
# 实时查看 CPU、内存、网络、IO 占用(类似 top 命令)
docker stats

# 查看某个容器的资源占用(一次性输出,不实时刷新)
docker stats <容器名> --no-stream

# 查看容器的详细资源限制
docker inspect <容器名> | grep -A 5 "Memory"

4. 常见问题处理(Troubleshooting)

4.1 容器处于 Restarting 状态

现象docker ps 显示 Restarting (1) 3 seconds ago

原因 :容器启动命令执行失败,或者主进程崩溃,Docker 策略设为 always 导致无限重试。

解决步骤:

  1. 立即查看日志:docker logs --tail 100 <容器ID>

  2. 常见错误:配置文件路径错误、数据库连不上、端口被占用

  3. 如果确定要停止重启循环:

    bash 复制代码
    docker update --restart=no <容器名>
    docker stop <容器名>

4.2 容器处于 Exited (137)

现象:容器意外退出,退出码 137。

原因OOM (Out Of Memory)。容器使用的内存超过了设定的 limit,被 Linux 内核杀掉了。

解决步骤:

  1. 验证:docker inspect <容器ID> | grep -i oom(如果返回 true 则是内存溢出)
  2. 查看系统内核日志确认:dmesg | grep -i 'out of memory' | grep <容器名>
  3. 调整:增加 Docker 内存限制或优化应用代码

4.3 容器处于 Created 状态

现象docker ps -a 显示 Created

原因 :容器被创建了,但没有执行 docker start,或者启动命令(Entrypoint/Cmd)为空/错误。

解决步骤:

  1. 尝试启动:docker start <容器名>
  2. 检查配置:docker inspect <容器名> | grep -A 5 "Cmd"
  3. 如果启动后立刻变成 Exited,查看日志定位原因

4.4 容器内时间不对

现象:业务日志时间与北京时间差 8 小时。

原因:容器默认使用 UTC 时间,而宿主机是东八区。

解决:启动时挂载宿主机时间文件。

bash 复制代码
docker run -v /etc/localtime:/etc/localtime:ro -v /etc/timezone:/etc/timezone:ro ...

4.5 磁盘空间满了(No space left on device)

现象:无法启动新容器,或者日志写不进去。

排查步骤:

bash 复制代码
# 1. 查看磁盘整体使用率
df -h

# 2. 查看 Docker 占用了多少空间
docker system df

# 3. 一键清理(慎用!会删除所有停止的容器、未使用的网络和悬空镜像)
docker system prune

# 4. 安全清理(只删除未使用的镜像,保留容器)
docker image prune

# 5. 彻底清理(删除所有未使用的镜像、停止的容器、构建缓存)
docker system prune -a

# 6. 查找大日志文件(Docker 容器日志可能占用几十 G)
find /var/lib/docker/containers/ -name "*-json.log" -size +1G

# 7. 清空指定日志文件(不删除文件,只清空内容)
cat /dev/null > /var/lib/docker/containers/<长ID>/<长ID>-json.log

4.6 端口冲突

现象 :启动容器时报错 driver failed programming external connectivity

原因:宿主机的端口已经被其他进程占用了。

解决步骤:

bash 复制代码
# 1. 查看哪个进程占用了目标端口
netstat -tlnp | grep <端口号>
# 或
lsof -i :<端口号>

# 2. 杀掉占用端口的进程(谨慎操作)
kill -9 <PID>

# 3. 或者修改容器启动时的端口映射
docker run -p 新端口:容器端口 ...

4.7 容器无法联网

现象 :容器内 pingcurl 外网超时。

排查步骤:

bash 复制代码
# 1. 检查 Docker 网络模式
docker inspect <容器名> | grep -A 5 "NetworkMode"

# 2. 进入容器检查 DNS 配置
docker exec <容器名> cat /etc/resolv.conf

# 3. 检查宿主机 DNS 是否正常
cat /etc/resolv.conf

# 4. 重启 Docker 网络(临时恢复)
sudo systemctl restart docker

5. Nacos 专项运维与排查实战

Nacos (Naming and Configuration Service) 是微服务架构的核心组件,承载了服务注册发现和配置管理两大功能。由于它一旦出问题往往是"爆炸性"的(所有微服务失联),因此需要特别关注其运行状态。

5.1 快速检查 Nacos 健康状态

不要只看 docker ps 显示 Up,Nacos 经常会出现"假死"状态(进程在,但无法响应 HTTP 请求)。

bash 复制代码
# 1. 检查端口监听情况(默认端口 8848)
# 确保状态是 LISTEN,且不是 127.0.0.1(除非你只允许本机访问)
netstat -tlnp | grep 8848

# 2. 使用 curl 探测控制台接口(最准确)
# 如果返回 HTTP 200 或 HTML 内容,说明服务正常
curl -I http://<服务器IP>:8848/nacos/

# 3. 检查集群节点状态(如果是集群模式)
curl http://<服务器IP>:8848/nacos/v1/ns/operator/cluster/state

# 4. 查看服务注册列表(确认微服务是否注册成功)
curl http://<服务器IP>:8848/nacos/v1/cs/services?serviceName=<服务名>

5.2 Nacos 常见故障排查

场景一:Nacos 启动后自动退出 (Exited)

原因:Nacos 对内存非常敏感,默认 JVM 堆内存设置过大,超过了 Docker 容器的内存限制,导致被 OOM Killer 杀掉。

排查命令

bash 复制代码
# 查看退出码,如果是 137,大概率是内存溢出
docker inspect <容器ID> --format='{{.State.ExitCode}}'

# 查看系统内核日志确认 OOM
dmesg | grep -i 'out of memory' | grep nacos

解决方案:启动时通过环境变量调小 JVM 内存。

bash 复制代码
# 示例:将堆内存限制为 512m
docker run -e JVM_XMS=256m -e JVM_XMX=512m ... nacos/nacos-server
场景二:微服务连不上 Nacos(注册失败)

原因:网络模式问题或 IP 漂移。Nacos 默认会注册服务器的内网 IP,如果 Docker 使用了桥接模式,微服务可能拿到的是错误的 IP。

排查命令

bash 复制代码
# 进入容器查看 Nacos 认为自己是谁
docker exec -it <nacos容器ID> cat /home/nacos/conf/application.properties

# 查看 Nacos 启动日志中的 IP 绑定信息
docker logs <nacos容器ID> | grep "Nacos started successfully"

# 查看 Nacos 启动完整日志
docker logs <nacos容器ID>

关键配置 :确保 nacos.inetutils.ip-address 配置的是微服务能访问到的真实 IP。

场景三:配置中心数据丢失或不更新

原因:数据库连接断开或 Derby 模式数据未持久化。

注意 :生产环境严禁使用默认的 Derby 嵌入式数据库,必须切换为 MySQL。

检查命令

bash 复制代码
# 检查是否连接到了外部 MySQL
docker logs <nacos容器ID> | grep "DataSource"
# 应该看到类似 HikariPool 初始化成功的日志,而不是 Derby
场景四:Nacos 控制台无法访问

排查步骤

bash 复制代码
# 1. 检查容器是否在运行
docker ps | grep nacos

# 2. 检查端口是否正确映射
docker inspect <nacos容器ID> | grep -A 10 "Ports"

# 3. 检查容器内部 Nacos 进程是否正常
docker exec -it <nacos容器ID> ps aux | grep nacos

# 4. 检查防火墙是否放行了 8848 端口
# CentOS/RHEL:
sudo firewall-cmd --list-ports | grep 8848
# Ubuntu/Debian:
sudo ufw status | grep 8848

# 5. 重启 Nacos 容器
docker restart nacos

5.3 Nacos 常用运维命令速查

操作 命令示例 说明
查看实时日志 docker logs -f --tail 200 nacos 关注 ERROR 和 WARN
进入容器调试 docker exec -it nacos bash Nacos 脚本通常在 /home/nacos/bin/
修改启动参数 docker exec -it nacos vi /home/nacos/conf/application.properties 修改后需重启容器生效
重启 Nacos docker restart nacos 配置修改后常用
查看 Nacos 版本 docker exec nacos cat /home/nacos/version.txt 确认当前版本
清理临时缓存 rm -rf /home/nacos/data/protocol/raft 高危操作:仅当集群元数据损坏导致无法选主时使用

5.4 Nacos 生产环境最佳实践 Checklist

  1. 持久化 :必须挂载 /home/nacos/data 目录到宿主机,防止容器删除后配置丢失。
  2. 数据库:必须使用 MySQL 8.0/5.7 作为外部存储,严禁使用默认的 Derby。
  3. 单机模式 vs 集群
    • 开发测试用单机模式(MODE=standalone)。
    • 生产环境务必使用集群模式(MODE=cluster),至少 3 个节点。
  4. 鉴权 :生产环境务必开启鉴权(nacos.core.auth.enabled=true)并修改默认密钥,防止被黑客利用上传恶意配置。
  5. 内存限制 :通过 JVM_XMSJVM_XMX 环境变量合理设置堆内存,避免 OOM。
  6. 日志轮转:配置 Nacos 日志轮转策略,防止日志文件无限增长占满磁盘。

6. 附录:常用命令速查表

6.1 容器管理

操作 命令 说明
启动容器 docker start <name> 启动已停止的容器
停止容器 docker stop <name> 优雅停止(发送 SIGTERM)
强制停止 docker kill <name> 立即杀掉进程(发送 SIGKILL)
重启容器 docker restart <name> 先停止再启动
删除容器 docker rm <name> 需先停止,或加 -f 强制删除
创建容器(不启动) docker create <镜像> 仅创建,不运行
进入容器终端 docker exec -it <name> /bin/bash 交互式进入容器
复制文件到容器 docker cp ./file.txt <name>:/path/ 宿主机 -> 容器
复制文件出容器 docker cp <name>:/path/file.txt ./ 容器 -> 宿主机

6.2 镜像管理

操作 命令 说明
列出镜像 docker images 查看本地所有镜像
拉取镜像 docker pull <镜像名> 从仓库下载镜像
删除镜像 docker rmi <镜像名> 删除指定镜像
构建镜像 docker build -t <名> . 从 Dockerfile 构建
查看镜像详情 docker inspect <镜像名> 查看镜像配置信息
镜像打标签 docker tag <旧名> <新名> 给镜像重命名
推送镜像到仓库 docker push <镜像名> 上传到私有/公共仓库

6.3 网络与存储

操作 命令 说明
列出网络 docker network ls 查看 Docker 网络
创建网络 docker network create <名> 创建自定义网络
列出挂载卷 docker volume ls 查看持久化卷
创建卷 docker volume create <名> 创建命名卷

6.4 清理与监控

操作 命令 说明
实时资源监控 docker stats 类似 top,看 CPU/内存
查看系统信息 docker info Docker 引擎详细信息
查看系统磁盘使用 docker system df Docker 各组件占用空间
清理未使用的资源 docker system prune 删除停止容器、悬空镜像等
彻底清理 docker system prune -a 删除所有未使用的镜像

7. 附录:容器名与 ID 速查

很多新手在执行 docker logsdocker exec 等命令时,不知道 <容器名或ID> 该填什么。以下是快速查找的方法汇总:

bash 复制代码
# 1. 列出所有容器,显示名字和 ID
docker ps -a

# 2. 只列出容器 ID(适合脚本中使用)
docker ps -q

# 3. 只列出容器 ID(包括已停止的)
docker ps -aq

# 4. 按名称模糊搜索容器
docker ps -a --filter "name=关键字"

# 5. 获取某个容器的完整 ID
docker inspect -f '{{.Id}}' <容器名>

# 6. 获取某个容器的短 ID(前 12 位)
docker inspect -f '{{.Id}}' <容器名> | cut -c1-12

命名规范建议

  • 容器名使用有意义的英文命名,如 myapp-backendmysql-primarynacos-cluster-1
  • 避免使用特殊字符和下划线以外的符号。
  • 集群场景下用序号区分:nacos-1nacos-2nacos-3

8. 附录:Docker 常用启动参数速查

参数 说明 示例
-d 后台运行(守护进程模式) docker run -d nginx
-p 端口映射 docker run -p 8080:80 nginx
-v 目录挂载(持久化数据) docker run -v /data:/data nginx
-e 设置环境变量 docker run -e MODE=standalone nacos
--name 指定容器名称 docker run --name my-nginx nginx
--restart 重启策略 --restart=always(总是重启)
-it 交互式终端 docker run -it ubuntu /bin/bash
--network 指定网络 docker run --network mynet nginx
--memory 内存限制 docker run --memory 512m nginx
--cpus CPU 限制 docker run --cpus 1.5 nginx
-h 设置容器主机名 docker run -h myhost nginx

重启策略说明:

  • no:不自动重启(默认)。
  • on-failure:容器非正常退出时才重启,可指定最大重启次数:on-failure:5
  • always:无论退出状态如何,总是重启。
  • unless-stopped:同 always,但手动停止后不再重启。

核心原则 :先看状态(docker ps),再看日志(docker logs),最后进容器调试(docker exec)。掌握这个顺序,你已经可以应对绝大多数 Docker 运维问题了。

相关推荐
测试运维日常笔记1 小时前
Unix/Linux 系统软件包管理笔记
linux·笔记·unix
维核科技1 小时前
大模型私有化部署:Docker与Kubernetes实战避坑
docker·容器·kubernetes
雾时之林2 小时前
Linux--介绍及管理
linux·运维·服务器
盐焗鹌鹑蛋2 小时前
【Linux】重定向
linux
呱呱巨基2 小时前
Docker 基础概念学习
linux·c++·学习·docker
Dlrb12113 小时前
Linux驱动---Linux 中断系统及其上与下半部的介绍与阻塞IO实现按键检测
linux·嵌入式硬件·imx6ull·中断·阻塞io
哎呦,帅小伙哦4 小时前
Linux系统中/proc/diskstats文件字段解析
linux
xiaoxiangsiyan4 小时前
企业网络运维自动化与管理协议深度指南
linux·运维·服务器·网络·学习·自动化