Korišćenje višestepenog docker-a za pravljenje Windows slika

Zdravo svima! Moje ime je Andrey i radim kao DevOps inženjer u Exnessu u razvojnom timu. Moja osnovna aktivnost je vezana za izgradnju, implementaciju i podršku aplikacija u docker-u pod Linux operativnim sistemom (u daljem tekstu OS). Nedavno sam imao zadatak sa istim aktivnostima, ali ciljni OS projekta je bio Windows Server i skup C++ projekata. Za mene je ovo bila prva bliska interakcija sa docker kontejnerima pod Windows OS-om i, općenito, sa C++ aplikacijama. Zahvaljujući tome, imao sam zanimljivo iskustvo i naučio o nekim od zamršenosti kontejnerskih aplikacija u Windowsu.

Korišćenje višestepenog docker-a za pravljenje Windows slika

U ovom članku želim vam reći s kojim sam se poteškoćama suočio i kako sam ih uspio riješiti. Nadam se da će ovo biti od pomoći za vaše trenutne i buduće izazove. Uživajte u čitanju!

Zašto kontejneri?

Kompanija ima postojeću infrastrukturu za kontejnerski orkestrator Hashicorp Nomad i povezane komponente - Consul i Vault. Stoga je kontejnerizacija aplikacije odabrana kao jedinstvena metoda za isporuku kompletnog rješenja. Budući da infrastruktura projekta sadrži docker hostove sa Windows Server Core OS verzijama 1803 i 1809, potrebno je izgraditi zasebne verzije docker slika za 1803 i 1809. U verziji 1803, važno je zapamtiti da je broj revizije build docker hosta mora odgovarati broju revizije osnovne docker slike i hosta na kojem će se pokrenuti kontejner iz ove slike. Verzija 1809 nema takav nedostatak. Možete pročitati više ovdje.

Zašto višestepeni?

Inženjeri razvojnog tima nemaju ili imaju vrlo ograničen pristup hostovima za izgradnju; ne postoji način da se brzo upravlja skupom komponenti za izgradnju aplikacije na ovim hostovima, na primjer, instalirati dodatni skup alata ili radno opterećenje za Visual Studio. Stoga smo donijeli odluku da instaliramo sve komponente potrebne za ugradnju aplikacije u build Docker image. Ako je potrebno, možete brzo promijeniti samo dockerfile i pokrenuti cjevovod za kreiranje ove slike.

Od teorije do akcije

U idealnoj višestepenoj izgradnji Docker slike, okruženje za izgradnju aplikacije priprema se u istoj Dockerfile skripti kao što je izgrađena i sama aplikacija. Ali u našem slučaju je dodana srednja veza, odnosno korak preliminarne izrade docker slike sa svime što je potrebno za izradu aplikacije. Ovo je učinjeno jer sam želio da koristim docker cache funkciju da smanjim vrijeme instalacije svih ovisnosti.

Pogledajmo glavne tačke dockerfile skripte za kreiranje ove slike.

Da biste kreirali slike različitih verzija OS-a, možete definirati argument u dockerfileu kroz koji se prenosi broj verzije tokom izgradnje, a on je i oznaka osnovne slike.

Može se pronaći kompletna lista Microsoft Windows Server oznaka slika ovdje.

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

Podrazumevano komande u uputstvima RUN unutar dockerfile-a na Windows OS-u se izvršavaju u konzoli cmd.exe. Radi praktičnosti pisanja skripti i proširenja funkcionalnosti korišćenih naredbi, redefinisaćemo konzolu za izvršavanje komandi u Powershell-u kroz instrukciju SHELL.

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

Sljedeći korak je instaliranje menadžera čokoladnih paketa i potrebnih paketa:

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'

Da biste instalirali pakete koristeći chocolatey, možete ih jednostavno proslijediti kao listu ili ih instalirati jedan po jedan ako trebate proslijediti jedinstvene parametre za svaki paket. U našoj situaciji koristili smo datoteku manifesta u XML formatu, koja sadrži listu potrebnih paketa i njihove parametre. Njegov sadržaj izgleda ovako:

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

Zatim instaliramo okruženje za izgradnju aplikacije, odnosno MS Build Tools 2019 - ovo je lagana verzija Visual Studio 2019, koja sadrži minimalni potreban skup komponenti za kompajliranje koda.
Da bismo u potpunosti radili s našim C++ projektom, trebat će nam dodatne komponente, i to:

  • Opterećenje C++ alata
  • Toolset v141
  • Windows 10 SDK (10.0.17134.0)

Možete automatski instalirati prošireni skup alata koristeći konfiguracijsku datoteku u JSON formatu. Sadržaj konfiguracijske datoteke:

Kompletna lista dostupnih komponenti može se naći na web stranici za dokumentaciju 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 pokreće instalacijsku skriptu i radi praktičnosti dodaje putanju do izvršnih datoteka alata za izgradnju u varijablu okruženja PATH. Također je preporučljivo ukloniti nepotrebne datoteke i direktorije kako biste smanjili veličinu slike.

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)

U ovoj fazi, naša slika za kompajliranje C++ aplikacije je spremna, i možemo nastaviti direktno sa kreiranjem docker višestepene build aplikacije.

Višestepeni u akciji

Mi ćemo koristiti kreiranu sliku sa svim alatima na ploči kao build image. Kao iu prethodnoj skripti dockerfile, dodaćemo mogućnost dinamičkog specificiranja broja verzije/oznake slike radi lakše ponovne upotrebe koda. Važno je dodati oznaku as builder na sliku sklopa u uputama FROM.

ARG WINDOWS_OS_VERSION=1809
FROM buildtools:$WINDOWS_OS_VERSION as builder

Sada je vrijeme za izradu aplikacije. Ovdje je sve prilično jednostavno: kopirajte izvorni kod i sve povezano s njim i započnite proces kompilacije.

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

Završna faza kreiranja finalne slike je specificiranje osnovne slike aplikacije, gdje će se nalaziti svi artefakti kompilacije i konfiguracijski fajlovi. Da biste kopirali kompajlirane datoteke sa slike srednjeg sklopa, morate navesti parametar --from=builder u uputstvima COPY.

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

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

Sada ostaje samo da se dodaju potrebne zavisnosti da bi naša aplikacija radila i da navedete komandu za pokretanje kroz uputstva ENTRYPOINT ili CMD.

zaključak

U ovom članku govorio sam o tome kako stvoriti punopravno okruženje za kompilaciju za C++ aplikacije unutar kontejnera pod Windowsom i kako koristiti mogućnosti docker-a u više faza za kreiranje punopravnih slika naše aplikacije.

izvor: www.habr.com

Dodajte komentar