web-dev-qa-db-ja.com

JenkinsとDockerを搭載したデバイスにスペースがありません-適切にクリーンアップする方法

Ubuntu 16.04.1サーバーでJenkins(バージョン2.60.1)を実行しています。最近発生した問題の1つは、「デバイスに空き容量がありません "」というエラーが定期的に発生することです。

Dockerを使用する場合、ファイルが残されて不要なスペースを占有するため、厳密なクリーンアッププロセスが必要であることを理解しています。

CloudBees Dockerビルドおよび公開プラグインを使用してビルドを処理し、AWSECSにプッシュします。未使用の画像をすべて削除することを考えました。 Jenkinsインスタンスに(SSH経由で)ログインしてdockerコマンドを実行しようとすると、 "Dockerデーモンに接続できません。dockerデーモンは実行されていますか?このホストで? "

どういうわけか、Jenkins環境内またはプラグインの一部からこれを行う必要があると思いますか?

誰かが以前にこれに対処したか、いくつかのアドバイスがありますか? -本当にありがたいです。

6
Aaron

Docker <1.13

1.13より古いDockerの場合、デバイスの一部のスペースをクリーンアップするために次の操作を実行できます。

docker ps -a | grep -i 'exited' | awk '{print $1}' | xargs docker rm > /dev/null 2>&1 &
docker images -a | grep "<none>" | awk '{print $3}' | xargs docker rmi > /dev/null 2>&1 &

または、次のdockerコマンドを実行してみてください。

docker rmi $(docker images --filter "dangling=true" -q --no-trunc)

古い孤立したコンテナをクリーンアップし、<none>でタグ付けされた画像を削除します。 CIサーバーの1つでこれらの2つの式を使用すると、正常に機能します。その前は、あなたの問題と同じように直面していました(デバイスにスペースが残っていません)。

孤立したボリュームのクリーニング

docker volume rm $(docker volume ls -qf dangling=true)
docker volume ls -qf dangling=true | xargs -r docker volume rm

Docker> = 1.13

Docker1.13ではdocker system Pruneコマンドが導入されています( https://docs.docker.com/engine/reference/commandline/system_Prune/ )。または、次を実行することもできます。

  • docker image Prune
  • docker volume Prune
  • docker container Prune

これらのコマンドは、Jenkinsパイプラインの一部として実行できます。私が取り組んでいるプロジェクトの1つでは、リリースプロセス中に新しいDockerイメージをビルドした後にクリーンアップを実行します。 「Dockerデーモンに接続できません。Dockerデーモンはこのホストで実行されていますか?」を修正するためにも試してください。問題。

7
Szymon Stepniak

以下のburnettkが提供するスクリプトを使用した後、さらにビルドを実行した後、いくらかのスペースが解放されたが、同じ場所に戻ったようで、EBSボリュームにスペースがありませんでした。ストレージを追加してAWSに毎月の請求額をさらに支払う必要があるのは、まったく意味がありません。

調査を行ったところ、ビルドごとに、それぞれ約1.4GB、つまり9GB /ビルドで構成される約7つのイメージ(docker images -a)が作成されていることがわかりました。最初の2つはビルド番号と最新のタグが付けられ、残りはがタグ付けされます。

ビルドが目的であり、とにかくECRにプッシュされるため、これらすべてのイメージをこのサーバーに保存することは実際には重要ではありません。そこで、スクリプトに以下を追加して、最新のDockerイメージのみが保持されるようにしました。

docker rmi $(docker images | sed 1,3d | awk '{print $3}')

最後に、-rm引数を追加してdocker buildコマンドを調整し、ビルド後に中間コンテナーを削除するようにしました。

docker build --rm

これがお役に立てば幸いです。

2
Aaron

「dockerdockerデーモンに接続できません」という問題を回避するには、dockerグループに含まれるユーザーを特定します。

grep 'docker' /etc/group

次に、それらのユーザーの1人としてdocker cleanupコマンドを実行します(cronなどで実行するスクリプトに変換する必要があります)。または、別のユーザーとSudoアクセスを取得して、Sudoを使用します。

Sudo docker rmi [image_name_here]

クリーンアップスクリプトの例の内容は次のとおりです(/usr/local/bin/clean_up_docker_stuff_on_ci_agent または類似):

#!/bin/bash

# stop containers that have been running for more than a day (may not be valid in your context if you intend run things for a long time)
docker ps -a | egrep " days" | awk '{print $1}' | grep -v CONTAINER | xargs docker stop

# remove all exited containers
docker ps -a | egrep "Exited|Created" | awk '{print $1}' | grep -v CONTAINER | xargs docker rm

# remove old images
docker images | egrep 'weeks|months' | awk '{print $1 ":" $2}' | xargs docker rmi -f
docker images | egrep 'weeks|months' | grep '<none>' | awk '{ print $3 }' | xargs docker rmi -f

# kill stray volumes
docker volume ls -qf dangling=true | xargs -r docker volume rm

Szymon Stepniakが彼の回答で述べているように、docker> = 1.13を使用している場合は、より簡単なオプションがあります。

cronの例(1時間ごとに20):

20 * * * * /usr/local/bin/clean_up_docker_stuff_on_ci_agent > /dev/null 2>&1
1
burnettk

JenkinsのDockerプラグインには、Dockerエージェントテンプレート構成にボリュームの削除チェックボックスがあります。

Remove the volumes associated to the container during container remove.

通常、発生しているエラーは、ユーザーがdocker cliの使用を許可されていないか、dockerが停止しているためです。

とにかく、クリーンアップを適切に行う方法についての質問に答えるために。

  1. 古いビルドを定期的に破棄するようにジョブを設定してください。
  2. Dockerを実行できない場合(理由はわかりません)。次に、Jenkinsサーバーの/ var/lib/dockerディレクトリをクリーンアップするcronを用意します。
  3. 最後に、jenkinsスレーブとして実行されるdockerコンテナーを使用します。このように、ビルドアーティファクトは一時ファイルシステムに保存され、jenkinsスレーブを定期的に再プロビジョニングすると、ディスク容量の問題が発生しなくなります。
0
john