Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

Docker Best Practice – Ekstra Katmanla Image Build Sürecindeki Performansı Arttırma

Merhaba,

Bu içeriğimizde, Docker yazı serisinde şu ana kadar ele aldığımız konular çerçevesinde image build sürecindeki maliyeti düşürmek için bir ipucu verecek ve best practice bir yöntem ile değerlendirme yapacağız.

Peki neyi değerlendireceğiz?
Dockerfile dosyasında verilen talimatlar arasında ‘COPY’ talimatının çalışma mantığı üzerine konuşacak ve genellikle ilgili dosya içeriğini tasarlarken yapılan yanlış olmayan ama pekte doğru sayılmayan bir durumdan bahsedecek ve nihayetinde düzeltici birkaç öneride bulunacağız.

‘COPY’ talimatının çalışma mantığı nasıldır?
Bunun için Dockerfile dosyasının build edilirken nasıl derlendiğini değerlendirmek gerekmektedir. Dockerfile dosyası, docker build -t <image_name> <dockerfile> komutuyla derlenerek nihayetinde bir image üretilmektedir. Build işlemi esnasında ‘COPY’ talimatı ilk tetiklendiğinde tüm kopyalanacak dosyaları cache’lemekte(önbelleklemekte) ve sonraki build işlemlerinde bu dosyalarda herhangi bir değişiklik olmadığı taktirde cache üzerinden işlemleri gerçekleştirmektedir. Böylece sonraki build işleminin sürecini hızlandırmış olmakta lakin ilgili dosyalar arasında bir değişiklik olduğu taktirde tüm kopyalama işlemin
fiziksel olarak gerçekleştirmektedir.

Eğer ki ‘COPY’ işlevinde cache’i etkisiz bırakmak ve tüm kopyalamayı fiziksel olarak tekrar gerçekleştirmek istiyorsanız build ederken –no-cache parametresini belirtmeniz yeterlidir.
docker build --no-cache -t <image_name> <dockerfile>

Şimdi örnek olarak içeriği aşağıdaki gibi bir web uygulamasına özel olarak talimatlar barındıran Dockerfile dosyasını ele alırsak;

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as sdkimage
WORKDIR /app
COPY . .
RUN dotnet restore
RUN dotnet publish DockerizeWebExample.csproj -c Release -o out

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
WORKDIR /app
COPY --from=sdkimage /app/out .

ENV ASPNETCORE_URLS="http://*:1453"
ENTRYPOINT ["dotnet", "DockerizeWebExample.dll"]

3. satırdaki ‘COPY’ talimatı mevcut uygulama dizinindeki tüm dosyaları o andaki image içerisinde açılmış(WORDKIR) klasöre kopyalamaktadır. Her build işleminde bu ‘COPY’ talimatı mevcut dosyalarda yahut uygulamanın kullandığı referanslarda bir değişiklik söz konusu olduğunda fiziksel olarak tetiklenmekte ve dosyaları tekrar kopyalamaktadır. Halbuki bir web uygulamasında kısa aralıkla birçok değişiklik söz konusu olmakta ve genellikle bu değişiklikler dosyalarda olsa da çok nadir referanslardan da kaynaklanabilmektedir.

Dolayısıyla image’i oluşturulan uygulamada kütüphane eklenmesi ve çıkarılması durumlarında koca uygulamanın tekrar fiziksel olarak kopyalanması build süresi açısından oldukça maliyet doğurmakta ve böylece makalemizin ilk paragraflarında bahsedilen yanlış olmayan ama pekte doğru sayılmayan durum söz konusu olmaktadır. İşte handikap buradadır.

Peki çözüm nasıldır?
Çözüm, kütüphanelerle dosyaların birbirlerinden ayrı kopyalanmasındadır. Böylece uygumada herhangi bir kütüphanenin eklenmesi yahut çıkarılması tüm dosyalar üzerinde fiziksel bir kopyalamaya mahal vermeyecek ve aynı durum dosya güncellemesinde kütüphaneler içinde geçerli olacaktır. Tabi ki de burada anlatılan senaryoya göre bizler sadece kütüphane ve fiziksel dosyalara odaklı bir şekilde olayı ele almış bulunmaktayız. Sizler istediğiniz kadar yapılanmayı parçalayabilir ve kendi bünyesinde değişiklik olduğu taktirde fiziksel işleme tabi tutabilirsiniz.

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 as sdkimage
WORKDIR /app
COPY *.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish DockerizeWebExample.csproj -c Release -o out

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
WORKDIR /app
COPY --from=sdkimage /app/out .

ENV ASPNETCORE_URLS="http://*:1453"
ENTRYPOINT ["dotnet", "DockerizeWebExample.dll"]

Yukarıdaki talimatları incelersek eğer; 3. satırdaki ‘COPY *.csproj .’ talimat ile uygulamaya dair tüm kütüphane vs. bilgilerini barındıran ‘.csproj’ dosyası güncellenmekte ve üzerine restore edilmektedir. Akabinde 5. satırda tekrar ‘COPY . .’ talimatı verilmektedir. Buradaki mantık şöyledir; eğer ki kütüphanelerde bir değişiklik olursa ilk 3. satırdaki talimat fiziksel kopyalama işlemi yapacak 5.’de ki ise cache’den çekecektir. Yok eğer dosyalarda bir değişiklik olursa tam tersi olmak üzere 5. satırdaki fiziksel kopyalanacak 3. cache’den gelecektir.

İşte Dockerfile içerisindeki işlemlerimizi bu şekilde tasarladığımız taktirde build ile image üretimi esnasında lüzumsuz kopyalama işlemlerinden arındırmış olacağız ve en önemlisi süresel açıdan oldukça maliyeti düşürmüş olacağız.

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

1 Cevap

  1. 30 Mart 2020

    […] Docker Best Practice – Ekstra Katmanla Image Build Sürecindeki Performansı Arttırma […]

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*