Përdorimi i docker me shumë faza për të ndërtuar imazhe të Windows

Pershendetje te gjitheve! Emri im është Andrey dhe punoj si inxhinier DevOps në Exness në ekipin e zhvillimit. Aktiviteti im kryesor lidhet me ndërtimin, vendosjen dhe mbështetjen e aplikacioneve në docker nën sistemin operativ Linux (në tekstin e mëtejmë OS). Jo shumë kohë më parë kisha një detyrë me të njëjtat aktivitete, por OS-ja e synuar e projektit ishte Windows Server dhe një grup projektesh C++. Për mua, ky ishte ndërveprimi i parë i ngushtë me kontejnerët docker nën sistemin operativ Windows dhe, në përgjithësi, me aplikacionet C++. Falë kësaj, pata një përvojë interesante dhe mësova për disa nga ndërlikimet e aplikacioneve të kontejnerimit në Windows.

Përdorimi i docker me shumë faza për të ndërtuar imazhe të Windows

Në këtë artikull dua t'ju tregoj se çfarë vështirësish më është dashur të përballem dhe si kam arritur t'i zgjidh ato. Shpresoj që kjo të jetë e dobishme për sfidat tuaja aktuale dhe të ardhshme. Kënaquni duke lexuar!

Pse kontejnerë?

Kompania ka infrastrukturën ekzistuese për orkestruesin e kontejnerëve Hashicorp Nomad dhe komponentët përkatës - Konsulli dhe Vault. Prandaj, kontejnerizimi i aplikacionit u zgjodh si një metodë e unifikuar për dhënien e një zgjidhjeje të plotë. Meqenëse infrastruktura e projektit përmban hoste docker me versionet e Windows Server Core OS 1803 dhe 1809, është e nevojshme të ndërtohen versione të veçanta të imazheve të dokerit për 1803 dhe 1809. Në versionin 1803, është e rëndësishme të mbani mend se numri i rishikimit të hostit të build docker duhet të përputhet me numrin e rishikimit të imazhit bazë të dokerit dhe hostit ku do të lëshohet kontejneri nga ky imazh. Versioni 1809 nuk ka asnjë pengesë të tillë. Mund të lexoni më shumë këtu.

Pse me shumë faza?

Inxhinierët e ekipit të zhvillimit nuk kanë ose kanë qasje shumë të kufizuar për të ndërtuar hoste; nuk ka asnjë mënyrë për të menaxhuar shpejt grupin e komponentëve për ndërtimin e një aplikacioni në këto hoste, për shembull, instaloni një grup mjetesh shtesë ose ngarkesë pune për Visual Studio. Prandaj, ne morëm vendimin për të instaluar të gjithë komponentët e nevojshëm për të ndërtuar aplikacionin në imazhin e build Docker. Nëse është e nevojshme, mund të ndryshoni shpejt vetëm skedarin docker dhe të nisni tubacionin për krijimin e këtij imazhi.

Nga teoria në veprim

Në një ndërtim ideal imazhi me shumë faza Docker, mjedisi për ndërtimin e aplikacionit përgatitet në të njëjtin skenar Dockerfile siç është ndërtuar vetë aplikacioni. Por në rastin tonë, u shtua një lidhje e ndërmjetme, domethënë, hapi i krijimit paraprak të një imazhi doker me gjithçka të nevojshme për të ndërtuar aplikacionin. Kjo u bë sepse doja të përdorja funksionin e docker cache për të reduktuar kohën e instalimit të të gjitha varësive.

Le të shohim pikat kryesore të skenarit dockerfile për krijimin e këtij imazhi.

Për të krijuar imazhe të versioneve të ndryshme të OS, mund të përcaktoni një argument në skedarin docker përmes të cilit kalohet numri i versionit gjatë ndërtimit, dhe është gjithashtu etiketa e imazhit bazë.

Mund të gjendet një listë e plotë e etiketave të imazheve të Microsoft Windows Server këtu.

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

Si parazgjedhje komandat në udhëzimet RUN brenda skedarit docker në OS Windows ato ekzekutohen në konsolën cmd.exe. Për lehtësinë e shkrimit të skripteve dhe zgjerimin e funksionalitetit të komandave të përdorura, ne do të ripërcaktojmë konsolën e ekzekutimit të komandës në Powershell përmes udhëzimit SHELL.

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

Hapi tjetër është instalimi i menaxherit të paketave të çokollatës dhe paketave të nevojshme:

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'

Për të instaluar paketat duke përdorur çokollatë, thjesht mund t'i kaloni ato si një listë, ose t'i instaloni ato një nga një nëse keni nevojë të kaloni parametra unikë për secilën paketë. Në situatën tonë, ne përdorëm një skedar manifest në formatin XML, i cili përmban një listë të paketave të kërkuara dhe parametrave të tyre. Përmbajtja e tij duket si kjo:

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

Më pas, ne instalojmë mjedisin e ndërtimit të aplikacionit, përkatësisht, MS Build Tools 2019 - ky është një version i lehtë i Visual Studio 2019, i cili përmban grupin minimal të kërkuar të komponentëve për përpilimin e kodit.
Për të punuar plotësisht me projektin tonë C++, do të na duhen komponentë shtesë, përkatësisht:

  • Ngarkesa e punës mjetet C++
  • Kompleti i mjeteve v141
  • Windows 10 SDK (10.0.17134.0)

Mund të instaloni automatikisht një grup të zgjeruar mjetesh duke përdorur një skedar konfigurimi në formatin JSON. Përmbajtja e skedarit të konfigurimit:

Një listë e plotë e komponentëve të disponueshëm mund të gjendet në faqen e dokumentacionit 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 ekzekuton skriptin e instalimit dhe për lehtësi, shton shtegun për skedarët e ekzekutueshëm të mjeteve të ndërtimit në variablin e mjedisit PATH. Këshillohet gjithashtu të hiqni skedarët dhe drejtoritë e panevojshme për të zvogëluar madhësinë e imazhit.

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)

Në këtë fazë, imazhi ynë për përpilimin e aplikacionit C++ është gati dhe ne mund të vazhdojmë drejtpërdrejt në krijimin e një ndërtimi shumëfazor docker të aplikacionit.

Shumëfazësh në veprim

Ne do të përdorim imazhin e krijuar me të gjitha mjetet në bord si një imazh ndërtimi. Ashtu si në skriptin e mëparshëm dockerfile, ne do të shtojmë aftësinë për të specifikuar në mënyrë dinamike numrin e versionit/etiketën e imazhit për lehtësinë e ripërdorimit të kodit. Është e rëndësishme të shtoni një etiketë as builder në imazhin e montimit në udhëzimet FROM.

ARG WINDOWS_OS_VERSION=1809
FROM buildtools:$WINDOWS_OS_VERSION as builder

Tani është koha për të ndërtuar aplikacionin. Gjithçka këtu është mjaft e thjeshtë: kopjoni kodin burimor dhe gjithçka që lidhet me të dhe filloni procesin e përpilimit.

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

Faza përfundimtare e krijimit të imazhit përfundimtar është të specifikoni imazhin bazë të aplikacionit, ku do të vendosen të gjitha objektet e përpilimit dhe skedarët e konfigurimit. Për të kopjuar skedarët e përpiluar nga imazhi i asamblesë së ndërmjetme, duhet të specifikoni parametrin --from=builder në udhëzimet COPY.

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

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

Tani mbetet vetëm të shtojmë varësitë e nevojshme që aplikacioni ynë të funksionojë dhe të specifikojmë komandën e nisjes përmes udhëzimeve ENTRYPOINT ose CMD.

Përfundim

Në këtë artikull, unë fola se si të krijoni një mjedis kompilimi të plotë për aplikacionet C++ brenda një kontejneri Windows dhe si të përdorni aftësitë e ndërtimeve me shumë faza docker për të krijuar imazhe të plota të aplikacionit tonë.

Burimi: www.habr.com

Shto një koment