Bu yazımda Work with remote images registries - retrieving information, images, signing content sloganlı Skopeo aracı üzerine konuşmak istiyorum.
Yakın zamanda Gitlab Container Registry ve Nexus gibi ortamlarda tutulan çeşitli container imajları üzerinde işlem yapmam gerekti, kopyalama, taşıma, silme gibi. Kopyalama gibi işlemleri genelde bilgisayarıma çekip, hedef registry’ye push etme şeklinde yapıyordum. Bu sefer işlem yapmam gereken imajlar sıkıştırılmış halleri 50-60 GB, açılmış halleri de 110 GB olan büyük imajlardı. Bu sefer Daha hızlı ve akıllıca yapabilir miyim? diye araştırırken Skopeo’yu buldum. Bu yazıda deneyimlerimi aktaracağım.
Bu kadar büyük imajlar nasıl oluyor?
Merak edenler için bahsettiğim imajlar ağırlıklı olarak Embedded Box, EBox projesi ile oluşturulmuş AMD/Xilinx ISE, Vivado, Vitis, PetaLinux imajları. Bu tarz araçlar gerçekten büyük yer kaplıyor.
Kurulum
Debian ve Ubuntu temelli Linux dağıtımlarında apt install skopeo şeklinde
kurulabiliyor. Windows tarafını bilmiyorum. Linux dağtımınızın sürümüne göre
kurulan versiyon değişecektir ama benim basit kullanımımım için Ubuntu 22.04,
Debian 12 ve 13’teki varsayılan sürümler işime yaradı.
Kopyalama
Temel kullanım amacım Gitlab Container Registry içerisinde kopyalama yapmak oldu. Temel kullanımına bakalım:
skopeo --copy all docker://<source> docker://<destination>
Buradaki docker kısmı kafanızı karıştırmasın. Bilgisayarınızda Docker yoksa
bile, ya da normalde sudo ile çalıştırmanız gerekse bile, Skopeo çalışacaktır.
Buradaki docker:// kısmı bir protokol belirtiyor aslında.
Kaynak yani source URL Gitlab Container Registry’den pull ederken
kullandığınız URL. destination ise istediğiniz hedef URL, bunun karşılığı
Container Registry’de olmayabilir, yaratılacaktır.
Kopyalama yaptıktan
sonra Gitlab üzerinde de her iki imajın Digest SHA256 sum değerini aynı
görmeniz lazım. Sonra isterseniz skopeo inspect ile de bakabilirsiniz.
Giriş Yapma
Gitlab Container Registry’ye login olmanız gerekiyorsa Personal Access Token (PAT)
kullanmanızı öneriyorum. read_registry ve write_registry hakları olan
bir token yeterli olmaktadır. Genel kural olarak bunu süreli yaratmanızı
öneririm. Örneğin birkaç gün taşıma işlemi yapacaksanız 1 haftalık bir token
yaratabilirsiniz. Giriş yapmak için
skopeo login <gitlab registry URL>
kullanabilirsiniz.
Burada interaktif olarak kullanıcı adı ve şifre soracaktır. PAT kullanırken kullanıcı adını rastgele bir şey yazabilirsiniz. Şifre kısmına da Gitlab’tan aldığınız PAT’ı girmelisiniz.
skopeo login olmadan işlemlerinizi skopeo copy --creds=testuser:testpassword
gibi tek seferlik işlemler ile de yapabilirsiniz. Eğer expire olan bir token
oluşturamıyorsanız, mesela Nexus registry’de başınıza gelebilir, çalıştığınız
bilgisayarda giriş bilgilerinizi kayıtlı unutma riskine karşın hiç login
olmadan da bu şekilde işlem yapabilirsiniz.
BASH geçmiş kaydetmeyi kapatma
Eğer vereceğiniz komutlarda giriş bilgileri gibi kritik bilgiler olacaksa bunun öncesinde BASH’in (ya da hangi shell’i kullanıyorsanız) history dosyasına komutlarınızı kaydetmesini kapatmanızı şiddetle öneririm.
Bunun için BASH’te:
export HISTCONTROL=ignoreboth
skopeo <op> --creds=testuser:testpassword <...>
veya
set +o history # history kaydını durdur
skopeo <op> --creds=testuser:testpassword <...>
set -o history # history kaydını devam ettir
kullanabilirsiniz. Başka bir shell kullanıyorsanız onun komutlarını kullanmanız gerekecektir.
Bunu atlama ihtimalinize karşın üşenmeyip eğer kullanabiliyorsanız süreli dolan (expire olan), süresi çok uzun verilmemiş PAT benzeri token kullanmanız her zaman daha iyi olacaktır. En azından bunu unutsanız ve history dosyanız çalınsa bile hesabınızı çaldırdığınız süre sınırlı olur…
Giriş yaptıktan sonra işlemlerinizi yapabilirsiniz.
Diğer İşlemler ve Nexus
copy dışında Skopeo’nun delete ve inspect komutlarını da kullandım,
onlarda da bir problem yaşamadım. Ayrıca Nexus hosted docker registry’de de
düzgün çalıştığını gözlemledim. Karmaşık bir kullanım senaryom olmadı.
Hayaller ve Gerçekler 🫤
Amacım Gitlab Container Registry’de büyük imajları taşımaktı. Beklentim ise aynı Gitlab instance’ında kopyalamanın akıllıca yapılmasıydı. Container layer’larını doğrudan yeni adrese mount etmesini beklerdim fakat Gitlab Container Registry tam olarak beklediğim gibi davranmadı. Bunun sebebi çalıştığım Gitlab sunucusunun konfigürasyonu olabilir ya da bir şeyleri eksik yapmış olabilirim. Gözlemim şu şekilde:
Gitlab’ta bir projenin altında Deploy → Container Registry şeklinde birden
fazla registry olabiliyor. Bunu URL’den de anlayabilirsiniz. URL’de registry id
kısmını en sonunda bir sayı olarak görüyorsunuz, mesela 42 gibi. Eğer
kopyalama yapılan kaynak ve hedef aynı ID’li registry içererisinde ise kopyalama
anlık oluyor, Gitlab otomatik olarak yeni container’a layerlerı taşıyor. Bu
aslında aynı imaja birden fazla tag vermekle eşdeğer mesela imaj:latest vardı
aynı registry içerisinde bunu imaj:v1 olarak tag’lediğiniz zaman bu işlem
anlık oluyor. Fakat aynı proje altında olsa bile ID’si farklı bir
registry’ye taşırsanız Skopeo’nun tüm katmanları lokal’e çekip tekrar push
etmesi gerekti. Bu asında docker pull sonra docker tag ve docker push
yapmak ile kabaca aynı süre alıyor. Ama hala Skopeo kullanımı anlamlı olabilir
çünkü imajı bilgisayarınızda tutmuyorsunuz bir de görebildiğim kadarıyla diske
indirip tekrar push etmiyor. Yani imajınız 100 GB ise önce diskinizde 100 GB
harcayıp sonra geri vermiyor, doğrudan indirip belki birkaç MB buffer alanı
harcaypı hedefe koyuyor yani hala avantajlı.
Sonuç
Gitlab Container Registry’de kopyalama işlemleri için beklediğim kolaylığı bulamadım, tüm layerların indirilmesi gerekti. Bunu Gitlab’ın iç yapısından kaynaklı bir durum olarak değerlendiriyorum. Yine de remote container registry’de veya iki registry arası işlem yapılacaksa Skopeo kullanmak mantıklı.
1️⃣ User olarak sudo ile Docker vs kullanmadan işlem yapabiliyorsunuz.
2️⃣ Gözlemlediğim kadarıyla kopyalama sırasında eğer imajın indirilmesi gerekiyorsa indirilirken aynı anda yükleniyor, diskinizi doldurmuyor.
3️⃣ Kopyalama sırasında doğrudan remote’ta layer’lar kopyalanabilecekse Skopeo bunu yapıyor, bilgisayarınıza imajı indirip tekrar yüklemiyor. Böyle bir durumda imajınız saniyeler içerisinde kopyalanmış oluyor. Bu imkan yoksa mecburen ağ bağlantı hızınıza göre arka planda indirme/yükleme işlemi yapılıyor.
4️⃣ inspect gibi komutlar imajı indirmeden doğrudan bilgi almak için
faydalı oluyor.
Alternatif olarak docker buildx imagetools create gibi araçlar da kullanılabilir ama denemediğim için bir yorum/karşılaştırma yapamayacağım.

