Windows görüntüleri oluşturmak için docker multi-stage'i kullanma

Herkese selam! Adım Andrey ve Exness'in geliştirme ekibinde DevOps mühendisi olarak çalışıyorum. Ana faaliyetim, Linux işletim sistemi (bundan sonra işletim sistemi olarak anılacaktır) altında docker'da uygulamalar oluşturmak, dağıtmak ve desteklemekle ilgilidir. Kısa bir süre önce aynı etkinliklere sahip bir görevim vardı ancak projenin hedef işletim sistemi Windows Server ve bir dizi C++ projesiydi. Bana göre bu, Windows işletim sistemi altında docker konteynerleriyle ve genel olarak C++ uygulamalarıyla ilk yakın etkileşimdi. Bu sayede ilginç bir deneyim yaşadım ve Windows'ta uygulamaları konteynerleştirmenin bazı inceliklerini öğrendim.

Windows görüntüleri oluşturmak için docker multi-stage'i kullanma

Bu yazıda size hangi zorluklarla karşılaştığımı ve bunları nasıl çözmeyi başardığımı anlatmak istiyorum. Umarım bu, mevcut ve gelecekteki zorluklarınız için faydalıdır. Okumanın tadını çıkar!

Neden konteynerler?

Şirket, Hashicorp Nomad konteyner orkestratörü ve ilgili bileşenler (Consul ve Vault) için mevcut altyapıya sahiptir. Bu nedenle, uygulama konteynerleştirmesi, eksiksiz bir çözüm sunmak için birleşik bir yöntem olarak seçildi. Proje altyapısı Windows Server Core OS 1803 ve 1809 sürümlerine sahip docker ana bilgisayarları içerdiğinden, 1803 ve 1809 için docker görüntülerinin ayrı sürümlerini oluşturmak gerekir. 1803 sürümünde, derleme docker ana bilgisayarının revizyon numarasının hatırlanması önemlidir. temel docker görüntüsünün revizyon numarasıyla ve bu görüntüdeki kapsayıcının başlatılacağı ana bilgisayarla eşleşmelidir. Sürüm 1809'un böyle bir dezavantajı yoktur. Daha fazlasını okuyabilirsiniz burada.

Neden çok aşamalı?

Geliştirme ekibi mühendislerinin ana bilgisayarlar oluşturmaya erişimi yoktur veya çok sınırlıdır; bu ana bilgisayarlar üzerinde bir uygulama oluşturmaya yönelik bileşen kümesini hızlı bir şekilde yönetmenin (örneğin, Visual Studio için ek bir araç seti veya iş yükü yüklemenin) bir yolu yoktur. Bu nedenle uygulamayı derlemek için gerekli tüm bileşenleri derleme Docker görüntüsüne yüklemeye karar verdik. Gerekirse, yalnızca docker dosyasını hızlı bir şekilde değiştirebilir ve bu görüntüyü oluşturmak için işlem hattını başlatabilirsiniz.

Teoriden eyleme

İdeal bir Docker çok aşamalı görüntü yapısında, uygulamayı oluşturmaya yönelik ortam, uygulamanın kendisi ile aynı Dockerfile betiğinde hazırlanır. Ancak bizim durumumuzda, uygulamayı oluşturmak için gereken her şeyi içeren bir docker görüntüsü oluşturma ön adımı olan bir ara bağlantı eklendi. Bu, tüm bağımlılıkların kurulum süresini azaltmak için liman işçisi önbellek özelliğini kullanmak istediğim için yapıldı.

Bu imajı oluşturmak için dockerfile betiğinin ana noktalarına bakalım.

Farklı işletim sistemi sürümlerinin görüntülerini oluşturmak için, docker dosyasında derleme sırasında sürüm numarasının aktarılacağı bir bağımsız değişken tanımlayabilirsiniz ve bu aynı zamanda temel görüntünün etiketidir.

Microsoft Windows Server görüntü etiketlerinin tam listesini burada bulabilirsiniz burada.

ARG WINDOWS_OS_VERSION=1809
FROM mcr.microsoft.com/windows/servercore:$WINDOWS_OS_VERSION

Talimatlardaki komutlar varsayılan olarak RUN Windows işletim sistemindeki docker dosyası içinde cmd.exe konsolunda yürütülürler. Komut dosyası yazmanın ve kullanılan komutların işlevselliğini genişletmenin rahatlığı için, Powershell'deki komut yürütme konsolunu talimat aracılığıyla yeniden tanımlayacağız. SHELL.

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';"]

Bir sonraki adım çikolata paket yöneticisini ve gerekli paketleri kurmaktır:

COPY chocolatey.pkg.config .
RUN Set-ExecutionPolicy Bypass -Scope Process -Force ;
    [System.Net.ServicePointManager]::SecurityProtocol = 
    [System.Net.ServicePointManager]::SecurityProtocol -bor 3072 ;
    $env:chocolateyUseWindowsCompression = 'true' ;
    iex ((New-Object System.Net.WebClient).DownloadString( 
      'https://chocolatey.org/install.ps1')) ;
    choco install chocolatey.pkg.config -y --ignore-detected-reboot ;
    if ( @(0, 1605, 1614, 1641, 3010) -contains $LASTEXITCODE ) { 
      refreshenv; } else { exit $LASTEXITCODE; } ;
    Remove-Item 'chocolatey.pkg.config'

Chocolatey kullanarak paketleri kurmak için, bunları bir liste halinde iletebilirsiniz veya her paket için benzersiz parametreler iletmeniz gerekiyorsa bunları birer birer kurabilirsiniz. Bizim durumumuzda gerekli paketlerin ve parametrelerinin listesini içeren XML formatında bir bildirim dosyası kullandık. İçeriği şuna benziyor:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="python" version="3.8.2"/>
  <package id="nuget.commandline" version="5.5.1"/>
  <package id="git" version="2.26.2"/>
</packages>

Daha sonra, uygulama oluşturma ortamını, yani MS Build Tools 2019'u yüklüyoruz - bu, kodu derlemek için gereken minimum bileşen kümesini içeren Visual Studio 2019'un hafif bir sürümüdür.
C++ projemizle tam olarak çalışabilmek için ek bileşenlere ihtiyacımız olacak:

  • İş yükü C++ araçları
  • Araç seti v141
  • Windows 10 SDK'sı (10.0.17134.0)

JSON biçimindeki bir yapılandırma dosyasını kullanarak, genişletilmiş bir araç kümesini otomatik olarak yükleyebilirsiniz. Yapılandırma dosyası içeriği:

Mevcut bileşenlerin tam listesi dokümantasyon sitesinde bulunabilir. Microsoft Visual Studio.

{
  "version": "1.0",
  "components": [
    "Microsoft.Component.MSBuild",
    "Microsoft.VisualStudio.Workload.VCTools;includeRecommended",
    "Microsoft.VisualStudio.Component.VC.v141.x86.x64",
    "Microsoft.VisualStudio.Component.Windows10SDK.17134"
  ]
}

Dockerfile, kurulum betiğini çalıştırır ve kolaylık olması açısından, derleme araçlarının yürütülebilir dosyalarının yolunu ortam değişkenine ekler. PATH. Görüntünün boyutunu azaltmak için gereksiz dosya ve dizinlerin kaldırılması da önerilir.

COPY buildtools.config.json .
RUN Invoke-WebRequest 'https://aka.ms/vs/16/release/vs_BuildTools.exe' 
      -OutFile '.vs_buildtools.exe' -UseBasicParsing ;
    Start-Process -FilePath '.vs_buildtools.exe' -Wait -ArgumentList 
      '--quiet --norestart --nocache --config C:buildtools.config.json' ;
    Remove-Item '.vs_buildtools.exe' ;
    Remove-Item '.buildtools.config.json' ;
    Remove-Item -Force -Recurse 
      'C:Program Files (x86)Microsoft Visual StudioInstaller' ;
    $env:PATH = 'C:Program Files (x86)Microsoft Visual Studio2019BuildToolsMSBuildCurrentBin;' + $env:PATH; 
    [Environment]::SetEnvironmentVariable('PATH', $env:PATH, 
      [EnvironmentVariableTarget]::Machine)

Bu aşamada, C++ uygulamasını derlemek için imajımız hazır ve doğrudan uygulamanın docker çok aşamalı yapısını oluşturmaya geçebiliriz.

Çok aşamalı çalışma

Oluşturulan görüntüyü, yerleşik tüm araçlarla birlikte bir yapı görüntüsü olarak kullanacağız. Önceki dockerfile betiğinde olduğu gibi, kodun yeniden kullanımını kolaylaştırmak için sürüm numarasını/görüntü etiketini dinamik olarak belirtme yeteneğini ekleyeceğiz. Bir etiket eklemek önemlidir as builder talimatlardaki montaj resmine FROM.

ARG WINDOWS_OS_VERSION=1809
FROM buildtools:$WINDOWS_OS_VERSION as builder

Şimdi uygulamayı oluşturmanın zamanı geldi. Buradaki her şey oldukça basit: kaynak kodunu ve onunla ilişkili her şeyi kopyalayın ve derleme sürecini başlatın.

COPY myapp .
RUN nuget restore myapp.sln ;
    msbuild myapp.sln /t:myapp /p:Configuration=Release

Nihai görüntüyü oluşturmanın son aşaması, tüm derleme yapıtlarının ve yapılandırma dosyalarının yerleştirileceği uygulamanın temel görüntüsünü belirlemektir. Derlenmiş dosyaları ara montaj görüntüsünden kopyalamak için parametreyi belirtmeniz gerekir. --from=builder talimatlarda COPY.

FROM mcr.microsoft.com/windows/servercore:$WINDOWS_OS_VERSION

COPY --from=builder C:/x64/Release/myapp/ ./
COPY ./configs ./

Artık geriye kalan tek şey uygulamamızın çalışması için gerekli bağımlılıkları eklemek ve talimatlar aracılığıyla başlatma komutunu belirtmek. ENTRYPOINT veya CMD.

Sonuç

Bu yazımda Windows Container içerisinde C++ uygulamaları için tam teşekküllü bir derleme ortamının nasıl oluşturulacağından ve uygulamamızın tam teşekküllü görsellerini oluşturmak için docker çok aşamalı yapıların yeteneklerinin nasıl kullanılacağından bahsettim.

Kaynak: habr.com

Yorum ekle