Docker multi-stage kasutamine Windowsi piltide ehitamiseks

Tere kõigile! Minu nimi on Andrei ja töötan exnessis DevOps insenerina arendusmeeskonnas. Minu peamine tegevus on rakenduste ehitamine, juurutamine ja toetamine dockeri abil Linuxi operatsioonisüsteemis (edaspidi — OS). Hiljuti tuli mul silmitsi seista ülesandega, mille raames tuli samuti neid tegevusi teostada, kuid projekti sihtoperatsioonisüsteemiks sai Windows Server ja hulk C++ projekte. See oli minu esimene tihe koostöö docker konteineritega Windowsi operatsioonisüsteemi all ning üldiselt C++ rakendustega. Selle tõttu sain huvitava kogemuse ning õppisin mõnedest rakenduste konteinerimise nüanssidest Windowsi operatsioonisüsteemis.

Docker multi-stage kasutamine Windowsi piltide ehitamiseks

Selles artiklis tahan rääkida, milliste raskustega ma silmitsi seisnud olen ja kuidas need ära lahendada õnnestus. Lootan, et see osutub kasulikuks teie praeguste ja tulevaste probleemide lahendamisel. Head lugemist!

Miks konteinerid?

Ettevõttel on olemasolev Hashicorp Nomad konteinerite orkestreerimise infrastruktuur ning seotud komponendid — Consul ja Vault. Seetõttu on rakenduste konteineriseerimine valitud ühtse lahendusena. Kuna projekti infrastruktuuris on docker-hostid Windows Server Core 1803 ja 1809 versioonidega, on vajalik eraldi docker-piltide versioonide koostamine 1803 ja 1809 jaoks. Versioonis 1803 on oluline meeles pidada, et docker-hosti koostamise revisjoninumber peab vastama põhilddocker-pildi ja hosti revisjoninumbrile, kus selle pildiga konteiner tööle pannakse. Versioon 1809 ei ole sellise puuduse all. Rohkem teavet saab lugeda siit.

Miks multi-stage?

Arenduse meeskonna inseneridel puudub juurdepääs kogumishostidele või see on tugevalt piiratud, mis tähendab, et nad ei saa kiiresti hallata komponentide kogumit rakenduse ehitamiseks nendel hostidel, näiteks installida täiendavat tööriistapaketti või töökoormust Visual Studio jaoks. Seetõttu otsustasime — kõik rakenduse ehitamiseks vajalikud komponendid installida kogumish Docker-pildile. Vajadusel on piisavalt kiiresti võimalik muuta ainult Dockerfile'i ja käivitada selle pildi loomise torujuhe.

Teooriast praktikani

Ideaalsetes Docker multi-stage pildistamise protsessides valmistatakse rakenduse ehitamiseks vajalik keskkond ette samas Dockerfile'i skriptis, kus toimub rakenduse enda ehitamine. Kuid meie juhul lisati vahepealne etapp, nimelt docker-pildi eelvalmistamise samm, kuhu on koondatud kõik rakenduse ehitamiseks vajalikud komponendid. See on tehtud, et kasutada Docker'i vahemälu võimalusi, vähendamaks kõigi sõltuvuste installimise aega.

Olgem nüüd tähelepanelikud Dockerfile'i skripti peamistele punktidele, mis on vajalikud selle pildi vormimiseks.

Diverse operatsioonisüsteemide versioonide imagede loomiseks dockerfile'is saab määrata argumendi, mille kaudu edastatakse versiooninumber ning see on ka aluseks oleva imagi silt.

Microsoft Windows Serveri imagede silte leiate täielikust loendist siit.

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

Vaikimisi käsud dockerfile'i juhises RUN Windowsi operatsioonisüsteemis dockerfile'i sees käivitatakse cmd.exe konsoolis. Mugavuse huvides skriptide kirjutamisel ja käsu funktsionaalsuse laiendamisel muudame käsu täitmise konsooli Powershelliks juhise kaudu SHELL.

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

Järgmine samm on paketihalduri chocolatey ja vajalike paketide installimine:

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'

Pakettide installimiseks chocolatey'ga saab neid lihtsalt loetleda või installida ükshaaval, kui on vajalik edastada individuaalsed parameetrid iga paketi jaoks. Meie olukorras kasutasime XML-formaadis manifestifaili, milles on loetletud vajalikud paketid ja nende parameetrid. Selle sisu näeb välja selline:

Järgmisena seadistame rakenduse koostamisvõime, nimelt MS Build Tools 2019 — see on Visual Studio 2019 kergversioon, mis sisaldab vajalikku komponentide minimaalselt vajalikku kogumit koodi kompileerimiseks.
Meie C++ projekti täielikuks tööks vajame täiendavaid komponente, nimelt:

  • C++ tööriistakomplekt
  • Tööriistakomplekt v141
  • Windows 10 SDK (10.0.17134.0)

Täpse tööriistakomplekti automaatset installimist saab teha JSON-vormingus konfiguratsioonifaili abil. Konfiguratsioonifaili sisu:

Kogu saadaolevate komponentide loendi leiate dokumentatsiooni saidilt 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'is käivitatakse installimisprotsess ning mugavuse huvides lisatakse build tools'i käivitatavate failide tee keskkonnamuutujasse. PATHSamuti on soovitatav eemaldada mittevajalikud failid ja kataloogid, et vähendada pildi suurust.

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)

Sel hetkel on meie C++ rakenduse kompileerimise pilt valmis ning on aeg alustada rakenduse docker multi-stage ehitamisega.

Multi-stage tegutsemises

Kogumiseks kasutame loodud pilti, millel on kõik vajalikud tööriistad olemas. Nagu eelnevas dockerfile skriptis, lisame võimaluse dünaamiliselt määrata versiooninumbri/tag'i mugavuse huvides koodi taaskasutamiseks. Oluline on lisada silt as builder kogumise pildile juhendis FROM.

ARG WINDOWS_OS_VERSION=1809
FROM buildtools:$WINDOWS_OS_VERSION as builder

On aeg rakendust kokku panna. Siin on kõik lihtne: kopeerime allika koodi ja kõik sellega seotud, ning käivitame kompileerimisprotsessi.

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

Lõppfaas lõpppildi loomisel — rakenduse põhikuva määramine, kus asuvad kõik kompileerimisartefaktid ja konfigureerimisfailid. Kompileeritud failide kopeerimiseks vahepealsest kogumispildist tuleb määrata valik --from=builder kasutamisjuhendis COPY.

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

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

Nüüd tuleb lisada vajalikud sõltuvused meie rakenduse töö tegemiseks ja määrata käivitamisjuhised ENTRYPOINT või CMD.

Kokkuvõte

Selles artiklis räägin, kuidas luua täisväärtuslik C++ rakenduste kompileerimiskeskkond Windowsi konteineris ja kuidas kasutada Docker multi-stage kogu võimalusi oma rakenduse täisversioonide loomisel.

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster