deniz.in

Piyasalar

Hava durumu

Hava durumu yükleniyor

· kaynak dev.to (home feed)

containerd 2.2'nin mount manager'ı tek mount'luk Activate zincirlerinde panikliyor

containerd 2.2'nin yeni mount manager'ı üzerinde yapılan bir dev.to pratik testi, tek mount'luk aktivasyonlarda bir panik, yanıltıcı hata tipleri ve Activate'in, yerini aldığı manuel mkfs ve losetup yolundan daha yavaş çalışması gibi bulgulara ulaştı.

containerd 2.2'nin mount manager'ı tek mount'luk Activate zincirlerinde panikliyor

Tek çağrılık provisioning yolu

containerd 2.2, bir mount manager ile geldi: bir dosya oluşturabilen, onu ext4 veya xfs olarak formatlayabilen, bir loopback cihazı olarak bağlayabilen ve sonucu bir runtime'a teslim edebilen, gömülebilir bir servis. Böylece alışılmış truncate, mkfs, losetup ve mount sırası tek bir Activate çağrısıyla değiştiriliyor. Bunu elle test edip bulgularını dev.to'da yayınlayan bir geliştirici, bileşenin iyi biçimlendirilmiş isteklerde çalıştığını, ancak tek mount'luk bir aktivasyonun bileşeni doğrudan çökerttiğini, bazı hataların yanlış tipte ya da hiç sarmalanmadan döndüğünü ve yazarın ölçümlerine göre yeni çağrının yerini aldığı shell komutlarından daha yavaş olduğunu bildiriyor.

Bunların hiçbiri için bir ctr alt komutu yok. Manager, containerd'nin çekirdek mount paketinde yer alıyor ve bir snapshotter ya da bir runtime shim tarafından gömülmesi amaçlanıyor. Activate iki grup mount döndürüyor: manager'ın kendi başına hallettikleri, örneğin loopback attach, ve çağıranın normal mount(2) syscall'ı ile hâlâ mount etmesi gerekenler. Yazar, testlerini Docker Engine 29.3.1 ile gelen containerd üzerinde yaptı (kendini 2.2.2 olarak bildiriyor) ve daemon'un sürüm dizgisine güvenmek yerine paket sürümünü go.mod'da sabitledi.

Elle yapmaktan daha yavaş

Testteki her iki yol da 200MiB'lik bir ext4 imajı formatlıyor, bir loop cihazı bağlıyor ve onu mount ediyor. Manager'ın Activate'i üç koşuda sırasıyla 29,6, 39,0 ve 47,2 milisaniye sürdü; manuel dört komutluk sıra ise 24,4, 23,6 ve 25,9 milisaniye sürdü. Yazar, transformer kaynak kodunu okuduğunda, bunun basitçe gerçek mkfs.ext4 ve mkfs.xfs binary'lerine shell out yaptığını gördü; yani manager, işi azaltmak yerine BoltDB yazmaları ve symlink oluşturma dahil bookkeeping ekliyor. Teardown da aynı boşluğu gösterdi: Deactivate artı umount 32 ile 45 milisaniye tutarken, umount artı loop cihazını elle ayırma 11 ile 13 milisaniye tuttu.

Rapor, yazarın yol boyunca düştüğü bir kıyaslama tuzağını da belgeliyor. İlk karşılaştırma imajı önceden oluşturmak için dd kullandı; bu gerçek sıfır baytları yazıyor ve 358 milisaniyeden 1,6 saniyeye kadar sürüyordu, bu da manager'ı olduğundan on ila elli kat hızlı gösteriyordu. Manuel yol truncate kullanmaya geçtiğinde — bir milisaniyenin altında seyrek (sparse) dosya oluşturuyor — bu görünür kazanç kayboldu ve hafifçe tersine döndü. Disk kullanımı iki yolda da aynıydı: 200MB görünür boyut ve yaklaşık 17MB gerçek blok.

Yanıltan hatalar

Geçersiz girdiler çoğunlukla temiz bir şekilde reddediliyor. Btrfs gibi desteklenmeyen bir dosya sistemi tipi ve eksik bir boyut seçeneği, herhangi bir dosya oluşturulmadan önce "invalid argument" ile başarısız oluyor. İki durum daha sert:

  • Manager'ın yapılandırılmış kökünün dışındaki bir kaynak yol, containerd'nin gerçekten var olmayan özellikler için kullandığı hata sınıfıyla aynı olan "not implemented" olarak reddediliyor. Farklı bir mount yoluna geri dönüp dönmeyeceğine karar vermek için not-implemented hatası kontrolü yapan kod, yanlış yapılandırılmış bir dizini eksik bir özellik olarak ele alır.
  • İlkini deactivate etmeden aynı adla ikinci kez Activate çağırmak, containerd düzeyinde hiçbir sarmalama olmadan, doğrudan metadata deposundan gelen çiğ bir bbolt "bucket already exists" hatası ortaya çıkarıyor. Doğru ama çağıranın hatası yerine depolama motorunu tarif ediyor.

Panik

Belgelenmiş örnekler her zaman en az iki mount'u zincirliyor: biri bir loop cihazı üreten ve biri onu tüketen. Çıktısını tüketen hiçbir şey olmadan tek bir mkfs/loop mount'unu tek başına Activate etmek, bildirilen stack trace'de manager.go 421. satırda Activate içinde bir index-out-of-range hatasıyla panikliyor. Yazar nedeni kaynak kodda izledi: kod, çağıranın halletmesi beklenen ilk mount'un indeksini takip ediyor ve yalnızca bir transform hedefi olarak hizmet veren bir mount için bu indeks, mount listesinin uzunluğuna eşit oluyor; sonraki bir döngü de bu indeksi mount slice'ına erişmek için kullanıyor. Çöküşün yanı sıra rapor, koşunun sonrasında hiçbir şeyin subsequently bulamadığı bağlı bir loop cihazı bıraktığını not ediyor.\n

Eşzamanlılık ayakta duruyor

Aynı manager örneğine paralel olarak Activate çağıran on goroutine, her biri kendi 50MiB'lik imajını formatlayarak, 70,1 milisaniyelik wall time içinde hepsi başarılı oldu; tek tek çağrılar 30,5 ile 69,8 milisaniye arasındaydı. Yazar, seri hale getirilmiş aktivasyonların birkaç yüz milisaniye süreceğini düşünüyor; yani manager'ın iç kilitlemesi, çağıranları kuyruğa almak yerine gerçekten eşzamanlı formatlamaya izin veriyor.

Neden önemli

Mount manager, snapshotter ve shim yazarlarına yönelik yeni bir API yüzeyi ve ham hızdan çok kompoze edilebilirlik (composability) etrafında konumlandırıldı — bu kıyaslama o ayrımı somutlaştırıyor. containerd 2.2'de Activate tabanlı provisioning yolunu benimseyen herkes mevcut pürüzlerini bilmeli: tek mount'luk bir zincir bir doğrulama hatası değil sert bir çöküş, hata tipleri fallback mantığını yanlış yöne sürükleyebilir ve yinelenen aktivasyonlar depolama motoru iç ayrıntılarını sızdırıyor. Savunmacı çağıranlar bugün şunlarla etkisini azaltabilir: üreten bir mount'un ardından her zaman tüketen bir mount zincirlemek, manager'a devretmeden önce yapılandırılmış kökleri doğrulamak ve sarmalanmamış bbolt hatasını adın zaten aktif olduğunun bir işareti olarak görmek. Ancak panik ve hata sınıflandırması, yeni yolun drop-in bir yerine koyma olarak güvenle ele alınabilmesinden önce upstream'in çözmesi gereken sorunlar gibi görünüyor.

  • #containerd
  • #containers
  • #linux
  • #runtime
  • #bug-report