docker里用top的一个坑

业务背景

使用 top + grep 来判断一个进程是否退出。如果grep不到了,就说明退出里,否则等待1秒钟重新判断

测试进程process_abc,sleep 5秒钟后自动退出

#include <stdio.h>

int main()
{
        sleep(5);
        return 0;
}

检测脚本

velscode@velscode:~/test$ cat check.sh
#/bin/bash

while true
do
        top -n 1 -b | grep "process_abc"
        if [ $? -eq 0 ];then
                echo "process_abc alive, wait it"
                sleep 1
        else
                echo "process_abc exit"
                break
        fi
done

问题现象

通过 docker run --it .. 进入容器bash,手工执行命令,正常

检测脚本检测到目标进程5次,每次等待1秒,process_abc退出后,执行结束

# 拉起容器的脚本
velscode@velscode:~/test$ cat run_manual.sh
DOCKER_CONTAINER_TAG=ubuntu/test:1.0

docker build -f Dockerfile . -t ${DOCKER_CONTAINER_TAG}
docker run -it --privileged \
 -v $(pwd):/opt/ \
 -w /opt/ \
 ${DOCKER_CONTAINER_TAG} /bin/bash

# 拉起容器
velscode@velscode:~/test$ bash run_manual.sh
Sending build context to Docker daemon  24.58kB
Step 1/1 : FROM ubuntu:latest
 ---> ba6acccedd29
Successfully built ba6acccedd29
Successfully tagged ubuntu/test:1.0

# 执行测试进程和检测脚本
root@a63946704302:/opt# ./process_abc & bash check.sh
[1] 9
     9 root      20   0    2352    516    452 S   0.0   0.1   0:00.00 process_abc
process_abc alive, wait it
     9 root      20   0    2352    516    452 S   0.0   0.1   0:00.00 process_abc
process_abc alive, wait it
     9 root      20   0    2352    516    452 S   0.0   0.1   0:00.00 process_abc
process_abc alive, wait it
     9 root      20   0    2352    516    452 S   0.0   0.1   0:00.00 process_abc
process_abc alive, wait it
     9 root      20   0    2352    516    452 S   0.0   0.1   0:00.00 process_abc
process_abc alive, wait it
process_abc exit
[1]+  Done                    ./process_abc

如果采用 docker run ... /bin/bash -c "./process_abc & bash check.sh",则检测脚本无法检测到进程

# 拉起容器的脚本
velscode@velscode:~/test$ cat run_docker.sh
DOCKER_CONTAINER_TAG=ubuntu/test:1.0

docker build -f Dockerfile . -t ${DOCKER_CONTAINER_TAG}
docker run --privileged \
 -v $(pwd):/opt/ \
 -w /opt/ \
 ${DOCKER_CONTAINER_TAG} /bin/bash -c "export TERM=xterm; ./process_abc & bash check.sh"

# 执行结果
velscode@velscode:~/test$ bash run_docker.sh
Sending build context to Docker daemon  24.58kB
Step 1/1 : FROM ubuntu:latest
 ---> ba6acccedd29
Successfully built ba6acccedd29
Successfully tagged ubuntu/test:1.0
process_abc exit

问题原因

在docker中,终端默认宽度比较小,top结果的进程名显示不全

velscode@velscode:~/test$ cat run_docker.sh
DOCKER_CONTAINER_TAG=ubuntu/test:1.0
docker build -f Dockerfile . -t ${DOCKER_CONTAINER_TAG}
docker run --privileged \
 -v $(pwd):/opt/ \
 -w /opt/ \
 ${DOCKER_CONTAINER_TAG} /bin/bash -c "export TERM=xterm; ./process_abc & top -n 1 -b"


velscode@velscode:~/test$ bash run_docker.sh
Sending build context to Docker daemon  24.58kB
Step 1/1 : FROM ubuntu:latest
 ---> ba6acccedd29
Successfully built ba6acccedd29
Successfully tagged ubuntu/test:1.0
top - 11:06:12 up  1:39,  0 users,  load average: 0.01, 0.08, 0.08
Tasks:   3 total,   1 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni, 93.3 id,  6.7 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :    962.1 total,    119.1 free,    256.5 used,    586.6 buff/cache
MiB Swap:   1924.0 total,   1922.5 free,      1.5 used.    551.5 avail Mem

   PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     1 root      20   0    3980   2952   2740 S   0.0   0.3   0:00.00 bash
     7 root      20   0    2352    576    516 S   0.0   0.1   0:00.00 process_+
     8 root      20   0    5972   3204   2776 R   0.0   0.3   0:00.00 top

导致grep失败。

解决方法

使用 top 的 w参数指定宽度

velscode@velscode:~/test$ cat run_docker.sh
DOCKER_CONTAINER_TAG=ubuntu/test:1.0
docker build -f Dockerfile . -t ${DOCKER_CONTAINER_TAG}
docker run --privileged \
 -v $(pwd):/opt/ \
 -w /opt/ \
 ${DOCKER_CONTAINER_TAG} /bin/bash -c "export TERM=xterm; ./process_abc & top -n 1 -b -w 512"


velscode@velscode:~/test$ bash run_docker.sh
Sending build context to Docker daemon  25.09kB
Step 1/1 : FROM ubuntu:latest
 ---> ba6acccedd29
Successfully built ba6acccedd29
Successfully tagged ubuntu/test:1.0
top - 11:07:57 up  1:40,  0 users,  load average: 0.07, 0.07, 0.08
Tasks:   3 total,   1 running,   2 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni, 93.3 id,  6.7 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :    962.1 total,    115.5 free,    258.3 used,    588.4 buff/cache
MiB Swap:   1924.0 total,   1922.5 free,      1.5 used.    549.6 avail Mem

   PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     1 root      20   0    3980   2944   2728 S   0.0   0.3   0:00.00 bash
     7 root      20   0    2352    584    520 S   0.0   0.1   0:00.00 process_abc
     8 root      20   0    5972   3232   2808 R   0.0   0.3   0:00.00 top

可以看到进程名显示全了,grep可以正常工作里

<think>嗯,用户的问题是关于如何查看Docker所有容器的运行状态。这个问题很实用,也是Docker日常管理中的基础操作。 仔细看看用户提供的引用内容,引用[1]提到了"docker ps -a"可以列出所有容器,无论状态如何。引用[2]展示了使用"docker inspect"查看具体容器状态的例子。引用[3]则提到了端口显示相关的问题。这些都是很有价值的参考资料。 用户特别强调了"所有容器"这个需求点,说明他需要的是一个局视角的监控方案。结合这些信息,我考虑给出三种同粒度的解决方案: 1. 最基础的docker ps命令,用-a参数确保显示所有容器,加上--format可以自定义输出格式。这是最直接的方法。 2. docker inspect配合格式化输出,虽然命令稍长但能获取更详细的信息,特别是容器运行状态的核心指标。 3. 第三方工具如ctop,适合需要实时监控的场景。 在示例部分,准备展示docker ps的几种常用输出格式,从默认格式到精简格式再到自定义格式。对于docker inspect,则重点提取运行状态和启动时间这两个关键字段。最后会简单介绍ctop的优势,给高级用户多一个选择。 考虑到用户可能是运维人员或开发者,问题中还准备加入注意事项,比如容器ID截断问题、格式化字符串的使用技巧等实用细节。这样仅解答了当前问题,还能帮助用户避免后续操作中的常见点。 </think>根据您的需求,以下是查看 Docker 所有容器运行状态的方法总结: ### 一、基础查看方法 1. **查看所有容器状态(推荐)** ```bash docker ps -a ``` - **输出说明**: `CONTAINER ID`(容器ID) | `IMAGE`(镜像) | `COMMAND`(启动命令) `CREATED`(创建时间) | `STATUS`(运行状态) | `PORTS`(端口映射) | `NAMES`(容器名称) - **状态字段解释**: - `Up [时间]`:正常运行(如 `Up 2 hours`) - `Exited ([代码]) [时间]`:已退出(如 `Exited (0) 5 minutes ago`) - `Created`:已创建但未运行 2. **仅显示运行中的容器** ```bash docker ps # 省略 -a 参数 ``` ### 二、高级状态监控 1. **获取所有容器的运行状态(精确过滤)** ```bash docker inspect -f '{{.Name}} {{.State.Running}}' $(docker ps -aq) ``` - **输出示例**: `/nginx1 true` `/mysql_container false` - 说明:`true`=运行中, `false`=已停止 2. **批量查看关键状态信息** ```bash docker ps -a --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Ports}}" ``` - **定制字段**:可替换 `{{.Ports}}` 为 `{{.Image}}`, `{{.Command}}` 等 ### 三、状态异常排查 1. **查看特定容器详细状态** ```bash docker inspect 容器名/ID | grep -A 10 "State" ``` - 输出包含:`"Running"`, `"ExitCode"`, `"Error"` 等关键字段 [^2] 2. **端口显示问题处理** - 若 `PORTS` 列为空,检查启动命令是否缺少 `-p` 参数: ```bash docker run -d -p 主机端口:容器端口 镜像名 # 正确示例 [^3] ``` ### 四、可视化工具推荐 ```bash docker run --rm -ti --name=ctop -v /var/run/docker.sock:/var/run/docker.sock quay.io/vektorlab/ctop:latest ``` > 实时显示所有容器的 CPU/内存/状态信息(类似 `top` 命令) --- **注意事项**: 1. 容器 ID 可缩写(通常前 4 字符足够) 2. 状态中的时间格式可通过 `--format` 自定义(如 `{{.RunningFor}}`) 3. 使用 `docker update` 可修改运行中容器的资源限制
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值