개인 도커 레지스트리를 실행 latest
하고 리포지토리에서 이미지를 제외한 모든 이미지를 삭제하고 싶습니다 . 전체 저장소를 삭제하고 싶지 않으며 그 안에있는 이미지 중 일부만 삭제하고 싶습니다. API 문서는 이 작업을 수행 할 수있는 방법을 언급하지 않지만, 분명히 그것은 가능?
답변
현재 해당 작업에 레지스트리 API를 사용할 수 없습니다. 리포지토리 또는 특정 태그 만 삭제할 수 있습니다.
일반적으로 리포지토리를 삭제하면이 리포지토리와 관련된 모든 태그가 삭제됩니다.
태그를 삭제하면 이미지와 태그 간의 연결이 삭제됩니다.
위의 어느 것도 단일 이미지를 삭제하지 않습니다. 그들은 당신의 디스크에 남아 있습니다.
해결 방법
이 문제를 해결하려면 도커 이미지를 로컬로 저장해야합니다.
솔루션의 해결 방법은 최신 태그를 제외한 모든 태그를 삭제하여 관련 이미지에 대한 참조를 제거하는 것입니다. 그런 다음 이 스크립트 를 실행 하여 태그 나 사용 된 이미지의 조상에서 참조하지 않는 모든 이미지를 제거 할 수 있습니다 .
용어 (이미지 및 태그)
대문자는 (여기서, 이와 같은 화상 그래프 고려 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>
태그가 이미지를 참조 하기 때문에 D
나는 당신에게 묻습니다 : 당신은 정말로 이미지를 제외한 모든 것을 삭제 하시겠습니까 D
? 아마 아닙니다!
태그를 삭제하면 어떻게됩니까?
<version1>
Docker REST API를 사용 하여 태그 를 삭제하면 다음을 얻을 수 있습니다.
A <- B <- C <- D
|
<version2>
<latest>
기억하십시오 : Docker는 이미지를 절대 삭제하지 않습니다! 이 경우에도 C
이미지 D
는 태그가 지정된 이미지의 상위 항목 이므로 이미지를 삭제할 수 없습니다 .
이 스크립트 를 사용하더라도 이미지는 삭제되지 않습니다.
이미지를 삭제할 수있는 경우
누군가가 레지스트리를 가져 오거나 푸시 할 수있는시기를 제어 할 수있는 조건 하에서 (예 : REST 인터페이스 비활성화). 이미지를 기반으로하는 다른 이미지가없고 이미지를 참조하지 않는 경우 이미지 그래프에서 이미지를 삭제할 수 있습니다.
다음 그래프, 이미지가 통지 D
되어 있지 기반으로 C
하지만,에 B
. 따라서에 D
의존하지 않습니다 C
. <version1>
이 그래프에서 태그를 삭제 하면 이미지 C
가 이미지 를 사용하지 않으며이 스크립트 는이를 제거 할 수 있습니다.
A <- B <--------- D
\ |
\ <version2>
\ <latest>
\ <- C
|
<version1>
정리 후 이미지 그래프는 다음과 같습니다.
A <- B <- D
|
<version2>
<latest>
이것이 당신이 원하는 것입니까?
답변
내 레지스트리와 동일한 문제에 직면 한 다음 블로그 페이지에서 아래 나열된 솔루션을 시도했습니다. 효과가있다.
1 단계 : 카탈로그 나열
이 URL을 호출하여 카탈로그를 나열 할 수 있습니다.
http://YourPrivateRegistyIP:5000/v2/_catalog
응답 형식은 다음과 같습니다.
{
"repositories": [
<name>,
...
]
}
2 단계 : 관련 카탈로그에 대한 태그 나열
이 URL을 호출하여 카탈로그의 태그를 나열 할 수 있습니다.
http://YourPrivateRegistyIP:5000/v2/<name>/tags/list
응답 형식은 다음과 같습니다.
{
"name": <name>,
"tags": [
<tag>,
...
]
}
3 단계 : 관련 태그의 매니페스트 값 나열
docker registry container에서이 명령을 실행할 수 있습니다.
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
4 단계 : 표시된 매니페스트 삭제
docker registy 컨테이너에서이 명령을 실행하십시오.
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
응답 에서 헤더를 확인하는 단계 .
편집 2 : 다음 env 세트로 레지스트리를 실행해야 할 수도 있습니다.
REGISTRY_STORAGE_DELETE_ENABLED="true"
Edit3 :이 디스크 공간을 확보하기 위해 가비지 수집을 실행해야 할 수도 있습니다 :
https://docs.docker.com/registry/garbage-collection/
답변
문제 1
개인 도커 레지스트리라고 언급 했으므로 제공 한 링크 인 Hub registry API doc 대신 Registry 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 를 사용 하여 개인 도커 레지스트리에 존재하는지 확인할 수 있습니다.
$ 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
-
모든 작업이 올바르게 완료되면 삭제 된 얼룩에 대한 정보가 표시됩니다.
답변
정확히 수행하는 클라이언트 (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
업데이트 : deckschrubber에 대한 간단한 소개 입니다.
답변
간단히;
1) docker repo의 RepoDigests에 다음 명령을 입력해야합니다.
## docker inspect <registry-host>:<registry-port>/<image-name>:<tag>
> docker inspect 174.24.100.50:8448/example-image:latest
[
{
"Id": "sha256:16c5af74ed970b1671fe095e063e255e0160900a0e12e1f8a93d75afe2fb860c",
"RepoTags": [
"174.24.100.50:8448/example-image:latest",
"example-image:latest"
],
"RepoDigests": [
"174.24.100.50:8448/example-image@sha256:5580b2110c65a1f2567eeacae18a3aec0a31d88d2504aa257a2fecf4f47695e6"
],
...
...
$ {digest} = sha256 : 5580b2110c65a1f2567eeacae18a3aec0a31d88d2504aa257a2fecf4f47695e6
2) 레지스트리 REST API 사용
##curl -u username:password -vk -X DELETE registry-host>:<registry-port>/v2/<image-name>/manifests/${digest}
>curl -u example-user:example-password -vk -X DELETE http://174.24.100.50:8448/v2/example-image/manifests/sha256:5580b2110c65a1f2567eeacae18a3aec0a31d88d2504aa257a2fecf4f47695e6
성공적인 호출을 위해서는 202 Accepted를 받아야합니다.
3) 가비지 콜렉터 실행
docker exec registry bin/registry garbage-collect --dry-run /etc/docker/registry/config.yml
registry — 레지스트리 컨테이너 이름입니다.
자세한 설명을 보려면 여기에 링크 설명을 입력하십시오