Korištenje višestupanjskog dockera za izradu Windows slika

Bok svima! Moje ime je Andrey i radim kao DevOps inženjer u Exnessu u razvojnom timu. Moja glavna djelatnost je vezana uz izgradnju, implementaciju i podršku aplikacija u dockeru pod operativnim sustavom Linux (u daljnjem tekstu OS). Nedavno sam imao zadatak s istim aktivnostima, ali ciljni OS projekta bio je Windows Server i skup C++ projekata. Za mene je ovo bila prva bliska interakcija s docker kontejnerima pod Windows OS-om i, općenito, s C++ aplikacijama. Zahvaljujući tome doživio sam zanimljivo iskustvo i naučio o nekim zamršenostima spremnika aplikacija u sustavu Windows.

Korištenje višestupanjskog dockera za izradu Windows slika

U ovom članku želim vam reći s kojim sam se poteškoćama morao suočiti i kako sam ih uspio riješiti. Nadam se da je ovo od pomoći za vaše sadašnje i buduće izazove. Uživaj čitajući!

Zašto kontejneri?

Tvrtka ima postojeću infrastrukturu za Hashicorp Nomad kontejnerski orkestrator i povezane komponente - Consul i Vault. Stoga je odabrana kontejnerizacija aplikacija kao objedinjena metoda za isporuku cjelovitog rješenja. Budući da projektna infrastruktura sadrži docker hostove s Windows Server Core OS verzijama 1803 i 1809, potrebno je izgraditi zasebne verzije docker slika za 1803 i 1809. U verziji 1803, važno je zapamtiti da broj revizije build docker hosta mora odgovarati revizijskom broju osnovne docker slike i hostu na kojem će se spremnik iz ove slike pokrenuti. Verzija 1809 nema takav nedostatak. Možete pročitati više здесь.

Zašto višestupanjski?

Inženjeri razvojnog tima nemaju ili imaju vrlo ograničen pristup izradi hostova; ne postoji način za brzo upravljanje skupom komponenti za izgradnju aplikacije na tim hostovima, na primjer, instaliranje dodatnog skupa alata ili radnog opterećenja za Visual Studio. Stoga smo donijeli odluku instalirati sve komponente potrebne za izgradnju aplikacije u build Docker sliku. Ako je potrebno, možete brzo promijeniti samo docker datoteku i pokrenuti cjevovod za stvaranje ove slike.

Od teorije do akcije

U idealnoj Docker višefaznoj izgradnji slike, okruženje za izgradnju aplikacije priprema se u istoj Dockerfile skripti kao što je sama aplikacija izgrađena. Ali u našem slučaju dodana je posredna veza, naime korak preliminarne izrade docker slike sa svime što je potrebno za izgradnju aplikacije. To je učinjeno jer sam želio upotrijebiti značajku predmemorije dockera za smanjenje vremena instalacije svih ovisnosti.

Pogledajmo glavne točke skripte dockerfile za stvaranje ove slike.

Za stvaranje slika različitih verzija OS-a, možete definirati argument u docker datoteci kroz koji se prosljeđuje broj verzije tijekom izgradnje, a to je ujedno i oznaka osnovne slike.

Potpuni popis Microsoft Windows Server slikovnih oznaka može se pronaći здесь.

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

Prema zadanim postavkama naredbe u uputama RUN unutar dockerfilea na Windows OS-u izvršavaju se u konzoli cmd.exe. Radi praktičnosti pisanja skripti i proširenja funkcionalnosti korištenih naredbi, redefinirat ćemo konzolu za izvršavanje naredbi u Powershellu kroz upute SHELL.

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

Sljedeći korak je instaliranje chocolatey package managera i potrebnih paketa:

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'

Za instaliranje paketa koristeći chocolatey, možete ih jednostavno proslijediti kao popis ili ih instalirati jedan po jedan ako trebate proslijediti jedinstvene parametre za svaki paket. U našoj situaciji koristili smo datoteku manifesta u XML formatu koja sadrži popis potrebnih paketa i njihove parametre. Njegov sadržaj izgleda ovako:

<?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>

Zatim instaliramo okruženje za izradu aplikacije, naime MS Build Tools 2019 - ovo je lagana verzija Visual Studio 2019, koja sadrži minimalno potreban skup komponenti za kompajliranje koda.
Za potpuni rad s našim C++ projektom trebat će nam dodatne komponente, naime:

  • Radno opterećenje C++ alata
  • Skup alata v141
  • Windows 10 SDK (10.0.17134.0)

Možete automatski instalirati prošireni skup alata pomoću konfiguracijske datoteke u JSON formatu. Sadržaj konfiguracijske datoteke:

Potpuni popis dostupnih komponenti može se pronaći na stranici dokumentacije 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 pokreće instalacijsku skriptu i radi praktičnosti dodaje putanju do izvršnih datoteka alata za izgradnju u varijablu okruženja PATH. Također je preporučljivo ukloniti nepotrebne datoteke i direktorije kako biste smanjili veličinu slike.

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)

U ovoj fazi, naša slika za kompajliranje C++ aplikacije je spremna, i možemo nastaviti izravno sa stvaranjem docker višestupanjske izgradnje aplikacije.

Višestupanjski na djelu

Koristit ćemo stvorenu sliku sa svim alatima na ploči kao sliku za izgradnju. Kao i u prethodnoj dockerfile skripti, dodat ćemo mogućnost dinamičkog određivanja broja verzije/oznake slike radi lakšeg ponovnog korištenja koda. Važno je dodati oznaku as builder na sliku montaže u uputama FROM.

ARG WINDOWS_OS_VERSION=1809
FROM buildtools:$WINDOWS_OS_VERSION as builder

Sada je vrijeme za izradu aplikacije. Ovdje je sve vrlo jednostavno: kopirajte izvorni kod i sve što je povezano s njim i pokrenite proces kompilacije.

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

Završna faza stvaranja konačne slike je određivanje osnovne slike aplikacije, gdje će se nalaziti svi artefakti kompilacije i konfiguracijske datoteke. Za kopiranje kompajliranih datoteka iz srednje slike sklopa, morate navesti parametar --from=builder u uputama COPY.

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

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

Sada preostaje samo dodati potrebne ovisnosti za rad naše aplikacije i odrediti naredbu za pokretanje kroz upute ENTRYPOINT ili CMD.

Zaključak

U ovom sam članku govorio o tome kako stvoriti potpuno kompilacijsko okruženje za C++ aplikacije unutar spremnika pod sustavom Windows i kako koristiti mogućnosti docker višefaznih nadogradnji za stvaranje potpunih slika naše aplikacije.

Izvor: www.habr.com

Dodajte komentar