Docker Scout'un erken erişim sürümüyle birlikte Docker Hub nihayet görüntünün dahili öğelerini görselleştirmeye başlıyor. Bu harika! Docker Hub bunu yıllar önce neden yapmadı? İş modeli nedeniyle.
Daha ileri gitmeden önce Docker görsellerinin nelerden oluştuğunu kısaca gözden geçirelim.
Komut satırında docker pull
komutunu çalıştırarak bir Docker görüntüsü indirdiğinizde Docker CLI, görüntüyü çekerken her katmanın indirme ilerlemesini görüntüler. Daha önce bir Docker görüntüsü indirdiyseniz muhtemelen şunu görmüşsünüzdür:
Daha önce Docker ile çalıştıysanız muhtemelen bu katmanlardan bazılarını kendi görselleriniz için tanımlamışsınızdır. Geliştiriciler Dockerfiles yazdıklarında bu katmanları örtülü olarak tanımlarlar. Örneğin, bu Docker dosyasındaki her satır bir katman oluşturur:
FROM ubuntu:22.04 # install apt dependencies RUN apt-get update RUN apt-get install -y iputils-ping python3 python3-pip # install python dependencies RUN pip3 install numpy # cleanup apt lists RUN rm -rf /var/lib/apt/lists/* CMD ["/bin/bash"]
Katmanlar arşivlenmiş Linux dizinleridir; dosya sistemi tarball'larıdır. Docker, tüm görüntü katmanlarınızı indirir ve her birini ayrı bir dizine açar. docker run
komutunu kullanarak bir Docker görüntüsünden bir kapsayıcı başlattığınızda, Docker arka plan programı, bir kapsayıcı oluşturmak için görüntü katmanlarını birleştirir.
Docker'ın bir ürün olarak katma değerinin çoğu, bu ayrıntıları soyutlayarak kullanıcıların, nasıl çalıştıklarını düşünmeden katmanlı konteynerlerin avantajlarından yararlanmasına olanak sağlamasıdır. Ancak tüm soyutlamalar sızdırılıyor ve Docker da bir istisna değil; bazen perdeyi geri çekmeniz gerekir.
Docker görüntü katmanları, konteynerin dosya sisteminde bulunan her ikili dosyanın başlangıç öyküsünü içerir. Docker görüntüsündeki ilk satır "FROM satırıdır". Dockerfile'ın üzerine oluşturduğu Docker görüntüsünü (ve dolayısıyla görüntü katmanlarını) tanımlar.
Geliştiriciler, geçerli Dockerfile'daki katmanları ve ana görüntü zincirindeki katmanları inceleyerek, bir konteynerin kök dosya sistemindeki her dosyanın nereden geldiğini belirleyebilir. Bu çok değerli bir bilgidir. Geliştiricilere yardımcı olur:
Docker görüntü sürümleri genelinde dosya değişikliklerini izlemek için bir görselleştirmedeki katmanlara tıkladığınızı hayal edin. Otomatik bir güvenlik taraması görüntülerinizden birinde bir güvenlik açığı tespit ettiğinde, güvenlik açığının nasıl ortaya çıktığını belirlemek için bir katman inceleme aracı kullandığınızı hayal edin.
Aşırı görsel boyutları şirketlere çok pahalıya mal olabilir. Birçok CI/CD işlem hattı, her çekme isteği için Docker görüntülerini çeker, bu nedenle uzun Docker görüntüsü indirme işlemleri işlem hatlarını yavaşlatabilir, geliştiricilerin daha az verimli olmasına ve CPU zamanının boşa harcanmasına neden olabilir. Kuruluşlar altyapı maliyetlerini genellikle saatlik olarak ödediklerinden, boşa harcanan her saat gereksiz bir harcamadır.
Boşa harcanan bilgi işlem kaynaklarının ötesinde, şişirilmiş Docker görüntüleri aşırı ağ aktarım maliyetlerine yol açabilir. Bir kuruluş, Docker görüntülerini AWS bölgeleri genelinde veya AWS'den açık internete indirirse, Docker görüntü şişkinliği doğrudan altyapı harcamalarının boşa harcanması anlamına gelir. Bu hızlı bir şekilde eklenir.
Docker görüntü katmanlarınıza yanlışlıkla şişkinlik eklemek kolaydır. Daha önce gösterilen Docker dosyası klasik bir örnek içerir; 4. satırdaki katman, diske 40 MB dosya kaydeder ve bunlar daha sonra 11. satırdaki katman tarafından silinir. Docker görüntülerinin çalışma şekli nedeniyle bu veriler hâlâ görüntünün bir parçasıdır. 40MB gereksiz resim boyutu.
Bu basit bir örnek; aslında doğrudan Docker'ın belgelerinden alınmıştır. Daha karmaşık Docker dosyalarında bu hatanın fark edilmesi çok daha zor olabilir.
Docker görüntü katmanlarıyla komut satırını kullanarak etkileşim kurmak zor olabilir, ancak Docker Scout yakın zamanda piyasaya sürülmeden önce, en son teknolojiyi bulabileceğiniz yer komut satırıydı. İşte iki temel yaklaşım.
Bu, gösterişten uzak, kendin yap Unix yöntemidir. İhtiyacınız olan tek şey Docker arka plan programını çalıştıran bir ana bilgisayardır. Bu basit bir yaklaşım:
docker create
komutunu çalıştırın.docker inspect
kullanın.cd
yazın ve kafanızdaki katmanlarla ilgili nedenleri belirtin.
Bu bir güçlük. Birkaç aydır kullandığımız ancak son zamanlarda boyutu önemli ölçüde büyüyen bir Docker görüntüsündeki bazı görüntü şişkinliklerini bulmaya çalıştığımızı varsayalım.
İlk olarak görselden bir konteyner oluşturuyoruz:
where-the@roadmap-ends ~ $ docker create --name example where-the-roadmap-ends 339b8905b681a1d4f7c56f564f6b1f5e63bb6602b62ba5a15d368ed785f44f55
Daha sonra docker inspect
, indirilen görüntünün katman dizinlerinin dosya sistemimizde nerede bulunduğunu bize bildirir:
where-the@roadmap-ends ~ $ docker inspect example | grep GraphDriver -A7 "GraphDriver": { "Data": { "LowerDir": "/var/lib/docker/overlay2/1c18bd289d9c3f9f0850e301bf86955395c312de3a64a70e0d0e6a5bed337d47-init/diff:/var/lib/docker/overlay2/wbugwbg23oefsf678r7anbn4f/diff:/var/lib/docker/overlay2/j0dekt7y8xgix11n0lturmf8t/diff:/var/lib/docker/overlay2/zd57mz6l4zrsjk9snc2crphfq/diff:/var/lib/docker/overlay2/83za1pmv9xri44tddzyju0usm/diff:/var/lib/docker/overlay2/8c639b22627e0ad91944a70822b442e5bff848968263a37715a293a15483c170/diff", "MergedDir": "/var/lib/docker/overlay2/1c18bd289d9c3f9f0850e301bf86955395c312de3a64a70e0d0e6a5bed337d47/merged", "UpperDir": "/var/lib/docker/overlay2/1c18bd289d9c3f9f0850e301bf86955395c312de3a64a70e0d0e6a5bed337d47/diff", "WorkDir": "/var/lib/docker/overlay2/1c18bd289d9c3f9f0850e301bf86955395c312de3a64a70e0d0e6a5bed337d47/work" }, "Name": "overlay2"
Bu inceleme için bakmak istediğimiz katmanlar "LowerDir" dizinlerinin listesidir. Diğer dizinler Docker görüntüsünün bir parçası değildir; onları görmezden gelebiliriz.
Böylece, komut satırında "LowerDir" dizinlerinin listesini ayrıştırıyoruz:
where-the@roadmap-ends ~ $ docker inspect example | grep GraphDriver -A7 | grep LowerDir | awk '{print $2}' | sed 's|"||g' | sed 's|,||g' | sed 's|:|\n|g' /var/lib/docker/overlay2/1c18bd289d9c3f9f0850e301bf86955395c312de3a64a70e0d0e6a5bed337d47-init/diff /var/lib/docker/overlay2/wbugwbg23oefsf678r7anbn4f/diff /var/lib/docker/overlay2/j0dekt7y8xgix11n0lturmf8t/diff /var/lib/docker/overlay2/zd57mz6l4zrsjk9snc2crphfq/diff /var/lib/docker/overlay2/83za1pmv9xri44tddzyju0usm/diff /var/lib/docker/overlay2/8c639b22627e0ad91944a70822b442e5bff848968263a37715a293a15483c170/diff
Bunlar, en alttaki katman ilk sırada olacak şekilde görüntüdeki katmanların listesidir. Şimdi bu katman dizinlerini, onları üreten Dockerfile satırlarıyla manuel olarak ilişkilendirmemiz gerekiyor.
Maalesef Docker bize bu satırları Docker görüntüsünden doğrudan çıkarmamız için bir yol sunmuyor; docker history
kullanarak elde edebileceğimiz en iyi şey bu:
where-the@roadmap-ends ~ $ docker history where-the-roadmap-ends IMAGE CREATED CREATED BY SIZE COMMENT 6bbac081b2a7 2 hours ago CMD ["/bin/bash"] 0B buildkit.dockerfile.v0 <missing> 2 hours ago RUN /bin/sh -c rm -rf /var/lib/apt/lists/* #… 0B buildkit.dockerfile.v0 <missing> 2 hours ago RUN /bin/sh -c pip3 install numpy # buildkit 70MB buildkit.dockerfile.v0 <missing> 2 hours ago RUN /bin/sh -c apt-get install -y iputils-pi… 343MB buildkit.dockerfile.v0 <missing> 2 hours ago RUN /bin/sh -c apt-get update # buildkit 40.1MB buildkit.dockerfile.v0 <missing> 8 months ago /bin/sh -c #(nop) CMD ["bash"] 0B <missing> 8 months ago /bin/sh -c #(nop) ADD file:550e7da19f5f7cef5… 69.2MB
Bu çıktıyı kullanarak, hangi katmanların dizinlere sahip olduğunu ve katmanı hangi Dockerfile komutunun oluşturduğunu (CREATED BY sütununda gösterilir) belirleyebiliriz.
docker history
komutu, konteynerinizdeki katmanları, docker inspect
katman dizinlerini listelediği sırayla çıkarır. Bunu bilerek, hangi katmanların diğerlerinden daha büyük olduğunu, bunları hangi Dockerfile komutunun oluşturduğunu ve her katmanı hangi dizinin içerdiğini görmek için iki çıkışı manuel olarak birleştirebiliriz.
İşte apt-get update
gerçekleştiren Katman A'nın içeriği:
where-the@roadmap-ends ~ $ du -hs /var/lib/docker/overlay2/83za1pmv9xri44tddzyju0usm/diff/var/lib/apt/lists 38.2M /var/lib/docker/overlay2/83za1pmv9xri44tddzyju0usm/diff/var/lib/apt/lists
Katman A'dan kalan dosyaları silen B katmanının içeriğiyle karşılaştırıldığında:
where-the@roadmap-ends ~ $ du -hs /var/lib/docker/overlay2/wbugwbg23oefsf678r7anbn4f/diff/var/lib/apt/lists 4.0K /var/lib/docker/overlay2/wbugwbg23oefsf678r7anbn4f/diff/var/lib/apt/lists
/var/lib/apt/lists
dizini her iki katmanda da bulunur, ancak Katman B'de dizin neredeyse hiç alan kullanmaz.
Bunun nedeni, katman B'nin dizininin, Docker'ın dosyaları son kapsayıcı dosya sisteminden hariç tutulacak şekilde işaretlemek için kullandığı "beyazlatma dosyaları" içermesidir.
Bu nedenle, dosyalar Katman B'de "silinmiş" olsa da, bunlar hala Katman A'da mevcuttur ve dolayısıyla görüntünüzün genel boyutuna katkıda bulunur; 38,2 MB gereksiz şişkinlik.
Peki bu kadar kolay değil miydi? 😉
Manuel yöntem o kadar karmaşık ve kullanışsız ki, açık kaynak topluluğu bu görev için özel olarak bir araç geliştirdi; buna dive
adı verildi. Dive, bir görüntüyü girdi olarak alan, dosya sistemlerini ayrıştıran ve terminalinizde metin tabanlı etkileşimli bir kullanıcı arayüzü sunan bir CLI aracıdır. Görüntü katmanlarını sizin için ilişkilendirerek katman dizinlerini daha kolay incelemenizi sağlar.
Yukarıdaki Docker dosyasından Docker görüntüsüne karşı çalıştırıldığında şöyle görünür:
┃ ● Layers ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │ Aggregated Layer Contents ├─────────────────────────────────────────────────────────────────────────────── Cmp Size Command └── var 69 MB FROM acee8cf20a197c9 └── lib 40 MB RUN /bin/sh -c apt-get update # buildkit └── apt 343 MB RUN /bin/sh -c apt-get install -y iputils-ping python3 python3-pip # buildkit └── lists 70 MB RUN /bin/sh -c pip3 install numpy # buildkit ├── auxfiles 0 B RUN /bin/sh -c rm -rf /var/lib/apt/lists/* # buildkit ├── lock ├── partial │ Layer Details ├─────────────────────────────────────────────────────────────────────────────────────────── ├── ports.ubuntu.com_ubuntu-ports_dists_jammy-backports_InRelease ├── ports.ubuntu.com_ubuntu-ports_dists_jammy-backports_main_binary-arm64_Packages.lz4 Tags: (unavailable) ├── ports.ubuntu.com_ubuntu-ports_dists_jammy-backports_universe_binary-arm64_Packages.lz4 Id: 2bc27a99fd5750414948211814da00079804292360f8e2d7843589b9e7eb5eee ├── ports.ubuntu.com_ubuntu-ports_dists_jammy-security_InRelease Digest: sha256:6e6fb36e04f3abf90c7c87d52629fe154db4ea9aceab539a794d29bbc0919100 ├── ports.ubuntu.com_ubuntu-ports_dists_jammy-security_main_binary-arm64_Packages.lz4 Command: ├── ports.ubuntu.com_ubuntu-ports_dists_jammy-security_multiverse_binary-arm64_Packages.lz4 RUN /bin/sh -c apt-get update # buildkit ├── ports.ubuntu.com_ubuntu-ports_dists_jammy-security_restricted_binary-arm64_Packages.lz4 ├── ports.ubuntu.com_ubuntu-ports_dists_jammy-security_universe_binary-arm64_Packages.lz4 │ Image Details ├─────────────────────────────────────────────────────────────────────────────────────────── ├── ports.ubuntu.com_ubuntu-ports_dists_jammy-updates_InRelease ├── ports.ubuntu.com_ubuntu-ports_dists_jammy-updates_main_binary-arm64_Packages.lz4 Image name: where-the-roadmap-ends ├── ports.ubuntu.com_ubuntu-ports_dists_jammy-updates_multiverse_binary-arm64_Packages.lz4 Total Image size: 522 MB ├── ports.ubuntu.com_ubuntu-ports_dists_jammy-updates_restricted_binary-arm64_Packages.lz4 Potential wasted space: 62 MB ├── ports.ubuntu.com_ubuntu-ports_dists_jammy-updates_universe_binary-arm64_Packages.lz4 Image efficiency score: 90 % ├── ports.ubuntu.com_ubuntu-ports_dists_jammy_InRelease ├── ports.ubuntu.com_ubuntu-ports_dists_jammy_main_binary-arm64_Packages.lz4 Count Total Space Path ├── ports.ubuntu.com_ubuntu-ports_dists_jammy_multiverse_binary-arm64_Packages.lz4 2 28 MB /var/lib/apt/lists/ports.ubuntu.com_ubuntu-ports_dists_jammy_universe_binary-arm64_Pack ├── ports.ubuntu.com_ubuntu-ports_dists_jammy_restricted_binary-arm64_Packages.lz4 2 7.3 MB /usr/bin/perl └── ports.ubuntu.com_ubuntu-ports_dists_jammy_universe_binary-arm64_Packages.lz4 2 4.4 MB /usr/lib/aarch64-linux-gnu/libstdc++.so.6.0.30 2 2.9 MB /var/lib/apt/lists/ports.ubuntu.com_ubuntu-ports_dists_jammy_main_binary-arm64_Packages 2 2.0 MB /var/lib/apt/lists/ports.ubuntu.com_ubuntu-ports_dists_jammy-updates_main_binary-arm64_ 2 1.7 MB /var/lib/apt/lists/ports.ubuntu.com_ubuntu-ports_dists_jammy-updates_universe_binary-ar
Dalış harika bir araçtır ve var olmasına sevindim ama bazen yetersiz kalıyor. Metin tabanlı arayüzler kullanımı en kolay arayüzler değildir; bazen Grafana top
daha hoştur.
Ayrıca büyük görüntüler Dive'ın yeteneklerini aşabilir. Büyük görüntüleri incelerken, Dive çok fazla bellek tüketir; bazen çekirdek, herhangi bir veri çıkışı yapmadan önce Dive işlemini sonlandırabilir.
Bir geliştiricinin bakış açısına göre, Docker görüntü katmanı görselleştirmelerinin Docker Hub'da mevcut olmasını beklemek her zaman mantıklı olmuştur. Sonuçta Docker görüntü verilerimiz zaten Docker Hub'ın arka ucunda bulunuyor.
Sık sık tarayıcımdaki Docker görüntüsünün iç kısımlarını şuna benzeyen bir kullanıcı arayüzü kullanarak incelediğimi hayal ettim:
Docker Scout ile Docker'ın şirket olarak bu yönde ilerlediği görülüyor. Bugün Docker Hub'daki en son Postgres görüntüsüne gittiğimde şununla karşılaşıyorum:
Bir geliştirici olarak bu heyecan verici. Bu yeni kullanıcı arayüzü, görüntü katmanı ayrıntılarına görsel olarak göz atmamı, güvenlik açığını ve görüntü boyutu sorunlarını tam istediğim gibi vurgulamamı sağlıyor.
Docker Hub ilk piyasaya sürüldüğünde iki tür kullanıcıya sahipti:
Ve Docker'ın bu iki tür kullanıcıya farklı şekilde yaklaşması gerekiyordu.
Docker 2013'te piyasaya çıktıktan sonra geliştiriciler hemen ürünlerini kullanmak istedi. Docker konteynerleri herkesin yazılımının paketlenmesini ve dağıtımını standart hale getirir. Konteynerler yazılım geliştirici topluluğunda hızla popüler hale geldi.
Ancak yazılım yayıncıları daha tereddütlüydü. Neden yazılımlarını, temel faydası yazılım ürünleri arasındaki farklılığı ortadan kaldırmak olan bir platforma yüklemeliler?
Docker Hub'ın başarılı olabilmesi için Docker'ın onları kazanması gerekiyordu. Bu nedenle Docker Hub'ın tasarımı ve özellik seti, geliştiricilerin ilgisini çekmeye odaklanmak yerine yazılım yayıncılarının ihtiyaçlarını karşıladı.
Yayıncılar için Docker Hub bir pazarlama sitesiydi. Onlara ürünlerinin reklamını yapabilecekleri bir alan sağladı. Araba bayilerinin motor bloklarını sökmenize izin vermemesi gibi, geliştiricilerin de Docker görüntüsünün dahili ayrıntılarını görmesine izin vermedi. İç mühendislik detayları sergilenmiyordu, gizleniyordu, bu nedenle alışveriş yapanlar ürünlerin nasıl yapıldığına değil, ürünlerin kendisine odaklanıyordu.
Docker Hub, görüntü boyutu optimizasyonu ve tedarik zinciri iç gözlemi için geliştiricilere yönelik özelliklerden yoksundu çünkü Docker, bu özelliklere sahip olmayan geliştiricilerin desteğini zaten kazandı. Aslında bu özelliklerin yazılım yayıncılarını kötü gösterme eğilimi vardır ve onlar Docker Hub'ın başarılı olmak için hâlâ kazanması gereken kullanıcılardı.
Hem yazılım yayıncılarına hem de geliştiricilere hizmet vermenin bu dinamiği, Docker Hub'ı iki taraflı bir platform haline getirdi.
İki taraflı platformlar, iki farklı kullanıcı kategorisine sahip olan ve işlerin yürümesi için her ikisinin de platforma katılmasına ihtiyaç duyan işletmelerdir. Genellikle kullanıcıları farklı gruplara ayıran şey platformu kullanma motivasyonudur.
İki kullanıcı grubu birbirleriyle doğrudan işlem yapmasa da, iki taraflı platformlar pazarlara benzer; satıcılar satış yapmak için gelmedikçe ve alışveriş yapanlar satın almak için gelmedikçe değer yaratmazlar.
Teknoloji endüstrisinde iki taraflı platformlar her yerde mevcuttur. Başarılı olduklarında bu iş modelleri, işletmeleri sürdürülebilir büyüme ve kârlılığa yönlendiren ağ etkileri üretme eğilimindedir. Belirli bir noktadan sonra platformun boyutu ve mekandaki yerleşik konumu yeni kullanıcıları platforma çekmektedir.
Ne aradığınızı öğrendikten sonra iki taraflı platformları fark etmek kolaydır. İşte üç örnek.
LinkedIn'de iki tür kullanıcı vardır: çalışanlar ve işe alım yöneticileri. Her iki grup da farklı nedenlerle katılıyor; çalışanlar iş istiyor ve işe alım yöneticileri insanları işe almak istiyor.
Diğer grup katılmaya başlayıncaya kadar hiçbir grup siteden istediğini alamamıştı. Her gruptan yeterli sayıda üye kaydolduktan sonra, her iki grubun da yeni üyelerinin bulunacağı varsayılan yer haline geldi ve sitenin büyümesi, Microsoft tarafından 26 milyar dolara satın alınıncaya kadar devam etti.
YouTube'da içerik oluşturucular var ve izleyiciler var. İzleyiciler siteye videoları görmek için gelirler; içerik oluşturucular iyi hisler, şöhret ve servet peşinde sitede yayınlarlar.
YouTube, içerik oluşturucuların başarılı olabileceği bir yer olarak ün kazandıktan sonra, giderek daha fazla içerik oluşturucu ortaya çıktı ve onlar daha fazla içerik ürettikçe daha fazla izleyici ziyarete geldi. Platform belirli bir boyutun üzerine çıktığında içerik oluşturucuların ve izleyicilerin onu kullanmaya devam etmekten başka seçeneği kalmadı; her grubun diğerine ihtiyacı vardı ve birbirlerini yalnızca YouTube aracılığıyla bulabildiler.
Docker Hub'ın alakalı olması için yazılım yayıncılarının görüntüleri yüklemesi ve geliştiricilerin bunları indirmesi gerekiyordu. Yeterli sayıda yayıncı Docker Hub'a görsel gönderdikten sonra, burası geliştiricilerin yararlanabileceği varsayılan yer haline gelecekti. Platform büyümeye devam ettikçe Docker Hub, hepsine hükmedecek tek kayıt defteri olarak hakimiyetini güçlendirecekti.
En azından plan buydu. Gerçekte Docker (şirket) reddedildi ve Docker Hub hiçbir zaman "tek" olmadı. İki taraflı bir platform oluştururken startup'ların tek bir ürünü vardır, ancak ürün pazarına uygun olanı iki kez bulmaları gerekir. Docker için bu yük taşınamayacak kadar fazlaydı; sonunda Docker'ı ikiye böldü .
Docker, kurumsal işini sattıktan sonra artık abonelik hizmetini yalnızca geliştiricilere ve onların işverenlerine odaklayarak kendini yeniden keşfetti. Docker Hub artık iki taraflı bir platform değil, basit bir SaaS'tır; müşteriler, görüntülerini itmek ve çekmek karşılığında aylık bir ücret öderler.
Bu, hesabı değiştirir. Artık Docker'ın memnun edeceği bir "yayıncı" kullanıcı kişiliği yok; hepsi geliştiricilerin elinde. Docker Hub için bu, Docker Scout'un görüntü katmanı inceleme işlevselliğinin önünü açıyor. Uzaktan izleyenlerimiz için bu, bir startup'ın iş modeli ile sunduğu ürün arasındaki incelikli, temel bağlantıyı gösteriyor.