Použití dockeru ve více fázích k vytváření obrazů systému Windows

Ahoj všichni! Jmenuji se Andrey a pracuji jako inženýr DevOps ve společnosti Exness ve vývojovém týmu. Moje hlavní činnost souvisí s budováním, nasazováním a podporou aplikací v dockeru pod operačním systémem Linux (dále jen OS). Nedávno jsem měl úkol se stejnými aktivitami, ale cílovým OS projektu byl Windows Server a sada projektů C++. Pro mě to byla první úzká interakce s docker kontejnery pod OS Windows a obecně s aplikacemi v C++. Díky tomu jsem měl zajímavou zkušenost a dozvěděl se o některých spletitostech kontejnerizačních aplikací ve Windows.

Použití dockeru ve více fázích k vytváření obrazů systému Windows

V tomto článku vám chci říct, jakým těžkostem jsem musel čelit a jak se mi je podařilo vyřešit. Doufám, že to bude užitečné pro vaše současné i budoucí výzvy. Příjemné čtení!

Proč kontejnery?

Společnost má stávající infrastrukturu pro orchestrátor kontejnerů Hashicorp Nomad a související komponenty – Consul a Vault. Proto byla jako jednotná metoda pro dodání kompletního řešení zvolena aplikační kontejnerizace. Protože infrastruktura projektu obsahuje hostitele dockeru s Windows Server Core OS verze 1803 a 1809, je nutné sestavit samostatné verze bitových kopií dockeru pro 1803 a 1809. Ve verzi 1803 je důležité si zapamatovat, že číslo revize hostitele sestavení dockeru musí odpovídat číslu revize základního obrazu dockeru a hostitele, kde bude kontejner z tohoto obrazu spuštěn. Verze 1809 žádnou takovou nevýhodu nemá. Můžete si přečíst více zde.

Proč vícestupňové?

Inženýři vývojového týmu nemají žádný nebo velmi omezený přístup k sestavování hostitelů; neexistuje způsob, jak rychle spravovat sadu komponent pro vytváření aplikace na těchto hostitelích, například nainstalovat další sadu nástrojů nebo pracovní zátěž pro Visual Studio. Proto jsme se rozhodli nainstalovat všechny komponenty potřebné k sestavení aplikace do obrazu buildu Docker. V případě potřeby můžete rychle změnit pouze dockerfile a spustit kanál pro vytvoření tohoto obrazu.

Od teorie k akci

V ideálním vícefázovém sestavení obrazu Dockeru je prostředí pro sestavení aplikace připraveno ve stejném skriptu Dockerfile, jako je sestavena samotná aplikace. Ale v našem případě byl přidán mezilehlý odkaz, konkrétně krok předběžného vytvoření obrazu dockeru se vším potřebným k sestavení aplikace. Bylo to provedeno, protože jsem chtěl použít funkci docker cache ke zkrácení doby instalace všech závislostí.

Podívejme se na hlavní body skriptu dockerfile pro vytvoření tohoto obrázku.

Chcete-li vytvořit bitové kopie různých verzí OS, můžete definovat argument v dockerfile, přes který je číslo verze předáváno během sestavení, a je to také značka základní bitové kopie.

Úplný seznam značek obrázků Microsoft Windows Server lze nalézt zde.

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

Ve výchozím nastavení příkazy v pokynech RUN uvnitř dockerfile v OS Windows jsou spouštěny v konzole cmd.exe. Pro usnadnění psaní skriptů a rozšíření funkčnosti používaných příkazů předefinujeme konzolu pro provádění příkazů v Powershell prostřednictvím instrukce SHELL.

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

Dalším krokem je instalace správce balíčků chocolatey a potřebných balíčků:

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'

Chcete-li nainstalovat balíčky pomocí chocolatey, můžete je jednoduše předat jako seznam nebo je nainstalovat jeden po druhém, pokud potřebujete předat jedinečné parametry pro každý balíček. V naší situaci jsme použili manifest soubor ve formátu XML, který obsahuje seznam požadovaných balíčků a jejich parametry. Jeho obsah vypadá 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>

Dále nainstalujeme prostředí pro sestavení aplikace, konkrétně MS Build Tools 2019 - jedná se o odlehčenou verzi Visual Studio 2019, která obsahuje minimální požadovanou sadu komponent pro kompilaci kódu.
Abychom mohli plně pracovat s naším projektem C++, budeme potřebovat další komponenty, konkrétně:

  • Pracovní zátěž C++ nástroje
  • Sada nástrojů v141
  • Windows 10 SDK (10.0.17134.0)

Rozšířenou sadu nástrojů můžete nainstalovat automaticky pomocí konfiguračního souboru ve formátu JSON. Obsah konfiguračního souboru:

Úplný seznam dostupných součástí lze nalézt na stránce dokumentace 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í instalační skript a pro usnadnění přidá cestu ke spustitelným souborům nástrojů sestavení do proměnné prostředí PATH. Je také vhodné odstranit nepotřebné soubory a adresáře, aby se zmenšila velikost obrázku.

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 této fázi je náš obraz pro kompilaci C++ aplikace připraven a můžeme přistoupit přímo k vytvoření dockeru vícefázového sestavení aplikace.

Vícestupňové v akci

Vytvořený obrázek se všemi nástroji na desce použijeme jako obrázek sestavení. Stejně jako v předchozím skriptu dockerfile přidáme možnost dynamicky specifikovat číslo verze/značku obrázku pro snadné opětovné použití kódu. Je důležité přidat štítek as builder na obrázek sestavení v návodu FROM.

ARG WINDOWS_OS_VERSION=1809
FROM buildtools:$WINDOWS_OS_VERSION as builder

Nyní je čas na sestavení aplikace. Vše je zde velmi jednoduché: zkopírujte zdrojový kód a vše, co je s ním spojeno, a spusťte proces kompilace.

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

Poslední fází vytváření konečného obrazu je určení základního obrazu aplikace, kde budou umístěny všechny artefakty kompilace a konfigurační soubory. Chcete-li zkopírovat kompilované soubory z obrazu přechodné sestavy, musíte zadat parametr --from=builder v pokynech COPY.

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

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

Nyní zbývá pouze přidat potřebné závislosti, aby naše aplikace fungovala, a pomocí pokynů zadat příkaz spuštění ENTRYPOINT nebo CMD.

Závěr

V tomto článku jsem mluvil o tom, jak vytvořit plnohodnotné kompilační prostředí pro C++ aplikace uvnitř kontejneru Windows a jak využít možností dockerových vícestupňových sestavení k vytvoření plnohodnotných obrázků naší aplikace.

Zdroj: www.habr.com

Přidat komentář