Docker kapsayıcı görüntüleri neden bu kadar büyük?


177

Fedora'dan Dockerfile ile basit bir görüntü yaptım (başlangıçta 320 MB).

Nano (1MB boyutundaki bu küçük editör) eklendi ve görüntünün boyutu 530 MB'ye yükseldi. Git'i bunun üzerine ekledim (30-ish MB) ve sonra görüntü boyutum gökyüzü roketlerimi 830 MB'a ekledim.

Bu deli değil mi?

Geçmişi / ara görüntüleri kaldırmak için kapsayıcıyı içe ve dışa aktarmaya çalıştım. Bu çaba 25 MB'a kadar tasarruf sağladı, şimdi görüntü boyutum 804 MB. Ayrıca bir çok komut çalıştırmayı denedimRUN , ama yine de aynı ilk 830MB alıyorum.

Docker'ı kullanmaya değecek olursam şüphelerim var. Demek istediğim, neredeyse hiç bir şey takmadım ve 1GB'ı vuruyorum. Bir veritabanı gibi ciddi şeyler eklemek zorunda kalacak ve böylece disk alanı tükenebilir.

Kimsenin gülünç boyutta görüntüleri var mı? Bununla nasıl başa çıkıyorsunuz?

Dockerfile'ım korkunç derecede yanlış değilse?

FROM fedora:latest
MAINTAINER Me NotYou <email@dot.com>
RUN yum -y install nano
RUN yum -y install git

ama burada neyin yanlış gidebileceğini hayal etmek zor.


Konteynerinizin boyutunu nerede ve nasıl ölçüyorsunuz? yum clean allBoyut üzerinde herhangi bir etkisi var mı ?
xeor

2
Görüntünün, üst görüntülerin ve temel görüntülerin birikimi olduğu için görüntülerin iyi bir boyutta olmasını bekleyin. Ayrıca, yum sadece belirtilen uygulamaları değil, aynı zamanda bağımlılıklarını da yükler. docs.docker.com/terms/container
rexposadas

2
Benim "ölçüm" benim yürütme olduğunu docker imageshangi son sütun büyük bir 830MB belirtir. Docker images komutu bu 830MB'nin sanal boyutta olduğunu belirttiğinden, görüntümün gerçek boyutunun ne olduğunu bilmiyor olabilirim. Ama sonra tekrar, görüntünün gerçek boyutu nedir?
Zen

Yanıtlar:


118

@Rexposadas'ın dediği gibi, görüntüler tüm katmanları içerir ve her katman, yüklediğiniz şeye ilişkin tüm bağımlılıkları içerir. Temel görüntülerin (örneğinfedora:latest çok çıplak kemikler olma eğilimi yüklü yazılımınızın sahip olduğu bağımlılıkların sayısı sizi şaşırtabilir.

yum -y clean allHer satıra ekleyerek kurulumunuzu önemli ölçüde küçülttüm :

FROM fedora:latest
RUN yum -y install nano && yum -y clean all
RUN yum -y install git && yum -y clean all

Her RUN için, katman işlenmeden veya silmelerin aslında verileri kaldırmaması için bunu yapmak önemlidir. Yani, bir birleştirme / yazma üzerine kopyalama dosya sisteminde, gerçek veriler zaten alt katmanlara adanmış olduğundan, temizleme işlemi dosya sistemi kullanımını gerçekten azaltmaz. Bu sorunu çözmek için her katmanda temizlemeniz gerekir.

$ docker history bf5260c6651d
IMAGE               CREATED             CREATED BY                                      SIZE
bf5260c6651d        4 days ago          /bin/sh -c yum -y install git; yum -y clean a   260.7 MB
172743bd5d60        4 days ago          /bin/sh -c yum -y install nano; yum -y clean    12.39 MB
3f2fed40e4b0        2 weeks ago         /bin/sh -c #(nop) ADD file:cee1a4fcfcd00d18da   372.7 MB
fd241224e9cf        2 weeks ago         /bin/sh -c #(nop) MAINTAINER Lokesh Mandvekar   0 B
511136ea3c5a        12 months ago                                                       0 B

1
Davayı araştırmak için gösterdiğiniz çaba için teşekkür ederiz docker images. Bu eski katmanları kaldırmak / silmek / yok etmek mümkün müdür? Daha spesifik olmak gerekirse: görüntüleri tamamen kaldırmak istiyorum (örneğinize dayanarak): 172743bd5d60, 3f2fed40e4b0, fd241224e9cf, 511136ea3c5a geçmişten tamamen kaldırmak istiyorum, böylece sanal görüntü boyutum son görüntü boyutuyla daha az aynı, burada ~ 260MB .
Zen

(1 yorum için çok uzun) Sanal görüntü boyutunun HDD'deki gerçek görüntü boyutuyla ilgisi yoksa? Bu durumda, görüntülerimin gerçek boyutunu nasıl / nerede kontrol edebilirim?
Zen

Yapabilirdin docker exportve sonra docker importtekrar. Bu katmanları düzleştirecektir. Boyutu azaltacağını sanmıyorum, ama yanılmış olabilirim.
Andy

10
Evet ama ihracat çok fazla tasarruf yapmıyor. Yine de ben docker gözlemleyebilir ne sanal görüntü boyutu olduğunu web üzerinden okuma başardı. HDD'deki gerçek boyut benim için gizem gibi görünüyor çünkü resmi bilgilere göre docker ps -sHDD'de gerçek durumum olan gerçek boyutu gösteriyor -1B. Kulağa mantıklı geliyor, eksi 1 Bayt . HDD'de biraz yer kazandım ... yasal görünüyor.
Zen

@Zen Üzgünüm takip etmiyorum. Sanal boyut ve disk boyutu 2 farklı şey mi? Sanal boyut tam olarak neyi ölçer?
Jason

63

Docker görüntüleri büyük değil, sadece büyük görüntüler oluşturuyorsunuz.

scratchGörüntü 0B ve statik ikili içine kodunuzu derlemek eğer kodunuzu paketlemek için kullanabilirsiniz. Örneğin, size Git programı derlemek ve üstünde paketlemekscratch 5 MB'den daha az tamamen kullanılabilir bir görüntü oluşturmak .

Anahtar, resmi Docker görüntülerini kullanmamaktır, çok büyüktür. Scratch da o kadar pratik değil, bu yüzden temel imajınız olarak Alpine Linux'u kullanmanızı tavsiye ederim. ~ 5MB, o zaman sadece uygulamanız için gerekli olanı ekleyin. Mikrodenetleyiciler hakkında bu yazı Alpine'de nasıl çok küçük görüntüler oluşturabileceğinizi gösteriyor.

GÜNCELLEME: Resmi Docker görüntüleri şimdi alpine dayanmaktadır, bu yüzden şimdi kullanmak iyidir.


2
Harika bir çözüm !, Atıkları durdurmak ve daha güvenli kalmak çok önemlidir ---> daha az kod -> daha az endişe.
Davidovitz

1
Neyse ki, Docker Resmi görüntüleri de bir Alp üssü kullanmak için hareket ediyor, bu nedenle iron.io'nun sürümlerine bağlı olarak normal görüntüleri daha da fazla kullanabilirsiniz. Bkz. Brianchristner.io/docker-is-moving-to-alpine-linux
Martijn Heemels

@Travis R, mikro konteynerlerle ilgili gönderi bağlantınız başka bir yere taşınmış gibi görünüyor. Mı bu Bağlantıya gerekiyordu sonrası?
Alexander F.

@AlexanderF. Sabit bağlantılar, bana bildirdiğiniz için teşekkürler.
Travis Reeder

28

İşte yapabileceğiniz bazı şeyler :

  • Mümkün olduğunda birden fazla RUNkomuttan kaçının . Tek bir RUNkomuta mümkün olduğu kadar koy (kullanarak &&)
  • wget veya git gibi gereksiz araçları temizleme (yalnızca indirme veya oluşturma için ihtiyacınız olan, ancak işleminizi yürütmemeniz)

Bu hem AND hem de @Andy ve @michau önerileri ile nodejs görüntü 1.062 GB 542 MB yeniden boyutlandırmak mümkün oldu.

Düzenleme: Bir daha önemli şey: "Gerçekten her Dockerfile komut deltas ile yeni bir kapsayıcı oluşturuyor anlamak biraz zaman aldı. [...] Eğer rm -rf sonraki komutta dosyaları rm; bazı ara katman kaplarında var olmaya devam ediyorlar. " Yani şimdi ben koymak başardı apt-get install, wget, npm install(git bağımlılıkları ile birlikte) ve apt-get removetek içineRUN yani şimdi benim resmi yalnızca 438 MB, komuta.

Düzenle 29/06/17

Docker v17.06 ile Dockerfiles için yeni bir özellik geliyor: FROMBir Dockerfile içinde birden fazla ifadeye sahip olabilirsiniz ve FROMson Docker görüntünüzde yalnızca sonuncudan gelen şeyler olur. Bu, görüntü boyutunu azaltmak için kullanışlıdır, örneğin:

FROM nodejs as builder
WORKDIR /var/my-project
RUN apt-get install ruby python git openssh gcc && \
    git clone my-project . && \
    npm install

FROM nodejs
COPY --from=builder /var/my-project /var/my-project

Sadece nodejs temel görüntüsüne ve ilk adımlardan / var / my-project içeriğine sahip bir görüntüyle sonuçlanır - ancak yakut, python, git, openssh ve gcc olmadan !


22

Evet, bu boyutlar çok saçma ve neden bu kadar az insanın bunu fark ettiğine dair hiçbir fikrim yok.

Ben aslında çok az bir Ubuntu görüntü yaptım (diğer "minimal" görüntüler aksine). Denir textlab/ubuntu-essentialve 60 MB'dir.

FROM textlab/ubuntu-essential
RUN apt-get update && apt-get -y install nano

Yukarıdaki görüntü nano yüklendikten sonra 82 MB'dir.

FROM textlab/ubuntu-essential
RUN apt-get update && apt-get -y install nano git

Git'in daha birçok önkoşulu vardır, bu yüzden görüntü yaklaşık 192 MB büyür. Bu, çoğu görüntünün başlangıç ​​boyutundan hala daha az.

Docker için minimum Ubuntu resmini yapmak için yazdığım senaryoya da göz atabilirsiniz . Belki de Fedora'ya uyarlayabilirsiniz, ancak ne kadar kaldırabileceğinizden emin değilim.


13

Aşağıdakiler bana çok yardımcı oldu:

Kabımın içindeki kullanılmayan paketleri (ör. 1200 mb serbest bırakılmış) çıkardıktan sonra, aşağıdakileri yaptım:

  1. docker dışa aktarma [containerID] -o includeername.tar
  2. docker import -m "buraya ileti gönderme" içeren kullanıcıadi.tar imagename: tag

Katmanlar düzleşir. Yeni görüntünün boyutu daha küçük olacaktır, çünkü yukarıda belirtildiği gibi paketleri kaptan kaldırdım.

Bunu anlamak çok zaman aldı ve bu yüzden yorumumu ekledim.


Her iki adımı tek bir adımda birleştirebilirsinizdocker export <CONTAINER ID> | docker import - some-image-name:latest
Anuj Kumar

8

En iyi uygulama için, tek bir RUN komutu yürütmelisiniz, çünkü Dockerfile'daki her RUN komutu görüntüde yeni bir katman yazar ve her katman diskte fazladan alan gerektirir. Sayı katmanlarını minimumda tutmak için yükleme, taşıma, çıkarma, kaldırma, vb. Gibi herhangi bir dosya manipülasyonu ideal olarak tek bir RUN talimatı altında yapılmalıdır.

FROM fedora:latest
RUN yum -y install nano git && yum -y clean all


0

Evet, katman sistemi oldukça şaşırtıcı. Temel bir görüntünüz varsa ve aşağıdakileri yaparak artırın:

# Test
#
# VERSION       1

# use the centos base image provided by dotCloud
FROM centos7/wildfly
MAINTAINER JohnDo 

# Build it with: docker build -t "centos7/test" test/

# Change user into root
USER root

# Extract weblogic
RUN rm -rf /tmp/* \
    && rm -rf /wildfly/* 

Görüntü tam olarak aynı boyutta. Bu, görüntüleri yüklenen yazılım kadar küçük yapmak için RUN adımlarınıza çok sayıda ayıklama, yükleme ve temizleme sihri koymayı başarmanız gerektiği anlamına gelir.

Bu hayatı çok daha zorlaştırıyor ...

DockerBuild, taahhüt olmadan RUN adımlarını kaçırıyor.

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.