Menggunakan berbilang peringkat docker untuk membina imej windows

Hai semua! Nama saya Andrey, dan saya bekerja sebagai jurutera DevOps di Exness dalam pasukan pembangunan. Aktiviti utama saya adalah berkaitan dengan membina, menggunakan dan menyokong aplikasi dalam docker di bawah sistem pengendalian Linux (selepas ini dirujuk sebagai OS). Tidak lama dahulu saya mempunyai tugas dengan aktiviti yang sama, tetapi OS sasaran projek itu ialah Windows Server dan satu set projek C++. Bagi saya, ini adalah interaksi rapat pertama dengan bekas docker di bawah Windows OS dan, secara umum, dengan aplikasi C++. Terima kasih kepada ini, saya mempunyai pengalaman yang menarik dan belajar tentang beberapa kerumitan aplikasi kontena dalam Windows.

Menggunakan berbilang peringkat docker untuk membina imej windows

Dalam artikel ini saya ingin memberitahu anda apa kesukaran yang saya hadapi dan bagaimana saya berjaya menyelesaikannya. Saya harap ini berguna untuk cabaran semasa dan masa depan anda. Selamat membaca!

Mengapa bekas?

Syarikat itu mempunyai infrastruktur sedia ada untuk pengatur kontena Hashicorp Nomad dan komponen yang berkaitan - Konsul dan Bilik Kebal. Oleh itu, kontena aplikasi dipilih sebagai kaedah bersatu untuk menyampaikan penyelesaian lengkap. Memandangkan infrastruktur projek mengandungi hos docker dengan Windows Server Core OS versi 1803 dan 1809, adalah perlu untuk membina versi berasingan imej docker untuk 1803 dan 1809. Dalam versi 1803, adalah penting untuk diingat bahawa nombor semakan hos docker binaan mesti sepadan dengan nombor semakan imej docker asas dan hos tempat bekas daripada imej ini akan dilancarkan. Versi 1809 tidak mempunyai kelemahan sedemikian. Anda boleh membaca lebih lanjut di sini.

Mengapa pelbagai peringkat?

Jurutera pasukan pembangunan tidak mempunyai akses atau sangat terhad untuk membina hos; tiada cara untuk mengurus set komponen dengan cepat untuk membina aplikasi pada hos ini, contohnya, memasang set alat tambahan atau beban kerja untuk Visual Studio. Oleh itu, kami membuat keputusan untuk memasang semua komponen yang diperlukan untuk membina aplikasi ke dalam imej binaan Docker. Jika perlu, anda boleh menukar hanya fail docker dengan cepat dan melancarkan saluran paip untuk mencipta imej ini.

Dari teori kepada tindakan

Dalam binaan imej berbilang peringkat Docker yang ideal, persekitaran untuk membina aplikasi disediakan dalam skrip Dockerfile yang sama seperti aplikasi itu sendiri dibina. Tetapi dalam kes kami, pautan perantaraan telah ditambah, iaitu, langkah awal mencipta imej docker dengan segala yang diperlukan untuk membina aplikasi. Ini dilakukan kerana saya ingin menggunakan ciri cache docker untuk mengurangkan masa pemasangan semua kebergantungan.

Mari kita lihat perkara utama skrip dockerfile untuk mencipta imej ini.

Untuk mencipta imej versi OS yang berbeza, anda boleh mentakrifkan hujah dalam fail docker yang melaluinya nombor versi dihantar semasa binaan, dan ia juga merupakan teg bagi imej asas.

Senarai lengkap tag imej Microsoft Windows Server boleh didapati di sini.

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

Secara lalai arahan dalam arahan RUN di dalam fail docker pada OS Windows ia dilaksanakan dalam konsol cmd.exe. Untuk kemudahan menulis skrip dan mengembangkan fungsi arahan yang digunakan, kami akan mentakrifkan semula konsol pelaksanaan arahan dalam Powershell melalui arahan SHELL.

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

Langkah seterusnya ialah memasang pengurus pakej coklat dan pakej yang diperlukan:

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'

Untuk memasang pakej menggunakan coklat, anda hanya boleh menghantarnya sebagai senarai, atau memasangnya satu demi satu jika anda perlu menghantar parameter unik untuk setiap pakej. Dalam situasi kami, kami menggunakan fail manifes dalam format XML, yang mengandungi senarai pakej yang diperlukan dan parameternya. Kandungannya kelihatan seperti ini:

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

Seterusnya, kami memasang persekitaran binaan aplikasi, iaitu, MS Build Tools 2019 - ini ialah versi ringan Visual Studio 2019, yang mengandungi set komponen minimum yang diperlukan untuk menyusun kod.
Untuk bekerja sepenuhnya dengan projek C++ kami, kami memerlukan komponen tambahan, iaitu:

  • Alat C++ beban kerja
  • Set alat v141
  • Windows 10 SDK (10.0.17134.0)

Anda boleh memasang set alat lanjutan secara automatik menggunakan fail konfigurasi dalam format JSON. Kandungan fail konfigurasi:

Senarai lengkap komponen yang tersedia boleh didapati di tapak dokumentasi 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"
  ]
}

Fail docker menjalankan skrip pemasangan, dan untuk kemudahan, menambah laluan kepada fail boleh laku alat binaan kepada pembolehubah persekitaran PATH. Ia juga dinasihatkan untuk mengalih keluar fail dan direktori yang tidak diperlukan untuk mengurangkan saiz imej.

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)

Pada peringkat ini, imej kami untuk menyusun aplikasi C++ sudah sedia, dan kami boleh meneruskan terus untuk mencipta binaan berbilang peringkat docker bagi aplikasi itu.

Pelbagai peringkat dalam tindakan

Kami akan menggunakan imej yang dicipta dengan semua alatan di atas kapal sebagai imej binaan. Seperti dalam skrip fail docker sebelumnya, kami akan menambah keupayaan untuk menentukan nombor versi/tag imej secara dinamik untuk memudahkan penggunaan semula kod. Adalah penting untuk menambah label as builder kepada imej pemasangan dalam arahan FROM.

ARG WINDOWS_OS_VERSION=1809
FROM buildtools:$WINDOWS_OS_VERSION as builder

Kini tiba masanya untuk membina aplikasi. Segala-galanya di sini agak mudah: salin kod sumber dan semua yang berkaitan dengannya, dan mulakan proses penyusunan.

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

Peringkat akhir mencipta imej akhir adalah untuk menentukan imej asas aplikasi, di mana semua artifak kompilasi dan fail konfigurasi akan ditempatkan. Untuk menyalin fail yang disusun daripada imej pemasangan perantaraan, anda mesti menentukan parameter --from=builder dalam arahan COPY.

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

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

Sekarang yang tinggal hanyalah menambah kebergantungan yang diperlukan untuk aplikasi kami berfungsi dan menentukan arahan pelancaran melalui arahan ENTRYPOINT atau CMD.

Kesimpulan

Dalam artikel ini, saya bercakap tentang cara mencipta persekitaran kompilasi penuh untuk aplikasi C++ di dalam bekas Windows dan cara menggunakan keupayaan binaan berbilang peringkat docker untuk mencipta imej lengkap aplikasi kami.

Sumber: www.habr.com

Tambah komen