Liman görüntüsünden dosya çıkartılsın mı?


24

Görüntüyü çalıştırmak zorunda kalmadan Docker görüntüsündeki bir dosyayı ayıklamak istiyorum.

Bu docker saveseçenek, belirli bir dosyayı kaldırmak için çok büyük bir dosya tasarrufu sağladığından, benim için şu anda uygun bir seçenek değil.


Hangi dağıtımı kullanıyorsun?
ryekayo

@ryekayo: Ubuntu 14, liman işçisi 1.12.4 (yaklaşık 1.24)
BlakBat

Yanıtlar:


21

Bir resimdeki dosyaları aşağıdaki komutlarla çıkarabilirsiniz:

docker create $image  # returns container ID
docker cp $container_id:$source_path $destination_path
docker rm $container_id

docker create Belgelere göre , bu konteyner çalıştırmaz:

docker createKomut Belirtilen resmin üzerine yazılabilir bir konteyner tabakası oluşturur ve belirli bir komutu çalıştırmak için hazırlar. Konteyner kimliği daha sonra basılır STDOUT. Bu, docker run -dkabın hiçbir zaman başlatılmaması haricinde benzer . docker start <container_id>Konteyneri herhangi bir noktada başlatmak için bu komutu kullanabilirsiniz .


Başvuru için (önceki cevabım), bir görüntüden bir dosyayı çıkarmanın daha az etkili bir yolu şudur:

docker run some_image cat $file_path > $output_path

3
Giriş noktasını fazla kullanmak isteyebilirsiniz. docker run --entrypoint /bin/sh my_image -c /bin/cat some_file
Andrew,

1
Bu, özellikle sorumla belirtildiği gibi yapmak istemediğim şey olan görüntüyü çalıştırıyor.
BlakBat

Ah, bu iyi bir nokta. Şimdiki cevabımın tatmin edici olmadığını kabul ediyorum.
bbc

1
@BlakBat Bu güncellenmiş cevap sizin için çalışıyor mu? Sanırım yeni bir cevap vermeliydim ama şimdi yapıldı.
bbc

1
@ bbc Bu güncellenmiş cevap aslında bir konteynır başlatmaz (sorunun temel noktasıdır) ve kök olmak zorunda değildir.
BlakBat

2

Yukarıdakilerin hiçbiri benim için çalıştı. Tam çalışma komutu:

docker run --rm --entrypoint /bin/sh image_name -c "cat /path/filename" > output_filename

Tırnaklar catolmadan dosya adı olmadan geçilir, bu nedenle ne gösterileceğini bilmez. Ayrıca komut tamamlandıktan sonra kabı silmek iyi bir fikirdir.


Bahsettiğiniz komut, sadece liman işçisi ve Dockerfile içinde ENTRYPOINT / CMD'nin ne kadar doğru ayarlandığına bağlı olarak çalışacaktır; bunun alıntı ile ilgisi yok. Ayrıca kabı silmek de diyorsunuz, ancak --rm belirtiyorsunuz. Son olarak, sorumu ilettiğimde "görüntüyü çalıştırmaya gerek kalmadan" belirttim ve hiçbir cevap bunu dikkate alarak bir çözüm değildi.
BlakBat

1
Hangi CMD ve ENTRYPOINT’in Dockerfile’de ayarlanmış olduğuna bakılmaksızın her ikisini de geçersiz kıldım, bu yüzden her zaman işe yarayacak (tabii ki Linux'ta). Ne demek "liman işçisi bağlı"? Ayarlar, sürüm, env, ne? Sorunuz doğru değil çünkü resimler yürütülemiyor, sadece konteynırlar var. Bence doğru cevap yok, birçok dosyayla başa çıkmak ya da geçici bir kap oluşturmak zorundasınız. --rm geçici kabı kaldırır, diğerlerinin cevapları diskinizde bazı hurdalıklar bırakır.
sekrett

1

Yanılmıyorsam, liman konteynerlerinin Ubuntu için aşağıdaki dizinde oluşturulan önbelleğe alınmış dosyaları depoladığını düşünüyorum:

/var/lib/docker/aufs/diff/<container_id>

Oradan, dosya sistemine erişebilmeli ve dosyalarınızı alabilmelisiniz.


Hayır! Bu dizin yalnızca içerir layersizeve jsonve ayrıca kullanıcı tarafından okunabilir değildir (kullanıcı docker grubunda olsa bile). /var/lib/docker/aufs/diffAradığım dosyayı içerecektir (ancak konteyner kimliğine göre kategorilere ayrılmamıştır) ve ayrıca okunamaz.
BlakBat

Bana birkaç ver, ben bakayım. Bir kabın içine girmeden veya çalıştırmadan dosyaları almanın bir yolu olduğunu biliyorum.
ryekayo

Okunamıyor, nasıl gösterir? Metin dosyalarını / var / lib / docker / aufs / diff / * dizinine gidip kaplardan çekebileceğiniz bir örnek buldum
ryekayo 20:16 '

Benim hatam. Kullanıcı erişebilir /var/lib/docker/aufs(içindeki tüm dizinlere /var/lib/docker/
erişemez

Kök olarak erişebilir misin?
ryekayo

0

Tam çıktısını saklamak docker savebir seçenek değilse, yalnızca gerekli dosyayı çıkarmak için boru hatları kullanabilirsiniz.

Ne yazık ki, çıktı bir "katran katranı" olduğu için, biraz yinelemeli bir işlem olabilir.

Az önce bir dosyayı çıkarmam gerektiğinde yaptığım şey:

1) En son ilgilendiğiniz dosyanın hangi sürümünde değiştirildiğini (bunun muhtemelen resminize bağlı olduğunu) ve oluşturulduğu / kaydedildiği tarihi belirleyin.

2) docker saveKomutun çıktısından tüm içindekiler tablosunu alın :

docker save IMAGE_NAME | tar -tvf -

3) layer.tar1. adımda belirlediğiniz resmin tarihine uyan bu komutun çıktısında bulunan | grep layer.tardosyaları inceleyin (yalnızca bu dosyaları göstermek için ekleyebilirsiniz )

4) Bu layer.tardosyayı standartlara ayıklayın ve içindekiler tablosunu alın:

docker save IMAGE_NAME | tar -xf - -O CHECKSUM_FROM_LIST/layer.tar | tar -tvf -

5) İstediğiniz dosyanın listelendiğini doğrulayın ve adı bulduktan sonra çıkarın:

docker save IMAGE_NAME | tar -xf - -O CHECKSUM_FROM_LIST/layer.tar | tar -xf - PATH/TO/YOUR/FILE

layer.tarAdım 2/3'te aradığınız tarihle eşleşen birden fazla dosya varsa, doğru olanı bulana kadar her biri için 4. adımı tekrarlamanız gerekebilir.

Büyük harflerle yazılan metni yukarıdaki komutlarda, durumunuz için doğru resim adları, sağlama toplamları ve dosya adlarıyla değiştirin.

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.