解决容器设置问题的五大必备命令

本文介绍了五个解决Docker容器设置问题的关键命令,包括检查容器状态、查看日志、进入容器内部、覆盖入口点和清理系统资源的方法,帮助开发者快速定位和修复容器故障。

解决容器设置问题的五大必备命令

遵循了教程,运行了Docker Run,然后……什么都没有发生。容器立即退出。或者它正在运行,但localhost只显示“无法访问此网站”。我们都经历过这种情况。当你刚接触Docker时,失败的容器感觉像一个密封的黑匣子。你知道里面出了问题,但不知道如何查看。

在这个快速指南中,我将展示五个基本命令来打开那个盒子,查看发生了什么,并修复你损坏的容器。

“损坏的应用程序”及其修复方法

为了帮助开发者调试他们的设置,让我们从一个有错误的Python小应用程序开始,看看如何进一步调试。以下是相关文件:

app.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello from docker!'

if __name__ == '__main__':
    # 确保容器监听所有网络地址
    app.run(host='0.0.0.0', port=3000)

Dockerfile

1
2
3
4
5
6
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 3000

构建以检查失败:

1
2
3
4
5
# 构建损坏的镜像并标记为my-broken-app
$ docker build -t my-broken-app .

# 运行容器
$ docker run -p 3000:3000 my-broken-app

什么也看不到,直接返回到命令提示符。不幸的是,容器没有启动。让我们开始调试以检查错误。

1. docker ps -a:检查运行的Docker进程

首先要尝试的是运行:docker ps来检查容器。

1
2
3
$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
# ... 它是空的!

这是初学者遇到的第一个陷阱。docker ps只显示当前运行的容器。由于我们的应用程序失败并停止,它不会出现在列表中。

要运行的命令是docker ps -a(这将显示运行/停止的容器)。

1
2
3
$ docker ps -a
CONTAINER ID   IMAGE        COMMAND                  CREATED          STATUS                      PORTS     NAMES
c6b8e0f6a2d1   my-broken-app "python App.py"         8 seconds ago    Exited (1) 8 seconds ago              upbeat_rogers

这揭示了我们可以用来进一步调试的某些信息。我们可以看到我们的my-broken-app容器。查看STATUS列:Exited (1) 8 seconds ago。这意味着容器确实运行了,但是其中的主进程(我们的python App.py命令)失败并以非零状态码退出(这表明有错误)。

何时使用:当容器似乎没有启动时,立即使用docker ps -a。它将确认它是否失败,或者(在另一种常见情况下)它是否正在运行,但你的run命令中存在端口转发问题(PORTS列将为空)。

2. docker logs [container_id]:“哪里出错了"命令

好的,我们知道容器失败了。现在我们需要知道原因。

每个容器都有自己的日志流,捕获其主进程的标准输出(stdout)和标准错误(stderr)。docker logs让你读取它。

docker ps -a命令获取CONTAINER ID(或NAMES)并在此处使用:

1
2
# 你可以使用ID 'c6b8e0f6a2d1' 或名称 'upbeat_rogers'
$ docker logs c6b8e0f6a2d1

输出:

1
python: can't open file '/app/App.py': [Errno 2] No such file or directory

在这里我们看到了问题。错误不是一些复杂的问题;而是一个简单且相当熟悉的"文件未找到"错误。我们的CMD有bug。

何时使用:当容器具有EXITED状态时使用docker logs。使用它来了解失败的原因和方式。

3. docker exec -it [container_id] /bin/sh:窥视容器内部

让我们修复我们的Dockerfile(将App.py更改为app.py)并重新构建:docker build -t my-fixed-app .

如果我们遇到不同的问题怎么办?如果容器正在工作但应用程序不工作(例如,localhost:3000显示"500内部服务器错误”)。

1
2
3
4
5
6
7
# 运行修复的应用程序,但在后台运行
$ docker run -d -p 3000:3000 my-fixed-app

# 检查正在运行的内容
$ docker ps
CONTAINER ID   IMAGE       COMMAND               CREATED          STATUS         PORTS                    NAMES
a3f9a0c3b7e8   my-fixed-app   "python app.py"     5 seconds ago   Up 1 second    0.0.0.0:3000->3000/tcp   eager_jones

它启动了,但不工作。我们如何"进入"其中探查?

使用docker exec。此命令允许你在已运行的容器内运行新进程。在这种情况下,我们将使用它来运行简单的shell命令。

  • exec:执行新命令。
  • -it:代表"交互式终端"。这将把你的键盘和屏幕附加到正在运行的容器。
  • [container_id]:运行容器的ID(例如,a3f9a0c3b7e8)。
  • /bin/sh:这是我们要运行的命令(一个简单的Shell命令)。(/bin/bash和/bin/sh常用)。
1
2
$ docker exec -it a3f9a0c3b7e8 /bin/sh
/app #

你正在查看容器内部!那个#显示它在容器的文件系统中:

  • /app #ls -l:列出文件以及相关权限。
  • /app #cat app.py:显示本地文件以检查内容是否正常。
  • /app #env:检查环境变量。
  • /app #ps aux:检查Python进程是否工作。

何时使用:当容器已启动并运行但应用程序不正常时使用此命令。这非常强大,将在调试实际问题时提供很大帮助。

4. docker run -it –entrypoint /bin/sh [image_id]:“覆盖"命令

这是一个非常巧妙的技巧。如果你的容器失败得如此之快(像我们的第一个my-broken-app示例),以至于你无法exec进入它,并且日志太糟糕以至于你无法使用它来调试。

实际上,Docker有一个有用的命令来覆盖Dockerfile中的CMD或ENTRYPOINT。

1
2
$ docker run -it --entrypoint /bin/sh my-broken-app
/app #

让我们分解一下:

  • run -it:以交互模式启动新容器。
  • –entrypoint /bin/sh:这是命令。它告诉Docker忽略Dockerfile中的CMD(python App.py部分)。相反,它只运行shell。
  • my-broken-app:我们要检查的镜像。

它会将你放入从损坏镜像构建的全新容器内的shell中。它使你能够与文件系统交互,就像CMD即将运行时一样。现在你可以运行ls -l并看到"A-ha!文件是app.py,但我的CMD调用的是App.py。“通过探索镜像本身,你找到了bug。

何时使用:当容器无法启动且Docker日志不清晰时,使用此"覆盖"命令。它是进入任何镜像的万能钥匙。

5. docker system prune:清理僵尸内容的清理命令

随着所有运行的损坏应用程序,将有许多来自旧失败构建的悬空镜像。一些镜像可能很大,占用千兆字节的磁盘空间。

回顾:

  • docker ps -a 显示所有容器。
  • docker image ls 显示所有镜像,包括标记为<none>的镜像(这些是悬空镜像)。

你可以通过docker rm [id]逐个删除容器,docker rmi [id]删除镜像。但是,有一个更简单的方法。

1
2
3
4
5
6
7
8
$ docker system prune
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all dangling images
  - all build cache

Are you sure you want to continue? [y/N] y

它将安全地清理本地设置中的所有悬空内容。

何时运行:在开发会话后运行docker system prune以回收磁盘空间并保持环境清洁。

完整的调试工作流程

以下是整个工作流程的回顾:

  1. 对于容器失败:运行docker ps -a查找容器并查看"EXITED"状态列以精确定位问题。
  2. 检查错误日志:运行docker logs [container_id]查找并了解容器的错误日志。
  3. 如果应用程序不工作时的探索内容
    • 如果容器没有启动,运行docker run -it --entrypoint /bin/sh [image_id]探索本地文件系统。
    • 如果容器正在运行但有bug,应用程序运行不正常,运行docker exec -it [container_id] /bin/sh{bash}以进行调试。
  4. 修复和重建:修复代码和Dockerfile并再次构建容器。
  5. 清理:运行docker system prune清除所有悬空内容。
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计