Hej alla! Jag heter Andrey och arbetar som DevOps-ingenjör pĂ„ Exness i utvecklingsteamet. Min huvudsakliga verksamhet handlar om att bygga, distribuera och stödja applikationer i Docker under operativsystemet Linux (hĂ€danefter â OS). Nyligen fick jag en uppgift med samma aktiviteter, men dĂ€r den angivna OS för projektet blev Windows Server och en uppsĂ€ttning projekt i C++. Det var första gĂ„ngen jag arbetade intensivt med Docker-containrar under Windows OS och generellt med applikationer i C++. Genom detta fick jag en intressant erfarenhet och lĂ€rde mig om vissa nyanser av containerisering av applikationer i Windows OS.

I den hÀr artikeln vill jag berÀtta om de svÄrigheter jag stötte pÄ och hur jag kunde lösa dem. Jag hoppas att detta kommer att vara anvÀndbart för att lösa dina aktuella och framtida uppgifter. Trevlig lÀsning!
Varför containrar?
Företaget har en befintlig infrastruktur för containerorkestrering med Hashicorp Nomad och relaterade komponenter â Consul och Vault. DĂ€rför valdes containerisering av applikationer som en enhetlig metod för leverans av en fĂ€rdig lösning. Eftersom infrastrukturen för projektet har Docker-vĂ€rdar med versioner av Windows Server Core 1803 och 1809, Ă€r det nödvĂ€ndigt att samla in separata versioner av Docker-bilder för 1803 och 1809. I version 1803 Ă€r det viktigt att kompilatorns revisionsnummer för Docker-vĂ€rden matchar revisionsnumret för den grundlĂ€ggande Docker-bilden och vĂ€rden dĂ€r containern frĂ„n denna bild ska startas. Version 1809 saknar denna brist. Mer information kan lĂ€sas. .
Varför multi-stage?
Utvecklingsingenjörer har begrÀnsad eller ingen tillgÄng till byggvÀrdar, vilket gör det svÄrt att snabbt administrera uppsÀttningen av komponenter för att bygga applikationen pÄ dessa vÀrdar, till exempel att installera ytterligare verktyg eller arbetsbelastningar för Visual Studio. DÀrför beslutade vi att installera alla nödvÀndiga komponenter för att bygga applikationen i Docker-bilden. Vid behov kan vi snabbt Àndra endast Dockerfile och köra pipeline för att skapa denna bild.
FrÄn teori till praktik
I en ideal docker multi-stage bildningsprocess för en bild förbereds miljön för att bygga applikationen i samma dockerfile-skript som sjÀlva applikationsbygget. Men i vÄrt fall har vi lagt till ett mellanled, nÀmligen ett steg för att förhands skapa docker-bilden med allt nödvÀndigt för att bygga applikationen. Detta har gjorts för att utnyttja docker-cache för att minska tiden för installation av alla beroenden.
LÄt oss gÄ igenom de viktigaste punkterna i dockerfile-skriptet för att skapa denna bild.
För att skapa bilder av olika versioner av operativsystemet i dockerfile kan man definiera en parameter, genom vilken versionsnumret skickas vid bygget, och vilket Àr ocksÄ taggen för basbilden.
En fullstÀndig lista över taggar för Microsoft Windows Server-bilder kan hittas .
ARG WINDOWS_OS_VERSION=1809
FROM mcr.microsoft.com/windows/servercore:$WINDOWS_OS_VERSIONSom standard körs kommandon i instruktionen RUN inuti dockerfile i Windows-operativsystemet i cmd.exe-konsolen. För att förenkla skrivandet av skript och utöka funktionaliteten hos de anvÀnda kommandona kommer vi att omdefiniera kommandokonsolen till Powershell via instruktionen SHELL.
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop';"]NÀsta steg Àr att installera paketförvaltaren chocolatey och de nödvÀndiga paketen:
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'För att installera paket med chocolatey kan man enkelt skicka dem som en lista eller installera dem en i taget om det behövs att skicka unika parametrar för varje paket. I vÄrt fall anvÀnde vi en manifestfil i XML-format som innehÄller en lista över nödvÀndiga paket och deras parametrar. InnehÄllet ser ut sÄ hÀr:
DĂ€refter installerar vi byggmiljön för applikationen, nĂ€mligen MS Build Tools 2019 â en lĂ€ttad version av Visual Studio 2019 som innehĂ„ller ett minimalt nödvĂ€ndigt set av komponenter för att kompilera koden.
För att kunna arbeta fullstÀndigt med vÄrt C++-projekt behöver vi ytterligare komponenter, nÀmligen:
- Arbetsbelastning C++ verktyg
- Verktygsvit v141
- Windows 10 SDK (10.0.17134.0)
Det utökade verktygssetet kan installation utföras automatiskt med hjÀlp av en konfigurationsfil i JSON-format. InnehÄllet i konfigurationsfilen:
Den fullstÀndiga listan över tillgÀngliga komponenter finns pÄ dokumentationssidan .
{
"version": "1.0",
"components": [
"Microsoft.Component.MSBuild",
"Microsoft.VisualStudio.Workload.VCTools;includeRecommended",
"Microsoft.VisualStudio.Component.VC.v141.x86.x64",
"Microsoft.VisualStudio.Component.Windows10SDK.17134"
]
}I dockerfilen körs installationsskriptet och för bekvÀmlighetens skull lÀggs sökvÀgen till körbara filer för byggverktyg i miljövariabeln. PATH. Det Àr dessutom önskvÀrt att ta bort onödiga filer och kataloger för att minska bildens storlek.
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)I detta steg Àr vÄr bild för att kompilera C++ applikationen redo, och vi kan gÄ vidare med att skapa docker multi-stage byggnaden av applikationen.
Multi-stage i aktion
Vi kommer att anvĂ€nda den skapade bilden som byggbild med alla verktyg ombord. Som i det tidigare dockerfilen, lĂ€gger vi till möjligheten att dynamiskt ange versionnummer/tag för att underlĂ€tta Ă„teranvĂ€ndning av koden. Det Ă€r viktigt att lĂ€gga till en etikett as builder till byggbilden i instruktionen FRĂ
N.
ARG WINDOWS_OS_VERSION=1809
FROM buildtools:$WINDOWS_OS_VERSION as builderNu Àr det dags att bygga applikationen. HÀr Àr allt ganska enkelt: kopiera kÀllkoden och allt som hör till det, och pÄbörja kompilationsprocessen.
COPY myapp .
RUN nuget restore myapp.sln ;
msbuild myapp.sln /t:myapp /p:Configuration=ReleaseAvslutande steg i att skapa den slutliga bilden â ange basbilden för applikationen, dĂ€r alla kompilationsartefakter och konfigurationsfiler kommer att placeras. För att kopiera de kompilerade filerna frĂ„n den mellanlagrade byggbilden mĂ„ste du ange parametern --from=builder i instruktionen COPY.
FROM mcr.microsoft.com/windows/servercore:$WINDOWS_OS_VERSION
COPY --from=builder C:/x64/Release/myapp/ ./
COPY ./configs ./Nu Àr det bara att lÀgga till de nödvÀndiga beroendena för att köra vÄr applikation och ange startkommandot via instruktionerna ENTRYPOINT eller CMD.
Slutsats
I den hÀr artikeln beskriver jag hur man skapar en komplett kompilermiljö för C++-applikationer inuti en container pÄ Windows och hur man utnyttjar docker multi-stage byggmöjligheter för att skapa fullstÀndiga bilder av vÄr applikation.
KĂ€lla: habr.com
