繁体   English   中英

停止运行了一定时间的 Docker 容器

[英]Stop a Docker container that's been running for a certain amount of time

我想创建一个 cron 作业,如果 Docker 容器已运行超过 2 小时,它将停止它们。

我可以得到他们开始的时间。

$ docker inspect -f '{{ .State.StartedAt }}' $(docker ps -q)<\/code>

只需要将其与 2 小时前进行比较...

$ date --utc --date="-2 hours" +"%Y-%m-%dT%H:%M:%S.%NZ"<\/code>

...如果它更早停止容器

$ docker stop <<container_id>><\/code>

如何使用 bash 脚本执行此操作?

"

这是一个旧线程,但如果有人正在寻找答案。 以下命令将停止运行超过 2 小时的容器。

docker ps --format="{{.RunningFor}} {{.Names}}"  | grep hours |  awk -F: '{if($1>2)print$1}' | awk ' {print $4} ' | xargs docker stop

说明:

docker ps --format="{{.RunningFor}} {{.Names}}" 

将打印容器名称和运行周期。

grep hours 

将打印以小时为单位运行的容器。

 awk -F: '{if($1>2)print$1}' 

只会打印运行超过 2 小时的容器。

awk ' {print $4} ' | xargs docker stop

将打印从先前输出中获得的容器名称并将其作为参数传递以停止容器。

早在 2013 年,第 1905 期就讨论了这个问题

bash 替代方案是:

#!/bin/bash
set -e

to=$1
shift

cont=$(docker run -d "$@")
code=$(timeout "$to" docker wait "$cont" || true)
docker kill $cont &> /dev/null
echo -n 'status: '
if [ -z "$code" ]; then
    echo timeout
else
    echo exited: $code
fi

echo output:
# pipe to sed simply for pretty nice indentation
docker logs $cont | sed 's/^/\t/'

和:

$ docker-run-timeout.sh 10s busybox sh -c 'echo start && sleep 30 && echo finish'
status: timeout
output:
    start

请注意,使用--rm -d 1.13,您可以使用--rm -d运行(请参阅PR 20848 )。

@Siru 的单线很棒,但是我必须更改以下部分才能正确找到超过两位数天数的容器:

awk -F " " '{if($1>14)print$0}'

@siru 的解决方案激励我寻找一个选项来了解控制的确切时间,因为running for docker ps 是一个四舍五入的格式化结果而不是精确的:

docker ps -q | xargs docker inspect --format='{{.Id}} {{.State.StartedAt}}' |\
 awk '{convert= "date -d " $2 " +%s"
 current= "date +%s" 
 convert | getline startedAt
 close(convert)
 current | getline now
 close(current)
 if((now-startedAt)/(60*60) > 5) print $1}' |\
 xargs docker rm -f

说明:

第一行将以 ISO 8601 格式传递容器 ID 及其开始时间的列表。

然后我们将每个日期转换为 UNIX 时间,计算与当前时间的增量,并仅将运行时间超过指定时间的行传递给docker rm -f

在本例中,所有运行时间超过 6 小时的容器都将被删除。

我希望在格式字符串的 Go 模板中执行此操作,但我认为我们没有时间解析包含的函数(可能会成为一个不错的 PR)。

相反,这是一个利用 date 命令进行时间解析的版本:

#!/bin/sh
# adjust threshold as needed
threshold="2 hours"
# cutoff is seconds since epoc of the threshold time
cutoff="$(date --date="-$threshold" "+%s")"
# loop through the running containers by id
docker container ls -q | while read cid; do
  # retrieve the start time as a string
  startedat="$(docker container inspect "$cid" --format "{{.State.StartedAt}}")"
  # convert to seconds since epoc
  start="$(date --date="$startedat" "+%s")"
  # then we can do a numeric comparison in shell
  if [ "$start" -lt "$cutoff" ]; then
    docker container stop "$cid"
  fi
done

有关使用日期计算偏移量的其他示例,请参阅unix.SE 中的这篇文章

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM