Použitie viacstupňového dockeru na vytváranie obrazov systému Windows

Ahojte všetci! Volám sa Andrey a pracujem ako inžinier DevOps v Exness vo vývojovom tíme. Moja hlavná činnosť súvisí s budovaním, nasadzovaním a podporou aplikácií v dockeri pod operačným systémom Linux (ďalej len OS). Nie je to tak dávno, čo som mal úlohu s rovnakými aktivitami, ale cieľovým OS projektu bol Windows Server a súbor C++ projektov. Pre mňa to bola prvá úzka interakcia s docker kontajnermi pod OS Windows a vo všeobecnosti s aplikáciami C++. Vďaka tomu som mal zaujímavú skúsenosť a dozvedel som sa o niektorých zložitostiach kontajnerových aplikácií vo Windows.

Použitie viacstupňového dockeru na vytváranie obrazov systému Windows

V tomto článku vám chcem povedať, akým ťažkostiam som musel čeliť a ako sa mi ich podarilo vyriešiť. Dúfam, že to bude užitočné pre vaše súčasné a budúce výzvy. Užívať si čítanie!

Prečo kontajnery?

Spoločnosť má existujúcu infraštruktúru pre kontajnerový orchestrátor Hashicorp Nomad a súvisiace komponenty – Consul a Vault. Preto bola aplikačná kontajnerizácia zvolená ako jednotná metóda na dodanie kompletného riešenia. Keďže infraštruktúra projektu obsahuje hostiteľov dockerov s operačným systémom Windows Server Core OS verzie 1803 a 1809, je potrebné vytvoriť samostatné verzie obrazov ukotvenia pre 1803 a 1809. Vo verzii 1803 je dôležité si uvedomiť, že číslo revízie hostiteľa zostavy docker sa musí zhodovať s číslom revízie základného obrazu doku a hostiteľa, na ktorom sa spustí kontajner z tohto obrazu. Verzia 1809 takúto nevýhodu nemá. Môžete si prečítať viac tu.

Prečo viacstupňové?

Inžinieri vývojového tímu nemajú žiadny alebo veľmi obmedzený prístup k zostavovaniu hostiteľov; neexistuje spôsob, ako rýchlo spravovať sadu komponentov na zostavenie aplikácie na týchto hostiteľoch, napríklad nainštalovať ďalšiu sadu nástrojov alebo pracovné zaťaženie pre Visual Studio. Preto sme sa rozhodli nainštalovať všetky komponenty potrebné na zabudovanie aplikácie do obrazu build Docker. V prípade potreby môžete rýchlo zmeniť iba súbor docker a spustiť kanál na vytvorenie tohto obrázka.

Od teórie k činom

V ideálnom viacstupňovom zostavovaní obrazu Docker je prostredie na zostavenie aplikácie pripravené v rovnakom skripte Dockerfile, ako je zostavená samotná aplikácia. Ale v našom prípade bol pridaný prechodný odkaz, konkrétne krok predbežného vytvorenia obrazu dockeru so všetkým potrebným na zostavenie aplikácie. Bolo to urobené, pretože som chcel použiť funkciu vyrovnávacej pamäte docker na skrátenie času inštalácie všetkých závislostí.

Pozrime sa na hlavné body skriptu dockerfile na vytvorenie tohto obrázka.

Ak chcete vytvoriť obrazy rôznych verzií OS, môžete definovať argument v dockerfile, cez ktorý sa počas zostavovania prenesie číslo verzie a je to tiež značka základného obrazu.

Úplný zoznam obrázkových značiek Microsoft Windows Server nájdete tu.

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

Štandardne príkazy v pokynoch RUN vo vnútri súboru docker v operačnom systéme Windows sa spúšťajú v konzole cmd.exe. Pre pohodlie pri písaní skriptov a rozširovanie funkčnosti používaných príkazov predefinujeme konzolu vykonávania príkazov v Powershell prostredníctvom inštrukcie SHELL.

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

Ďalším krokom je inštalácia správcu balíkov chocolatey a potrebných balíkov:

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'

Ak chcete nainštalovať balíky pomocou chocolatey, môžete ich jednoducho odovzdať ako zoznam alebo ich nainštalovať jeden po druhom, ak potrebujete pre každý balík zadať jedinečné parametre. V našej situácii sme použili súbor manifestu vo formáte XML, ktorý obsahuje zoznam požadovaných balíkov a ich parametre. Jeho obsah vyzerá takto:

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

Ďalej nainštalujeme prostredie na zostavenie aplikácie, konkrétne MS Build Tools 2019 - ide o odľahčenú verziu Visual Studio 2019, ktorá obsahuje minimálnu požadovanú sadu komponentov na kompiláciu kódu.
Aby sme mohli plne pracovať s naším projektom C++, budeme potrebovať ďalšie komponenty, konkrétne:

  • Pracovné zaťaženie C++ nástrojov
  • Sada nástrojov v141
  • Windows 10 SDK (10.0.17134.0)

Rozšírenú sadu nástrojov môžete nainštalovať automaticky pomocou konfiguračného súboru vo formáte JSON. Obsah konfiguračného súboru:

Úplný zoznam dostupných komponentov nájdete na stránke dokumentácie 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 spustí inštalačný skript a pre pohodlie pridá cestu k spustiteľným súborom nástrojov na zostavenie do premennej prostredia PATH. Je tiež vhodné odstrániť nepotrebné súbory a adresáre, aby sa zmenšila veľkosť obrázka.

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)

V tejto fáze je náš obrázok na kompiláciu C++ aplikácie pripravený a môžeme pristúpiť priamo k vytvoreniu dockerovej viacstupňovej zostavy aplikácie.

Viacstupňové v akcii

Vytvorený obrázok so všetkými nástrojmi na palube použijeme ako obrázok zostavy. Rovnako ako v predchádzajúcom skripte dockerfile, pridáme možnosť dynamicky špecifikovať číslo verzie/značku obrázka pre jednoduché opätovné použitie kódu. Je dôležité pridať štítok as builder k obrázku montáže v návode FROM.

ARG WINDOWS_OS_VERSION=1809
FROM buildtools:$WINDOWS_OS_VERSION as builder

Teraz je čas zostaviť aplikáciu. Všetko je tu celkom jednoduché: skopírujte zdrojový kód a všetko, čo je s ním spojené, a spustite proces kompilácie.

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

Poslednou fázou vytvorenia výsledného obrazu je špecifikácia základného obrazu aplikácie, kde budú umiestnené všetky artefakty kompilácie a konfiguračné súbory. Ak chcete skopírovať kompilované súbory z obrazu prechodnej zostavy, musíte zadať parameter --from=builder v návode COPY.

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

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

Teraz už zostáva len pridať potrebné závislosti, aby naša aplikácia fungovala, a zadať príkaz na spustenie pomocou pokynov ENTRYPOINT alebo CMD.

Záver

V tomto článku som hovoril o tom, ako vytvoriť plnohodnotné kompilačné prostredie pre aplikácie C++ vo vnútri kontajnera pod Windowsom a ako využiť možnosti viacstupňových zostavení dockerov na vytvorenie plnohodnotných obrázkov našej aplikácie.

Zdroj: hab.com

Pridať komentár