Her seferinde en küçük çalışan liman işçisi imajı nasıl oluşturulur?


19

Amaç: her seferinde en küçük çalışan liman işçiliği görüntülerini oluşturmak

şimdiki

REPOSITORY          TAG       IMAGE ID            CREATED             SIZE
a-docker-image      latest    x                   42 minutes ago       1.92 GB

Girişim

Dockerfile dosyasının sonuna bir temizleme adımı ekleme:

#clean
RUN apt-get purge -y wget
RUN rm -r a-build-dir
RUN apt-get purge -y a-package

görüntü boyutunu biraz küçülttü:

REPOSITORY          TAG       IMAGE ID            CREATED             SIZE
a-docker-image      latest    y                   2 minutes ago       1.86 GB

Tartışma

Çeşitli liman işçisi resimleri yaptım. Oluşturulan görüntünün boyutunu her azaltmaya çalıştığımda, ancak her zaman çok büyük olduğunu hissediyorum. Ben zaten github üzerinde oluşturulan gereksiz görüntünün boyutu mümkün olduğunca küçük olacak şekilde tüm gereksiz paketleri görüntüden kaldırır biri tarafından oluşturulmuş bir komut dosyası arıyorum.

Dediğim gibi her zaman görüntünün boyutunu küçültmeye çalışıyorum, ancak bundan sonra yarattığım her görüntünün mümkün olduğunca küçük olması için bunu tutarlı bir şekilde uygulamak istiyorum.

Soru

Her seferinde en küçük çalışan liman işçisi imajı nasıl oluşturulur?

Yanıtlar:


1

Tek bir çözüm olmadan çeşitli teknikler söz konusudur. Muhtemelen aşağıdakilerden birkaçını yapmak isteyeceksiniz:


İlk olarak, görüntü katmanlarınızı yeniden kullanmak üzere optimize edin. Önceki katmanlardan önceki katmanların önbelleğe alınma şansını artırmak için sık sık değişen adımları daha sonra Dockerfile'a koyun. Yeniden kullanılan bir katman a'da daha fazla disk alanı olarak görünecektir docker image ls, ancak alttaki dosya sistemini incelerseniz, her katmanın yalnızca bir kopyası diskte depolanır. Bu, her biri 2 GB'lık 3 resim anlamına gelir, ancak son birkaç katmanda yalnızca 50 MB farklı olan yapı, listenin sizden beri 6 GB kullandığını göstermesine rağmen, yalnızca 2,1 GB disk alanı kaplar. yeniden kullanılan katmanların her birini iki kez sayarak.

Katman yeniden kullanımı, nadiren değişen yapı bağımlılıklarına sahip görüntüleri kodda kopyalamadan önce ilk olarak yüklediklerini görmenizdir. Şuna benzer bir desene sahip herhangi bir python örneğine bakın:

FROM python
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
# note how the code is copied only after the pip install
# since code changes but requirements.txt doesn't
COPY . .
CMD ["gunicorn", "app:app"]

Minimum bir temel görüntü seçin. İnsanların gelen gittiğini görmek nedeni budur ubuntuiçin debian:slim(ince varyantları az araçlarla nakliye, küçüktür), hatta alpine. Bu, başlangıç ​​noktanızın boyutunu azaltır ve temel görüntünün sürekli yeni sürümlerini çekiyorsanız çok yardımcı olur. Ancak, temel görüntünüz nadiren değişirse katman yeniden kullanımı, minimum temel görüntünün avantajlarının çoğunu kaldırır.

Seçebileceğiniz en küçük temel görüntü scratch, hiçbir şey, kabuk veya kitaplık değildir ve yalnızca statik olarak derlenmiş ikili dosyalarda kullanışlıdır. Aksi takdirde, çok fazla araca ihtiyaç duymadan ihtiyacınız olan araçları içeren bir temel görüntü seçin.


Daha sonra, bir dosyayı değiştiren veya silen herhangi bir adım, o dosyayı oluşturan önceki adımlarla birleştirilmelidir. Aksi takdirde, dosya izni değişikliği gibi şeylerde bile yazma üzerine kopyalama kullanan katmanlı dosya sistemi, önceki dosyadaki orijinal dosyaya sahip olur ve dosyaları kaldırdığınızda görüntü boyutu küçülmez. Bu nedenle rmkomutlarınızın sonuçta ortaya çıkan disk alanı üzerinde hiçbir etkisi yoktur. Bunun yerine, komutları aşağıdaki gibi zincirleyebilirsiniz:

RUN apt-get update \
 && apt-get install -y \
      a-package \
      wget \
 && ... \
 && apt-get purge -y wget \
 && rm -r a-build-dir \
 && apt-get purge -y a-package

Önkoşul her değiştiğinde aynı araç setini yeniden yüklemeniz gerektiğinden, komut zincirinin aşırı kullanılmasının yapılarınızı yavaşlatabileceğini unutmayın (örn. Wget ile alınan kod). Daha iyi bir alternatif için aşağıdaki çok aşamalı bölüme bakın.


Oluşturduğunuz görüntüde ihtiyacınız olmayan oluşturduğunuz tüm dosyalar, onu oluşturan adımda silinmelidir. Bu, paket önbelleklerini, günlükleri, man sayfalarını vb. İçerir. Her katmanda hangi dosyaların oluşturulduğunu keşfetmek için wagoodman / dive gibi bir araç kullanabilirsiniz (ki ben kişisel olarak denetlemedim ve tam kök erişimi ile çalıştığı için dikkat göstereceğim) veya barındırıcı görüntülerinizi ara kapları budanmadan oluşturup ardından farkı şununla görüntüleyebilirsiniz:

# first create and leave containers from any RUN step using options on build
docker image build --rm=false --no-cache -t image_name . 
# review which layers use an unexpectedly large amount of space
docker image history image_name
# list all containers, particularly the exited ones from above
docker container ps -a 
# examine any of those containers
docker container diff ${container_id} 
# ... repeat the diff for other build steps
# then cleanup exited containers
docker container prune

Bu ara kapların her biriyle, fark dosyaları eklenebilir, değiştirilebilir veya bu aşamada silinir neyi gösterecek (bunlar ile gösterilir A, Cya da Dher dosya önce). Farkı gösteren, konteynere özel yazma / yazma dosya sistemidir; bu, konteynır tarafından yazma üzerine kopyalama kullanılarak görüntü durumundan değiştirilen herhangi bir dosyadır.


Görüntü boyutunu azaltmanın en iyi yolu, derleyiciler gibi gereksiz bileşenleri gönderilen görüntünüzden kaldırmaktır. Bunun için, çok aşamalı derlemeler tek bir aşamada derlemenize izin verir ve sonra yalnızca elde edilen yapay nesneleri derleme aşamasından uygulamayı çalıştırmak için gereken minimum değere sahip bir çalışma zamanı görüntüsüne kopyalar. Bu, sonuçta elde edilen görüntü ile birlikte gönderilmedikleri için oluşturma adımlarından herhangi birini optimize etme ihtiyacını ortadan kaldırır.

FROM debian:9 as build
# still chain update with install to prevent stale cache issues
RUN apt-get update \
 && apt-get install -y \
      a-package \
      wget \
RUN ... # perform any download/compile steps

FROM debian:9-slim as release
COPY --from=build /usr/local/bin/app /usr/local/bin/app
CMD [ "/usr/local/bin/app" ]

Çok aşamalı, temel görüntünüz olarak sıfırdan çalıştırabileceğiniz veya JDK gibi bir derleme ortamından JRE gibi bir çalışma süresine geçiş yapabileceğiniz statik olarak derlenmiş ikili dosyalar için idealdir. Bu, hızlı yapılara sahipken görüntü boyutunuzu önemli ölçüde azaltmanın en kolay yoludur. Önceki adımlarda oluşturulan dosyaları değiştiren veya silen adımlarınız varsa, yayın aşamanızdaki adımların zincirlenmesini yine de yapabilirsiniz, ancak çoğunlukla COPYbaşka bir aşamadan, yayınlama aşamasını önceki oluşturma aşamalarında yaşanan herhangi bir katman şişmesinden yalıtır.


Not: Katmanların yeniden kullanılmasını ortadan kaldırmak pahasına bir görüntünün boyutunu küçülttüğü için görüntüleri ezmeyi önermiyorum. Bu, aynı görüntünün gelecekteki derlemelerinin güncellemeleri göndermek için daha fazla disk ve ağ trafiği gerektireceği anlamına gelir. İlk örneğe geri dönmek için, ezme resminizi 2 GB'tan 1 GB'a düşürebilir, ancak 3 GB 2,1 GB yerine 3 GB alabilir.


25

A Dockerfile, dosyadaki komutların her biri için yeni bir katman oluşturur. Katmanlar iyi olduğundan, üst üste katmanlı olduğundan, önceki katmanın eklediği dosyaları kaldıramazsınız. Bu nedenle, paketleri yüklediğinizde veya dosya indirdiğinizde veya her birini ayrı bir komutta derlemeler oluşturduğunuzda - gelecekteki bir katmanda kaldırmış olsanız bile, bunlar hala görüntüde bulunur.

Eğer bunu değiştirirseniz:

RUN apt-get update -y
RUN apt-get install -y wget a-package
# ...
RUN apt-get purge -y wget
RUN rm -r a-build-dir
RUN apt-get purge -y a-package

Buna:

RUN apt-get update -y \
    && apt-get install -y wget a-package \
    && mkdir a-build-dir \
    && wget http://some-site/very-big-source-code.tar.gz \
    && tar xzvf very-big-source-code.tar.gz \
    && do-some-compilation \
    && apt-get purge -y wget \
    && cd .. \
    && rm -rf a-build-dir \
    && apt-get purge -y a-package

Çok daha küçük bir görüntü elde edersiniz.


Başka bir seçenek de, görüntüyü oluşturduktan sonra ezmektir . S: Yeni nasıl docker --squashçalışır?


Yine başka bir seçenek, ince bir temel görüntü seçmektir. Örneğin, Debian yerine temel olarak Alpine Linux kullanan görüntüler 180-250mb yerine sadece 10-15mb alır. Bu, kendi uygulamanızı ve verilerinizi eklemeden önce. Docker Hub'daki birçok resmi temel resim, alpin bir versiyona sahiptir.


3
2.37vs.1.47 GB
030

4

Muhtemelen tam olarak bir cevap değil, alternatifler vermeye değer.

Şef'in yaşam alanı , bu düşünülerek yaratıldı, istemediğiniz yabancı dağıtım / temel görüntü yükü olmadan gerekli tüm bağımlılıklara sahip bir paket oluşturdu.

Burada önemli olan şeyleri, basit bir nodejs uygulamasıyla bu blog gönderisinden konteyner boyutunu çıkarır:

michael@ricardo-2:plans_pkg_part_2$ docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
mfdii/node-example   latest              36c6568c606b        40 minutes ago      655.9 MB
node                 latest              04c0ca2a8dad        16 hours ago        654.6 MB
mfdii/mytutorialapp  latest              534afd80d74d        2 minutes ago       182.1 MB

mdfii/node-exampleklasik bir dockerfile'dan bir liman mfdii/mytutorialappişçisi görüntüsüdür.

Boyut ana endişenizse ve Habitat planlarının öğrenme eğrisini almaya hazırsanız, bu sizin için bir çözüm olabilir.


0

Ayrıca dalış kullanabilirsiniz

docker run --rm -it \
    -v /var/run/docker.sock:/var/run/docker.sock \
    wagoodman/dive:latest <dive arguments...>

boyutu küçültmek için bir docker görüntüsünden hangi atıkların çıkarılabileceğine dair bir rapor almak için.


0

Yeniden kullanılabilir geliştirme katmanlarına sahip olmak, ancak dağıtım için disk kullanımınızı azaltmak istiyorsanız, bunun gibi birleştirilmiş bir "dağıtım katmanı" oluşturabilirsiniz:

  1. Resminizi kullanan bir kapsayıcınız olduğundan emin olun (eğer docker run IMAGE echoyoksa, echo komutu varsa)
  2. Kapsayıcı kimliğini bulma (belki de kullanarak docker container ls -l)
  3. Boru docker exportiçin docker importbirleştirilmiş katman oluşturmak için (böyle bir şey docker export 20f192c6530a | docker import - project:merged)

Bu, geliştirme katmanlarınızı koruyacak, ancak size sunabileceğiniz daha küçük, birleştirilmiş bir görüntü verecektir.



0

basit .. docker ps mevcut çalışan görüntüleri kontrol .. basit dosya örneği aşağıda ..

BAŞLANGIÇ ubuntu16

MAINTAINER sreeni (e-posta / alan adı)

Apt-get güncellemesini çalıştır

RUN apt-get install -y nginx

ENTRYPOINT [“/ usr / sbin / nginx”, ”- g”, ”arka plan programı kapalı;”]

EXPOSE 80 (bağlantı noktası)

basit docker dosyası ...

aşağıdaki docker komutunu kullan

docker run -d -p 80:80 - bundan sonra isim web sunucusu ubuntu16 (resim adı) localhost veya ip adresini kontrol et: 80 (tarayıcıyı aç ve kontrol et)


1
lütfen cevabınızın biçimlendirmesini düzeltin ...
Pierre.Vriens
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.