Docker'da bağımlı alt imajların listesi nasıl alınır?


123

Bir resmi kaldırmaya çalışıyorum ve şunu elde ediyorum:

# docker rmi f50f9524513f  
Failed to remove image (f50f9524513f): Error response from daemon: conflict: unable to delete f50f9524513f (cannot be forced) - image has dependent child images

Docker versiyonu budur:

# docker version
Client:
 Version:      1.10.3
 API version:  1.22
 Go version:   go1.5.3
 Git commit:   20f81dd
 Built:        Thu Mar 10 21:49:11 2016
 OS/Arch:      linux/amd64

Server:
 Version:      1.10.3
 API version:  1.22
 Go version:   go1.5.3
 Git commit:   20f81dd
 Built:        Thu Mar 10 21:49:11 2016
 OS/Arch:      linux/amd64

ancak fazladan bilgi yok:

# docker images --format="raw" | grep f50f9524513f -C3

repository: debian
tag: 8
image_id: f50f9524513f
created_at: 2016-03-01 18:51:14 +0000 UTC
virtual_size: 125.1 MB

repository: debian
tag: jessie
image_id: f50f9524513f
created_at: 2016-03-01 18:51:14 +0000 UTC
virtual_size: 125.1 MB

Sahip olduğunu iddia ettiği bağımlı çocuk resimlerini nasıl alabilirim ?

bu görüntü kimliğine sahip çalışan veya durdurulmuş kap yok.


9
Docker ekibinin bunu yapmak için neden yerel bir yol sağlayamadığını merak etmeliyim?
Amalgovinus

Yanıtlar:


54

Kısa cevap: İşte bağımlı docker görüntülerini listeleyen bir python3 betiği .

Uzun cevap: Söz konusu görselden sonra oluşturulan tüm görsellerin görsel kimliğini ve ana kimliğini aşağıdakilerle görebilirsiniz:

docker inspect --format='{{.Id}} {{.Parent}}' \
    $(docker images --filter since=f50f9524513f --quiet)

F50f9524513f ile başlayan ebeveyn kimliğine sahip resimleri arayabilmelisiniz, sonra bunların alt resimlerini vb. Arayabilirsiniz . Ama .Parent düşündüğünüz gibi değil. , bu nedenle çoğu durumda docker images --all, bunun işe yaraması için yukarıda belirtmeniz gerekir , o zaman tüm ara katmanlar için de görüntü kimlikleri alırsınız.

Docker çıktısını ayrıştırmak ve görüntülerin listesini oluşturmak için arama yapmak için daha sınırlı bir python3 betiği:

#!/usr/bin/python3
import sys

def desc(image_ids, links):
    if links:
        link, *tail = links
        if len(link) > 1:
            image_id, parent_id = link
            checkid = lambda i: parent_id.startswith(i)
            if any(map(checkid, image_ids)):
                return desc(image_ids | {image_id}, tail)
        return desc(image_ids, tail)
    return image_ids


def gen_links(lines):
    parseid = lambda s: s.replace('sha256:', '')
    for line in reversed(list(lines)):
        yield list(map(parseid, line.split()))


if __name__ == '__main__':
    image_ids = {sys.argv[1]}
    links = gen_links(sys.stdin.readlines())
    trunc = lambda s: s[:12]
    print('\n'.join(map(trunc, desc(image_ids, links))))

Bunu desc.pyşu şekilde çağırabileceğiniz şekilde kaydederseniz:

docker images \
    | fgrep -f <(docker inspect --format='{{.Id}} {{.Parent}}' \
        $(docker images --all --quiet) \
        | python3 desc.py f50f9524513f )

Ya da aynı şeyi yapan yukarıdaki özü kullanın .


2
Ya hiçbiri beklenen karakterlerle başlamazsa? Bu olası bir hatayı mı gösteriyor? Mac için Docker beta, FWIW kullanıyorum, bu beni şaşırtmasın.
neverfox

Ya bu bir hata, ya da söz konusu görüntünün çocuğu olmadığı anlamına geliyor.
Aryeh Leib Taurog

2
Bu gerçekten orijinal soruyu cevaplamıyor. Bu, söz konusu görüntüden sonra oluşturulmuş olanı gösterir ve bu, posterin silmeye çalıştığı görüntüye bağlı olabilir veya olmayabilir. Simon Brady'nin cevabı, en azından küçük resim örnekleri için hile yapıyor.
penguincoder

2
@penguincoder python betiği bunun için.
Aryeh Leib Taurog

@ Neverfox gibi, bu cevap bende işe yaramadı. Simon Brady'nin aşağıdaki cevabı yine de işe yaradı.
Mark

91

Çok sayıda görüntünüz yoksa, her zaman kaba kuvvet yaklaşımı vardır:

for i in $(docker images -q)
do
    docker history $i | grep -q f50f9524513f && echo $i
done | sort -u

1
Bunun "en iyi" çözüm olduğunu düşünüyorum. Bunu biraz genişletebilir ve neyin ne echo $1olduğunu daha çirkin (ama yine de kaba kuvvet) değiştirerek biraz daha net hale getirebilirsiniz docker images | grep $i(docker sürümlerinde --filterGörüntü Kimliği için bayrak kullanmaktan daha taşınabilir )
Jon V

15

Dockviz'i kurun ve ağaç görünümündeki resim kimliğinden dalları izleyin:

go get github.com/justone/dockviz
$(go env GOPATH)/bin/dockviz images --tree -l

önce yapmak daha iyi sudo apt-get update ; sudo apt-get install golang-go; export GOPATH=$HOME/.go.
loretoparisi

3
brew install dockviz
MacOS'ta

Ubuntu kullanırken dikkatli olun. Genellikle kullanım için eski depoları kullanıyor
Qohelet

7

Herhangi birinin bash çözümüyle ilgilenmesi durumunda, bir docker görüntüsünün alt ağacını yazdırmak için kabuk komut dosyasıyla bir öz oluşturdum :

#!/bin/bash
parent_short_id=$1
parent_id=`docker inspect --format '{{.Id}}' $1`

get_kids() {
    local parent_id=$1
    docker inspect --format='ID {{.Id}} PAR {{.Parent}}' $(docker images -a -q) | grep "PAR ${parent_id}" | sed -E "s/ID ([^ ]*) PAR ([^ ]*)/\1/g"
}

print_kids() {
    local parent_id=$1
    local prefix=$2
    local tags=`docker inspect --format='{{.RepoTags}}' ${parent_id}`
    echo "${prefix}${parent_id} ${tags}"

    local children=`get_kids "${parent_id}"`

    for c in $children;
    do
        print_kids "$c" "$prefix  "
    done
}

print_kids "$parent_id" ""

Bu bağlantı soruyu cevaplayabilirken, cevabın temel kısımlarını buraya eklemek ve referans için bağlantıyı sağlamak daha iyidir. Bağlantılı sayfa değişirse, yalnızca bağlantı yanıtları geçersiz hale gelebilir. - Yorumdan
Juan Cruz Soler

Kodu biçimlendirirken sorun yaşadım, bu yüzden pes ettim, bunu yaptığınız için teşekkürler Jan
Michal Linhard

2

Son "imajımı" korumak için yaptığım şey buydu (katman, gerçekten - bu beni atlatan şeydi, çünkü docker yapılarına yeni giriyorum).

Bütün "... zorlanamaz ..." mesajını alıyordum. İhtiyaç duymadığım görüntüleri silemeyeceğimi fark ettim çünkü bunlar 'docker commit' tarafından oluşturulan gerçekten bağımsız görüntüler değiller. Benim sorunum, temel görüntü ile son görüntü arasında birkaç görüntü (veya katman) vardı ve sadece temizlemeye çalışmak, çocuk ve ebeveynle ilgili hata / uyarı ile karşılaştığım yerdi.

  1. Son görüntüyü (veya isterseniz katmanı) bir tarball'a aktardım.
  2. Daha sonra, finalim de dahil olmak üzere istediğim tüm görüntüleri sildim - onu bir tarball'a kaydettim, bu yüzden kullanabileceğimden emin değildim, sadece deney yapıyordum.
  3. Sonra koştum docker image load -i FinalImage.tar.gz. Çıktı şunun gibi bir şeydi:

7d9b54235881: Loading layer [==================================================>]  167.1MB/167.1MB
c044b7095786: Loading layer [==================================================>]  20.89MB/20.89MB
fe94dbd0255e: Loading layer [==================================================>]  42.05MB/42.05MB
19abaa1dc0d4: Loading layer [==================================================>]  37.96MB/37.96MB
4865d7b6fdb2: Loading layer [==================================================>]  169.6MB/169.6MB
a0c115c7b87c: Loading layer [==================================================>]    132MB/132MB

Yüklenen resim kimliği: sha256: 82d4f8ef9ea1eab72d989455728762ed3c0fe35fd85acf9edc47b41dacfd6382

Şimdi, 'docker image ls' ile listelediğimde, sadece orijinal temel imaja ve daha önce bir tarball'a kaydettiğim son imaja sahibim.

[root@docker1 ~]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
httpd               import              82d4f8ef9ea1        3 days ago          747MB
centos              httpd               36540f359ca3        5 weeks ago         193MB

Sistemim artık 'temiz'. Sadece istediğim görüntülere sahibim. Temel resmi bile sorunsuz bir şekilde sildim.

[root@docker1 ~]# docker rmi 36540f359ca3
Untagged: centos:httpd
Untagged:     centos@sha256:c1010e2fe2b635822d99a096b1f4184becf5d1c98707cbccae00be663a9b9131
Deleted: sha256:36540f359ca3b021d4b6a37815e9177b6c2bb3817598979ea55aee7ecc5c2c1f

İyi yanıt, ancak yükün yalnızca "docker save" ile oluşturulan bir görüntüde kullanılması gerekiyor. "
Docker

2

Dayanarak slushy ve Michael Hoffman Bunu kabuk işlevini kullanabilirsiniz görüntülerin bir ton yoksa, cevaplar:

docker_image_desc() {
  for image in $(docker images --quiet --filter "since=${1}"); do
    if [ $(docker history --quiet ${image} | grep ${1}) ]; then
      docker_image_desc "${image}"
    fi
  done
  echo "${1}"
}

ve sonra bunu kullanarak arayın

docker_image_desc <image-id> | awk '!x[$0]++'

2

Burada pip install docker, soyundan gelenleri etiketleriyle birlikte (varsa) yinelemeli olarak listeleyen ve ilişkinin derinliğine göre (çocuklar, torunlar, vb.) Girintiyi artıran Python API'ye ( ) dayalı bir çözüm var :

import argparse
import docker

def find_img(img_idx, id):
    try:
        return img_idx[id]
    except KeyError:
        for k, v in img_idx.items():
            if k.rsplit(":", 1)[-1].startswith(id):
                return v
    raise RuntimeError("No image with ID: %s" % id)

def get_children(img_idx):
    rval = {}
    for img in img_idx.values():
        p_id = img.attrs["Parent"]
        rval.setdefault(p_id, set()).add(img.id)
    return rval

def print_descendants(img_idx, children_map, img_id, indent=0):
    children_ids = children_map.get(img_id, [])
    for id in children_ids:
        child = img_idx[id]
        print(" " * indent, id, child.tags)
        print_descendants(img_idx, children_map, id, indent=indent+2)

def main(args):
    client = docker.from_env()
    img_idx = {_.id: _ for _ in client.images.list(all=True)}
    img = find_img(img_idx, args.id)
    children_map = get_children(img_idx)
    print_descendants(img_idx, children_map, img.id)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("id", metavar="IMAGE_ID")
    main(parser.parse_args())

Misal:

$ python find_dep_img.py 549afbf12931
 sha256:913d0981fdc7d2d673f2c8135b7afd32ba5037755e89b00432d3460422ba99b9 []
   sha256:0748dbc043b96ef9f88265c422e0267807f542e364b7a7fadf371ba5ee082b5d []
     sha256:6669414d2a0cc31b241a1fbb00c0ca00fa4dc4fa65dffb532bac90d3943d6a0a []
       sha256:a6441e7d9e92511608aad631f9abe8627033de41305c2edf7e03ee36f94f0817 ['foo/bar:latest']

Bunu https://gist.github.com/simleo/10ad923f9d8a2fa410f7ec2d7e96ad57 adresinde bir özet olarak kullanıma sundum


1

Bir ana resme bağlı olan alt resimlerin bir listesini almanın basit bir yolu:

image_id=123456789012

docker images -a -q --filter since=$image_id |
xargs docker inspect --format='{{.Id}} {{.Parent}}' |
grep $image_id

Bu, alt / üst resim kimliklerinin bir listesini oluşturacaktır, örneğin (kısalık olması için kısaltılmıştır):

sha256:abcdefghijkl sha256:123456789012

Sol taraf alt resim kimliğidir, sağ taraf silmeye çalıştığımız ana resim kimliğidir, ancak "resimde bağımlı alt resimler var" diyor. Bu bize abcdefghijklbağımlı olan çocuğun olduğunu söylüyor 123456789012. Öyleyse önce yapmalıyız docker rmi abcdefghijkl, sonra yapabilirsindocker rmi 123456789012 .

Şimdi, bağımlı çocuk imajlarından oluşan bir zincir olabilir, bu yüzden son çocuğu bulmak için tekrar etmeye devam etmeniz gerekebilir.


0

Docker görüntülerini, Docker'ın aşağıdaki dizini aracılığıyla, üst ve alt ilişkiden bağımsız olarak silebilirsiniz.

/var/lib/docker/image/devicemapper/imagedb/content/sha256

Bu dizinde Docker görüntülerini bulabilir, böylece istediğinizi silebilirsiniz.


Docker API kullanarak taşınabilir komutlar yapmaya çalışıyorum, cihaz eşleyici ve docker motorunun (örneğin docker swarm aksine) bunu taşınabilir olmayan bir çözüm yaptığını varsayarak. Ayrıca diğer süreç (docker daemon dahil) onu kullanıyor olabilirken dosya sistemindeki dosyaları silmek risklidir.
nicocesar

macos'da nerede?
Anthony Kong

1
* UYARI "bu, gelecekte konteynırların silinmesi ve çekilmesiyle birden fazla hataya neden olabilir. /var/lib/docker
Direkleri

0

Peki ya:

ID=$(docker inspect --format="{{.Id}}" "$1")
IMAGES=$(docker inspect --format="{{if eq \"$ID\" .Config.Image}}{{.Id}}{{end}}" $(docker images --filter since="$ID" -q))
echo $(printf "%s\n" "${IMAGES[@]}" | sort -u)

sha256:Önek ile alt görüntü kimliklerini yazdıracaktır .
Ayrıca isimleri ekleyen şunlara da sahiptim:

IMAGES=$(docker inspect --format="{{if eq \"$ID\" .Config.Image}}{{.Id}}{{.RepoTags}}{{end}}" $(docker images --filter since="$ID" -q))

  • ID= Görüntünün tam kimliğini alır
  • IMAGES= Bu görüntünün listelendiği tüm alt görüntüleri alır Image
  • echo... Yinelenenleri kaldırır ve sonuçları yansıtır

Go formatı koşullarını seviyorum, ancak bu kullanım durumu için filtre olarak daha iyi olabilirler.
ingyhere

0

Bunu, çocukları, repo etiketlerini tekrar tekrar bulmak ve yaptıklarını yazdırmak için hazırladım:

docker_img_tree() {
    for i in $(docker image ls -qa) ; do
        [ -f "/tmp/dii-$i"  ] || ( docker image inspect $i > /tmp/dii-$i)
        if grep -qiE 'Parent.*'$1 /tmp/dii-$i ; then
            echo "$2============= $i (par=$1)"
            awk '/(Cmd|Repo).*\[/,/\]/' /tmp/dii-$i | sed "s/^/$2/"
            docker_img_tree $i $2===
        fi
    done
}

Barındırıcınız güvenli değilse / tmp / dii- * silmeyi unutmayın.


-5

Ben de aynı sorunla karşı karşıyaydım. Sorunu çözmek için aşağıda atanan adımlar.

Çalışan tüm kapsayıcıları durdurun

docker stop $ (docker ps -aq) Tüm kapsayıcıları kaldır

docker rm $ (docker ps -aq) Tüm görüntüleri kaldır

docker rmi $ (docker görüntüleri -q)


bu cevap sorgulayıcı gereksinimini karşılamıyor.
Ankur Loriya

Lütfen insanların kopyalayıp yapıştırma ve zararlı şeyler yapma potansiyeli olan şeyleri yorumlamayı bırakın.
nicocesar
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.