私は専用のdockerレジストリを実行していて、リポジトリからlatest
以外のすべての画像を削除したいのです。リポジトリ全体を削除するのではなく、その中の一部の画像だけを削除します。 APIドキュメント はこれを行う方法について言及していませんが、確かに可能ですか?
現時点では、そのタスクにレジストリAPIを使用することはできません。リポジトリまたは特定のタグを削除することしかできません。
一般に、リポジトリを削除すると、このリポジトリに関連付けられているすべてのタグが削除されます。
タグを削除するとは、画像とタグとの関連付けが削除されることを意味します。
上記のどれも単一の画像を削除しません。それらはあなたのディスクに残されています。
この回避策のためにあなたはあなたのdockerイメージをローカルに保存させる必要があります。
この問題を回避するには、最新のタグを除くすべてのタグを削除して、関連する画像への参照を削除することが考えられます。その後、このスクリプトを実行して、タグや他の使用済みイメージの祖先によって参照されていないすべてのイメージを削除できます。 。
次のようなイメージグラフを考えてみましょう。大文字(A
、B
、...)は短いイメージIDを表し、<-
はイメージが別のイメージに基づいていることを意味します。
A <- B <- C <- D
今、私たちは写真にタグを追加します。
A <- B <- C <- D
| |
| <version2>
<version1>
ここで、タグ<version1>
はイメージC
を参照し、タグ<version2>
はイメージD
を参照します。
あなたの質問では、削除したいと言っていました
latest
以外のすべての画像
。さて、この用語はまったく正しくありません。画像とタグが混在しています。グラフを見ると、タグ<version2>
が最新のバージョンを表していることに同意すると思います。実際、 この質問によると 最新のバージョンを表すタグを付けることができます。
A <- B <- C <- D
| |
| <version2>
| <latest>
<version1>
<latest>
タグはimage D
を参照しているので、私はあなたに尋ねます:あなたは本当にimage D
以外のすべてを削除したいですか?おそらくそうではありません!
Docker REST APIを使用してタグ<version1>
を削除すると、次のようになります。
A <- B <- C <- D
|
<version2>
<latest>
覚えておいてください:Dockerは決して画像を削除しません!たとえそうであっても、この場合それはイメージを削除することができません、なぜならイメージC
はタグ付けされたイメージD
のための先祖の一部であるからです。
このスクリプトを使用しても、画像は削除されません。
誰かがあなたのレジストリに引っ張ったりプッシュしたりできるときを制御できるという条件の下で(例えばRESTインターフェースを無効にすることによって)。他の画像がそれに基づいておらず、タグがそれを参照していない場合は、画像グラフから画像を削除できます。
次のグラフでは、イメージD
は、C
ではなくB
に基づいてnotになっています。したがって、D
はC
に依存しません。このグラフのタグ<version1>
を削除すると、画像C
はどの画像でも使用されなくなり、このスクリプトでそれを削除できます。 。
A <- B <--------- D
\ |
\ <version2>
\ <latest>
\ <- C
|
<version1>
クリーンアップ後、画像グラフは次のようになります。
A <- B <- D
|
<version2>
<latest>
これは、あなたの望むことですか?
私は私の登録簿との同じ問題に直面したそして私はブログページからの下にリストされている解決を試みた。できます。
次のURLを呼び出してカタログを一覧表示できます。
http://YourPrivateRegistyIP:5000/v2/_catalog
応答は次の形式になります。
{
"repositories": [
<name>,
...
]
}
このURLを呼び出すことでカタログのタグを一覧表示できます。
http://YourPrivateRegistyIP:5000/v2/<name>/tags/list
応答は次の形式になります。
{
"name": <name>,
"tags": [
<tag>,
...
]
}
このコマンドはdockerレジストリコンテナで実行できます。
curl -v --silent -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X GET http://localhost:5000/v2/<name>/manifests/<tag> 2>&1 | grep Docker-Content-Digest | awk '{print ($3)}'
応答は次の形式になります。
sha256:6de813fb93debd551ea6781e90b02f1f93efab9d882a6cd06bbd96a07188b073
マニフェスト値を指定して以下のコマンドを実行します。
curl -v --silent -H "Accept: application/vnd.docker.distribution.manifest.v2+json" -X DELETE http://127.0.0.1:5000/v2/<name>/manifests/sha256:6de813fb93debd551ea6781e90b02f1f93efab9d882a6cd06bbd96a07188b073
Docker registy containerでこのコマンドを実行してください。
bin/registry garbage-collect /etc/docker/registry/config.yml
これが私のconfig.ymlです。
root@c695814325f4:/etc# cat /etc/docker/registry/config.yml
version: 0.1
log:
fields:
service: registry
storage:
cache:
blobdescriptor: inmemory
filesystem:
rootdirectory: /var/lib/registry
delete:
enabled: true
http:
addr: :5000
headers:
X-Content-Type-Options: [nosniff]
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
現在のv2
レジストリはDELETE /v2/<name>/manifests/<reference>
による削除をサポートするようになりました
参照: https://github.com/docker/distribution/blob/master/docs/spec/api.md#deleting-an-image
実用的な使用法: https://github.com/byrnedo/docker-reg-tool
編集:上記のマニフェスト<reference>
は、リクエストから取得することができます
GET /v2/<name>/manifests/<tag>
レスポンスのDocker-Content-Digest
ヘッダをチェックする。
問題1
あなたはそれがあなたのプライベートdockerレジストリであると述べたので、あなたはおそらく レジストリAPI の代わりに ハブレジストリAPIドキュメントをチェックする必要があります 、あなたが提供したリンクです。
問題2
docker registry APIはクライアント/サーバープロトコルであり、バックエンドでイメージを削除するかどうかはサーバーの実装次第です。 (私は推測する)
DELETE /v1/repositories/(namespace)/(repository)/tags/(tag*)
詳細説明
以下に私はあなたの質問に対する私の理解としてあなたの説明からそれが今どのように機能するかを実演します。
あなたは私のデフォルトのものを使い、5000
ポートでリッスンします。
docker run -d -p 5000:5000 registry
それから私はローカル画像にタグを付けてそれにプッシュします。
$ docker tag ubuntu localhost:5000/ubuntu
$ docker Push localhost:5000/ubuntu
The Push refers to a repository [localhost:5000/ubuntu] (len: 1)
Sending image list
Pushing repository localhost:5000/ubuntu (1 tags)
511136ea3c5a: Image successfully pushed
d7ac5e4f1812: Image successfully pushed
2f4b4d6a4a06: Image successfully pushed
83ff768040a0: Image successfully pushed
6c37f792ddac: Image successfully pushed
e54ca5efa2e9: Image successfully pushed
Pushing tag for rev [e54ca5efa2e9] on {http://localhost:5000/v1/repositories/ubuntu/tags/latest}
その後、Registry APIを使用して、プライベートdockerレジストリに存在することを確認できます。
$ curl -X GET localhost:5000/v1/repositories/ubuntu/tags
{"latest": "e54ca5efa2e962582a223ca9810f7f1b62ea9b5c3975d14a5da79d3bf6020f37"}
そのAPIを使ってタグを削除することができます。
$ curl -X DELETE localhost:5000/v1/repositories/ubuntu/tags/latest
true
もう一度確認してください。タグがプライベートレジストリサーバーに存在しません
$ curl -X GET localhost:5000/v1/repositories/ubuntu/tags/latest
{"error": "Tag not found"}
これは本当に醜いですが、うまくいきます、テキストはレジストリでテストされます:2.5.1。削除を有効にするように設定を更新した後でも、削除が円滑に機能しませんでした。 IDを取得するのは本当に難しかったし、それを取得するにはログインしなければならなかった、多少の誤解もありました。とにかく、次のように動作します。
コンテナにログインする
docker exec -it registry sh
コンテナとコンテナのバージョンに一致する変数を定義します。
export NAME="google/cadvisor"
export VERSION="v0.24.1"
レジストリディレクトリに移動します。
cd /var/lib/registry/docker/registry/v2
ハッシュに関連するファイルを削除します。
find . | grep `ls ./repositories/$NAME/_manifests/tags/$VERSION/index/sha256`| xargs rm -rf $1
マニフェストを削除します。
rm -rf ./repositories/$NAME/_manifests/tags/$VERSION
ログアウト
exit
GCを実行します。
docker exec -it registry bin/registry garbage-collect /etc/docker/registry/config.yml
すべてが正しく行われた場合は、削除されたBLOBに関する情報が表示されます。
まさにそれを行うクライアントがいくつかあります(Python、Rubyなど)。私の好みでは、私のレジストリにハウスキーピングするためだけに、ランタイム(例えばPython)を私のレジストリサーバーにインストールすることは持続可能ではありません!
だから deckschrubber
が私の解決策です。
go get github.com/fraunhoferfokus/deckschrubber
$GOPATH/bin/deckschrubber
指定した年齢より古い画像は自動的に削除されます。年齢は-year
、-month
、-day
、またはそれらの組み合わせを使用して指定できます。
$GOPATH/bin/deckschrubber -month 2 -day 13 -registry http://registry:5000
UPDATE: これがdeckschrubberの簡単な紹介 です。
this に基づく単純なRubyスクリプト: registry_cleaner 。
あなたはローカルマシンでそれを実行することができます:
./registry_cleaner.rb --Host=https://registry.exmpl.com --repository=name --tags_count=4
その後、レジストリマシンで/bin/registry garbage-collect /etc/docker/registry/config.yml
を使用してBLOBを削除します。
Bashスクリプトの下最新のものを除くレジストリにあるすべてのタグを削除します。
for D in /registry-data/docker/registry/v2/repositories/*; do
if [ -d "${D}" ]; then
if [ -z "$(ls -A ${D}/_manifests/tags/)" ]; then
echo ''
else
for R in $(ls -t ${D}/_manifests/tags/ | tail -n +2); do
digest=$(curl -k -I -s -H -X GET http://xx.xx.xx.xx:5000/v2/$(basename ${D})/manifests/${R} -H 'accept: application/vnd.docker.distribution.manifest.v2+json' | grep Docker-Content-Digest | awk '{print $2}' )
url="http://xx.xx.xx.xx:5000/v2/$(basename ${D})/manifests/$digest"
url=${url%$'\r'}
curl -X DELETE -k -I -s $url -H 'accept: application/vnd.docker.distribution.manifest.v2+json'
done
fi
fi
done
このランの後
docker exec $(docker ps | grep registry | awk '{print $1}') /bin/registry garbage-collect /etc/docker/registry/config.yml
このdockerイメージには、リモートv2レジストリからイメージを削除するために使用できるbashスクリプトが含まれています。 https://hub.docker.com/r/vidarl/remove_image_from_registry/