Container Image Registry Oluşturmak

9 Tem 2024 tarihinde yayınlandı

Selamlar,

Bazen kendizine özel, yerel makinanızda çalışan ya da bulut/on-prem üzerinde tüm yönetimini sizin üstlendiğiniz bir container image registry'si oluşturmanız gerekebilir. Bu durumlara:

  • Bağlı olduğunuz organizasyonun sahip olduğu imajların yüksek boyutlu olması ve uzak noktalara yükleme sürelerinin uzaması,
  • İmajlar üzerinde erişim kontrolü,
  • İmaj şifreleme,
  • Geliştirme sürecinde imajları uzak registry'ye yükleme gerekliliği,

...örnek olarak verilebilir.

Container Image Registry Nedir?

Container imajları temelde iki noktada bulunur; yerel makinanız ve uzak image registry'leri.

Image registry'ler, geliştiricilerin container imajlarını paylaşmalarını sağlayan dağıtım noktalarıdır. Bir imaj oluşturduğunuz zaman bunu paylaşmanızın en kolay yolu onu bir image registry'ye yüklemenizdir.

Günümüzde public/private, ücretli/ücretsiz olmak üzere pek çok farklı image registry bulmak mümkün. Bunlardan bazıları şu şekilde:

RegistryFiyatTür
GitHub PackagesÜcretsizSaaS
Distribution (Eski adı ile Registry)ÜcretsizOn-Prem
Google Artifact RegistryÜcretliSaaS
Docker HubPublic imajlar ücretsizSaaS
HarborÜcretsizOn-Prem
Red Hat QuayÜcretliSaaS
Amazon Elastic Container RegistryÜcretliSaaS
Azure Container RegistryÜcretliSaaS

Görebildiğiniz üzere popüler cloud provider'ların hepsi container registry hizmeti sunuyor. Eğer organizasyonunuzun image registry'sini on-prem makinelerde tutma gibi bir zorunluluğu yok ise, bu hizmetlerden birini kullanabilirsiniz. Ben bu yazıda Distribution'ı (eski adı ile Registry) anlatmaya çalışacağım.

Distribution

Eski adıyla Registry olan Distribution, Docker ekibi tarafından geliştirilip CNCF vakfına bağışlanmış bir container image registry yazılımı. Kullanımının kolay olmasının yanında, bizlere authentication, imajları farklı depolama birimlendirme barındırma (S3, Google Cloud Storage, Azure Storage vb.) gibi özellikler sunuyor.

İlk olarak sisteminizde Docker'ın yüklü olduğundan emin olun.

Teknik olarak Distribution bir container imajı olduğu için Podman gibi farklı bir container aracı kullanarak da işlemleri gerçekleştirebilirsiniz. Ben bu yazıda Docker kullanacağım.

Sonrasında registry'mizi çalıştırmak için aşağıdaki komutu kullanalım:

$ docker run -d -p 5000:5000 --restart always --name registry registry:2

Yukarıdaki komutun üzerinden geçersek;

  • -d: Container'ımızı "detached" modda, yani arkaplanda çalışmasını sağlıyoruz. Başka bir deyişle input ve output'un aktif terminale bağlanmasını önlüyoruz.
  • -p: Container içerisindeki 5000 portunun host makinedeki 5000 portuna bağlıyoruz. Eğer bu portu hali hazırda kullanıyorsanız, komutu <PORT>:5000 ile değiştirerek farklı bir porta işaret edecek şekilde güncelleyebilirsiniz.
  • --restart always: Container'ın isteyerek (stop) veya istemeyerek (crash) sonlanması durumunda otomatik olarak yeniden çalıştırılmasını sağlıyoruz.
  • --name registry: Diğerlerinden ayrıştırmak adına container'ımıza isim veriyoruz.
  • registry:2: Registry, Distribution olarak yeniden isimlendirilmiş olsa da, (tahminimce) geriye dönük uyumluluk sebebiyle hala registry isimli imajı kullanıyor. Biz de bu imajı seçerek container'ımızı başlatıyoruz.

Bu aşamada image registry'niz kullanıma hazır hale geliyor. Şimdi gelin bu registry'ye imajları nasıl push/pull yapacağımızı görelim.

Registry'yi kullanmak

Örnek olması için basit bir imaj oluşturalım:

FROM alpine:3.14
CMD ["sh", "-c", "echo 'Merhaba, dünya!'"]

Evet daha basit bir şey olamazdı sanırım 😃. Çalıştırıldığı zaman ekrana mesaj yazan basit bir inline shell scripti yazdık. İmaj boyutunu düşük tutmak adına alpine imajını taban aldık.

Yukarıdaki dosyayı Dockerfile ismiyle bir yerlere kayıt edin. Sonra kayıt ettiğiniz konumda bir terminal ekranı açarak imajı build edin:

$ docker build -t greeter .
[+] Building 2.0s (5/5) FINISHED                                                          docker:default
 => [internal] load build definition from Dockerfile                                                0.0s
 => => transferring dockerfile: 98B                                                                 0.0s
 => [internal] load metadata for docker.io/library/alpine:3.14                                      1.9s
 => [internal] load .dockerignore                                                                   0.0s
 => => transferring context: 2B                                                                     0.0s
 => CACHED [1/1] FROM docker.io/library/alpine:3.14@sha256:0f2d5c38dd7a4f4f733e688e3a6733cb5ab1ac6  0.0s
 => exporting to image                                                                              0.0s
 => => exporting layers                                                                             0.0s
 => => writing image sha256:a1f1a67c51d4954187c2679c0cf661e29b00f2ba6273305e97dfad7ab9fdae42        0.0s
 => => naming to docker.io/library/greeter                                                          0.0s

Evet imajımız şu an yerel docker üzerinde kullanılmaya hazır. Bunu aşağıdaki komut ile test ederek doğrulayabiliriz:

$ docker run --rm greeter
Merhaba, dünya!

--rm parametresi, çalışma süreci tamamlandığı zaman container'ın otomatik olarak silinmesini sağlar.

Peki bu imajı kendi registry'mize nasıl push'layacağız? Docker, imajları nereden çekip (pull) nereye göndereceğine (push) imaj isminde bulunan host bilgisine göre karar verir. Peki bu ne anlama geliyor?

Docker varsayılan olarak tüm imajları docker.io üzerinden çeker ve buraya gönderir. Eğer docker.io dışında bir konum kullanılacaksa, ya imaj ismine dahil edilmeli, ya da imaj etiketlenmelidir.

Buna göre greeter imajımızı localhost:5000 adresinde çalışan registry'mize göre isimlendirmemiz ya da etiketlendirmemiz gerek.

Etiketlemeyi, bir imaj için sembolik link (ln -s) oluşturmak gibi düşünebilirsiniz. Aynı yere işaret eden farklı isimler kısaca. docker tag komutu ile yapılan bu etiketleme haricinde, bir de imajların farklı sürümlerini belirlemek adına yapılan etiketleme vardır. Bu, imaj isimlerinin sonuna : karakterinden sonra yazılarak belirtilir. Örn: hello-world:linux ya da hello-world:nanoserver-1809

Halihazırda imajımızı oluşturduğumuz için etiketleme yöntemini uygulayalım:

$ docker tag greeter localhost:5000/greeter

İmajımızı etiketledik, bunu docker images komutu ile de görebiliriz:

$ docker images
REPOSITORY               TAG            IMAGE ID       CREATED         SIZE
registry                 2              6a3edb1d5eb6   9 months ago    25.4MB
alpine                   3.14           9e179bacf43c   15 months ago   5.61MB
greeter                  latest         a1f1a67c51d4   15 months ago   5.61MB
localhost:5000/greeter   latest         a1f1a67c51d4   15 months ago   5.61MB

Artık imajımızı oluşturduğumuz yeni etiket üzerinden de işaret edebileceğiz. Şimdi ise docker push <imaj adı> komutunu kullanarak imajımızı registry'imize push'layalım:

$ docker push localhost:5000/greeter
Using default tag: latest
The push refers to repository [localhost:5000/greeter]
9733ccc39513: Pushed 
latest: digest: sha256:90bdb97f2d1958c14c8082bf7740fe5e6f9ac9c6e9376706ab1669dae7a16cc0 size: 527

Şimdi imajımızın gerçekten bizim oluşturduğumuz registry'ye push'landığından emin olmak için diğer imajları silelim:

$ docker rmi greeter localhost:5000/greeter
Untagged: greeter:latest
Untagged: localhost:5000/greeter:latest
Untagged: localhost:5000/greeter@sha256:90bdb97f2d1958c14c8082bf7740fe5e6f9ac9c6e9376706ab1669dae7a16cc0
Deleted: sha256:a1f1a67c51d4954187c2679c0cf661e29b00f2ba6273305e97dfad7ab9fdae42

Az önce etiketlediğimiz localhost:5000/greeter isimli imajı da kaldırıyoruz. İmajı tam olarak silmek istiyorsak kendisine işaret eden diğer etiketleri de silmemiz gerekiyor.

Evet diğer imajları sildik. İmajımızın tek kopyası yerelde çalıştırdığmız imaj registry'mizde yer alıyor:

$ docker run --rm localhost:5000/greeter
Unable to find image 'localhost:5000/greeter:latest' locally
latest: Pulling from greeter
f7dab3ab2d6e: Already exists 
Digest: sha256:90bdb97f2d1958c14c8082bf7740fe5e6f9ac9c6e9376706ab1669dae7a16cc0
Status: Downloaded newer image for localhost:5000/greeter:latest
Merhaba, dünya!

Gördüğünüz gibi docker imajımızı yerelde bulamıyor ve registry'mizden çekmeye başlıyor. Sonrasında ise çalıştırarak çıktıyı bizlere gösteriyor.

Bu serinin bir sonraki yazısında, registry'miz için yetkilendirme işlemlerini inceleyeceğiz inşallah. Görüşmek üzere 👋