Brug af docker multi-stage til at bygge Windows-billeder

Hej alle! Mit navn er Andrey, og jeg arbejder som DevOps-ingeniør hos Exness i udviklingsteamet. Min hovedaktivitet er relateret til at bygge, implementere og understøtte applikationer i docker under Linux-operativsystemet (herefter benævnt OS). For ikke længe siden havde jeg en opgave med de samme aktiviteter, men projektets mål-OS var Windows Server og et sæt C++-projekter. For mig var dette den første tætte interaktion med docker-containere under Windows OS og generelt med C++-applikationer. Takket være dette havde jeg en interessant oplevelse og lærte om nogle af forviklingerne ved containerisering af applikationer i Windows.

Brug af docker multi-stage til at bygge Windows-billeder

I denne artikel vil jeg fortælle dig, hvilke vanskeligheder jeg måtte stå over for, og hvordan jeg formåede at løse dem. Jeg håber, at dette er nyttigt for dine nuværende og fremtidige udfordringer. God fornøjelse med at læse!

Hvorfor containere?

Virksomheden har eksisterende infrastruktur til Hashicorp Nomad container orkestrator og relaterede komponenter - Consul og Vault. Derfor blev applikationscontainerisering valgt som en samlet metode til at levere en komplet løsning. Da projektinfrastrukturen indeholder docker-værter med Windows Server Core OS version 1803 og 1809, er det nødvendigt at bygge separate versioner af docker-billeder til 1803 og 1809. I version 1803 er det vigtigt at huske, at revisionsnummeret på build-docker-værten skal matche revisionsnummeret på basisdockerbilledet og værten, hvor containeren fra dette billede vil blive lanceret. Version 1809 har ingen sådan ulempe. Du kan læse mere her.

Hvorfor multi-stage?

Udviklingsteamingeniører har ingen eller meget begrænset adgang til at bygge værter; der er ingen måde at hurtigt administrere sættet af komponenter til at bygge en applikation på disse værter, for eksempel installere et ekstra værktøjssæt eller arbejdsbyrde til Visual Studio. Derfor tog vi beslutningen om at installere alle de komponenter, der er nødvendige for at indbygge applikationen i build Docker-billedet. Hvis det er nødvendigt, kan du hurtigt kun ændre dockerfilen og starte pipelinen for at oprette dette billede.

Fra teori til handling

I en ideel Docker multi-stage image build er miljøet til at bygge applikationen forberedt i det samme Dockerfile script, som selve applikationen er bygget. Men i vores tilfælde blev der tilføjet et mellemled, nemlig trinnet med foreløbig oprettelse af et docker-billede med alt det nødvendige for at bygge applikationen. Dette blev gjort, fordi jeg ønskede at bruge docker-cache-funktionen til at reducere installationstiden for alle afhængigheder.

Lad os se på hovedpunkterne i dockerfile-scriptet til at skabe dette billede.

For at oprette billeder af forskellige OS-versioner kan du definere et argument i dockerfilen, hvorigennem versionsnummeret sendes under opbygningen, og det er også tagget for basisbilledet.

En komplet liste over Microsoft Windows Server-billedmærker kan findes her.

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

Som standard kommandoerne i instruktionerne RUN inde i dockerfilen på Windows OS udføres de i cmd.exe-konsollen. For at gøre det nemmere at skrive scripts og udvide funktionaliteten af ​​de brugte kommandoer, vil vi omdefinere kommandoudførelseskonsollen i Powershell gennem instruktionen SHELL.

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

Det næste trin er at installere chokoladepakkemanageren og de nødvendige pakker:

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'

For at installere pakker ved hjælp af chokolade, kan du blot sende dem som en liste, eller installere dem en ad gangen, hvis du har brug for at videregive unikke parametre for hver pakke. I vores situation brugte vi en manifestfil i XML-format, som indeholder en liste over nødvendige pakker og deres parametre. Dens indhold ser således ud:

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

Dernæst installerer vi applikationsopbygningsmiljøet, nemlig MS Build Tools 2019 - dette er en letvægtsversion af Visual Studio 2019, som indeholder det mindst nødvendige sæt af komponenter til kompilering af kode.
For fuldt ud at arbejde med vores C++-projekt skal vi bruge yderligere komponenter, nemlig:

  • Arbejdsbelastning C++ værktøjer
  • Værktøjssæt v141
  • Windows 10 SDK (10.0.17134.0)

Du kan installere et udvidet sæt værktøjer automatisk ved hjælp af en konfigurationsfil i JSON-format. Indhold af konfigurationsfil:

En komplet liste over tilgængelige komponenter kan findes på dokumentationssiden 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"
  ]
}

Dockerfilen kører installationsscriptet og tilføjer for nemheds skyld stien til byggeværktøjets eksekverbare filer til miljøvariablen PATH. Det er også tilrådeligt at fjerne unødvendige filer og mapper for at reducere størrelsen af ​​billedet.

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)

På dette stadium er vores image til kompilering af C++-applikationen klar, og vi kan fortsætte direkte til at oprette en docker-flertrins-build af applikationen.

Flertrin i aktion

Vi vil bruge det oprettede billede med alle værktøjerne ombord som et byggebillede. Som i det tidligere dockerfile-script tilføjer vi muligheden for dynamisk at angive versionsnummeret/billedmærket for at lette genbrug af kode. Det er vigtigt at tilføje en etiket as builder til monteringsbilledet i vejledningen FROM.

ARG WINDOWS_OS_VERSION=1809
FROM buildtools:$WINDOWS_OS_VERSION as builder

Nu er det tid til at bygge applikationen. Alt her er ret simpelt: Kopier kildekoden og alt, der er forbundet med den, og start kompileringsprocessen.

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

Den sidste fase af oprettelsen af ​​det endelige billede er at specificere basisbilledet af applikationen, hvor alle kompileringsartefakter og konfigurationsfiler vil blive placeret. For at kopiere kompilerede filer fra det mellemliggende assemblybillede skal du angive parameteren --from=builder i instruktionerne COPY.

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

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

Nu er der kun tilbage at tilføje de nødvendige afhængigheder for at vores applikation kan fungere og angive startkommandoen gennem instruktionerne ENTRYPOINT eller CMD.

Konklusion

I denne artikel talte jeg om, hvordan man opretter et fuldgyldigt kompileringsmiljø for C++-applikationer inde i en container under Windows, og hvordan man bruger mulighederne i docker-flertrins-builds til at skabe fuldgyldige billeder af vores applikation.

Kilde: www.habr.com

Tilføj en kommentar