Docker görüntüleri, kapsayıcılarınızda gördüğünüz içeriği toplu olarak sağlayan birden çok katmandan oluşur. Ancak gerçekte katman nedir ve tam bir görüntüden farkı nedir?
Bu makalede, bu iki kavramı nasıl ayırt edeceğinizi ve farkın neden önemli olduğunu öğreneceksiniz. Katmanları tam olarak anlamadan Docker’ı kullanabilirsiniz, ancak bunların amaçlarının farkında olmak, optimizasyon fırsatlarını belirlemenize yardımcı olacaktır.
Resim Nedir?
Bir Docker “görüntüsü”, tutarlı kapların oluşturulabileceği bir şablon gibi davranır. Docker geleneksel bir sanal makine olsaydı, görüntü sanal makinenizi kurmak için kullanılan ISO’ya benzetilebilirdi. Docker, hem konsept hem de uygulama açısından VM’lerden farklı olduğu için bu sağlam bir karşılaştırma değildir, ancak yine de faydalı bir başlangıç noktasıdır.
Görüntüler, yeni kapsayıcıların ilk dosya sistemi durumunu tanımlar. Uygulamanızın kaynak kodunu ve bağımlılıklarını bir kapsayıcı çalışma zamanı ile kullanıma hazır, bağımsız bir pakette paketlerler. Görüntü içinde, dosya sistemi içeriği birden çok bağımsız katman olarak temsil edilir.
Katmanlar nedir?
Katmanlar, Docker görüntülerinin oluşturulma biçiminin bir sonucudur. Dockerfile’deki her adım, esasen son adımdan bu yana dosya sistemi değişikliklerinin bir farkı olan yeni bir “katman” oluşturur. Meta veri talimatları, örneğin LABEL
ve MAINTAINER
dosya sistemini etkilemedikleri için katmanlar oluşturmayın.
Bu görüntünün iki talimatı vardır (COPY
ve RUN
) böylece iki katman oluşturur:
FROM ubuntu:latest
COPY foo.txt /foo.txt
RUN date > /built-on.txt
- İlk adım kopyalar
foo.txt
dayalı yeni bir katmanaubuntu:latest
görüntü. - İkinci adım,
date
komut ve çıktısını bir dosyaya aktarır. Bu, öncekine dayanan ikinci bir katman oluşturur.
Oluşturmak foo.txt
çalışma dizininizde:
$ echo "Hello World" > foo.txt
Şimdi örnek görüntüyü oluşturun:
$ docker build . -t demo:latest
Sending build context to Docker daemon 2.56kB
Step 1/3 : FROM ubuntu:latest
---> df5de72bdb3b
Step 2/3 : COPY foo.txt /foo.txt
---> 4932aede6a15
Step 3/3 : RUN date > /built-on.txt
---> Running in 91d260fc2e68
Removing intermediate container 91d260fc2e68
---> 6f653c6a60fa
Successfully built 6f653c6a60fa
Successfully tagged foo:latest
Her derleme adımı, oluşturulan katmanın kimliğini yayar. Son adımın katmanı son görüntü olur, böylece etiketlenir foo:latest
.
Sıra bunu ortaya koyuyor katmanlar geçerli Docker görüntüleridir. “Katman” terimi normalde etiketli bir görüntüye atıfta bulunmak için kullanılmasa da, tüm etiketli görüntüler teknik olarak yalnızca bir tanımlayıcı atanmış katmanlardır.
Bir ara katmanın görüntüsünden bir kapsayıcı başlatabilirsiniz:
$ docker run -it 4932aede6a15 sh
# cat /foo.txt
Hello World
# cat /built-on.txt
cat: /built-on.txt: No such file or directory
Bu örnek, ikinci oluşturma adımı tarafından oluşturulan katmandan bir kapsayıcı başlatır. foo.txt
kapta mevcut ama built-on.txt
yok çünkü üçüncü adıma kadar eklenmedi. Bu dosya yalnızca sonraki katmanların dosya sistemlerinde bulunur.
Katmanların Rolü
Katmanlar, Dockerfile’deki önceki katmana göre bir derleme adımı tarafından oluşturulan değişiklikleri içerir. FROM
talimatlar, mevcut bir görüntünün son katmanına başvuran özel bir durumdur.
Katmanlar, gereksiz çalışmayı önlemek için derleme adımlarının önbelleğe alınmasına izin verir. Docker, önceden oluşturulmuş katmanı yeniden kullanarak Dockerfile’nizdeki değişmeyen talimatları atlayabilir. Yeni bir tane oluşturmak yerine bir sonraki adımı mevcut katmana dayandırır.
Bunu, Dockerfile’ınızı aşağıdaki gibi değiştirerek görebilirsiniz:
FROM ubuntu:latest
COPY foo.txt /foo.txt
RUN date +%Y-%m-%d > /built-on.txt
Üçüncü inşa adımı değişti. Şimdi imajınızı yeniden oluşturun:
$ docker build . -t demo:latest
Sending build context to Docker daemon 3.584kB
Step 1/3 : FROM ubuntu:latest
---> df5de72bdb3b
Step 2/3 : COPY foo.txt /foo.txt
---> Using cache
---> 4932aede6a15
Step 3/3 : RUN date +%Y-%m-%d > /built-on.txt
---> Running in 2b91ec0462c4
Removing intermediate container 2b91ec0462c4
---> c6647ff378c1
Successfully built c6647ff378c1
Successfully tagged demo:latest
İkinci inşa adımı şu şekilde gösterilir: Using cache
ve aynı katman kimliğini üretir. Docker, daha önce oluşturulduğu için bu katmanı oluşturmayı atlayabilir ve foo.txt
ilk yapımdan beri değişmedi.
Bu önbelleğe alma, yalnızca bir katmanın değiştirildiği noktaya kadar çalışır. Bu katmandan sonraki tüm adımların da yeni dosya sistemi revizyonunu temel almaları için yeniden oluşturulması gerekecek.
Katmanlar ve Çekme İşlemleri
Katmanların bir başka yararı, kısmi görüntü çekmelerini nasıl etkinleştirdikleridir. Makinenize birkaç görüntü indirdikten sonra, genellikle yeni çekimlerin zaten sahip olduğunuz bazı katmanları atlayabileceğini göreceksiniz. Bu görüntü 13 katman içeriyor, ancak çekme işlemiyle yalnızca altı tanesinin indirilmesi gerekiyordu:
docker pull php:8.0-apache
8.0-apache: Pulling from library/php
7a6db449b51b: Already exists
ad2afdb99a9d: Already exists
dbc5aa907229: Already exists
82f252ab4ad1: Already exists
bf5b34fc9894: Already exists
6161651d3d95: Already exists
cf2adf296ef1: Already exists
f0d7c5221e44: Pull complete
f647198f6316: Pull complete
c37afe1da4e5: Pull complete
09c93531cbca: Pull complete
fef371007dd3: Pull complete
52043dbb1c06: Pull complete
Digest: sha256:429889e8f9eac0a806a005b0728a004303b0d49d77b09496d39158707abd6280
Status: Downloaded newer image for php:8.0-apache
docker.io/library/php:8.0-apache
Diğer katmanlar, yeniden kullanılabilmeleri için Docker ana bilgisayarında zaten mevcuttu. Bu, performansı artırır ve ağ bant genişliğinin boşa harcanmasını önler.
Görüntü Katmanlarını İnceleme
çalıştırarak bir görüntüdeki katmanları listeleyebilirsiniz. docker image history
emretmek. Her katman, oluşturulan görüntünün kimliğini ve değişikliğe neden olan Dockerfile komutunu görüntüler. Katman içindeki içeriğin toplam boyutunu da görebilirsiniz.
$ docker image history
IMAGE CREATED CREATED BY SIZE COMMENT
6f653c6a60fa 4 minutes ago /bin/sh -c date > /built-on.txt 29B
f8420d1a96f3 4 minutes ago /bin/sh -c #(nop) COPY file:a5630a7506b26a37... 0B
df5de72bdb3b 4 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 4 weeks ago /bin/sh -c #(nop) ADD file:396eeb65c8d737180... 77.8MB
Son katman olarak görüntülenir <missing>
içindeki bir katmana atıfta bulunduğundan ubuntu:latest
temel görüntü. Bu, yerel olarak kullanılamaz, çünkü yalnızca temel görüntünün son katmanı (df5de72bdb3b
) oluşturma sırasında aşağı çekilir. Belirli bir görüntüyü kullanmak istediğinizde tüm ara katmanları bağımsız olarak çekmenize gerek yoktur.
Özet
Docker görüntüleri ve katmanları genellikle birbirinin yerine kullanılabilen terimlerdir. Katman bir görüntüdür ve bir veya daha fazla katmandan bir görüntü oluşturulur. En büyük fark etiketlerde yatmaktadır: bir görüntü etiketlenecek ve son kullanıcılar için tasarlanacaktır, “katman” terimi normalde bir oluşturma işleminin parçası olarak oluşturulan etiketlenmemiş ara görüntüleri ifade eder. Onları aramaya gitmedikçe bunlar görünmez.
Katmanlarla ilgili bir konu daha var: çalışan kapsayıcılar, görüntülerinin üzerine fazladan yazılabilir bir katman ekler. Kapsayıcının görüntüsünden kaynaklanan katmanlar salt okunurdur, bu nedenle kapsayıcı tarafından yapılan dosya sistemi değişiklikleri, geçici yazılabilir katmanını hedefler. Kapsayıcı durdurulduğunda veya silindiğinde yazılabilir katman atılır.