Menggunakan buruh pelabuhan multi-tahap untuk membuat gambar windows

Halo semua! Nama saya Andrey, dan saya bekerja sebagai insinyur DevOps di Exness di tim pengembangan. Aktivitas utama saya terkait dengan membangun, menyebarkan dan mendukung aplikasi di buruh pelabuhan pada sistem operasi Linux (selanjutnya disebut OS). Belum lama ini saya mendapat tugas dengan aktivitas yang sama, tetapi OS target proyek tersebut adalah Windows Server dan sekumpulan proyek C++. Bagi saya, ini adalah interaksi dekat pertama dengan kontainer buruh pelabuhan di OS Windows dan, secara umum, dengan aplikasi C++. Berkat ini, saya mendapatkan pengalaman menarik dan belajar tentang beberapa seluk-beluk aplikasi containerizing di Windows.

Menggunakan buruh pelabuhan multi-tahap untuk membuat gambar windows

Pada artikel ini saya ingin memberi tahu Anda kesulitan apa saja yang saya hadapi dan bagaimana saya berhasil menyelesaikannya. Saya harap ini bermanfaat untuk tantangan Anda saat ini dan masa depan. Selamat membaca!

Mengapa kontainer?

Perusahaan ini memiliki infrastruktur untuk orkestrator kontainer Hashicorp Nomad dan komponen terkait - Konsul dan Vault. Oleh karena itu, containerisasi aplikasi dipilih sebagai metode terpadu untuk memberikan solusi lengkap. Karena infrastruktur proyek berisi host buruh pelabuhan dengan Windows Server Core OS versi 1803 dan 1809, maka perlu untuk membuat versi gambar buruh pelabuhan yang terpisah untuk 1803 dan 1809. Dalam versi 1803, penting untuk diingat bahwa nomor revisi dari host buruh pelabuhan build harus cocok dengan nomor revisi image buruh pelabuhan dasar dan host tempat container dari image ini akan diluncurkan. Versi 1809 tidak memiliki kekurangan seperti itu. Anda dapat membaca lebih lanjut di sini.

Mengapa multi-tahap?

Insinyur tim pengembangan tidak memiliki atau sangat terbatas akses untuk membangun host; tidak ada cara untuk dengan cepat mengelola kumpulan komponen untuk membangun aplikasi pada host ini, misalnya, menginstal perangkat tambahan atau beban kerja untuk Visual Studio. Oleh karena itu, kami membuat keputusan untuk menginstal semua komponen yang diperlukan untuk membangun aplikasi ke dalam image build Docker. Jika perlu, Anda dapat dengan cepat hanya mengubah dockerfile dan meluncurkan pipeline untuk membuat image ini.

Dari teori hingga tindakan

Dalam pembuatan image multi-tahap Docker yang ideal, lingkungan untuk membangun aplikasi disiapkan dalam skrip Dockerfile yang sama dengan aplikasi itu sendiri dibuat. Namun dalam kasus kami, tautan perantara telah ditambahkan, yaitu langkah awal pembuatan image buruh pelabuhan dengan semua yang diperlukan untuk membangun aplikasi. Ini dilakukan karena saya ingin menggunakan fitur docker cache untuk mengurangi waktu instalasi semua dependensi.

Mari kita lihat poin utama skrip dockerfile untuk membuat gambar ini.

Untuk membuat image dari versi OS yang berbeda, Anda dapat menentukan argumen di dockerfile yang digunakan untuk meneruskan nomor versi selama pembuatan, dan itu juga merupakan tag dari image dasar.

Daftar lengkap tag gambar Microsoft Windows Server dapat ditemukan di sini.

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

Secara default perintah dalam instruksi RUN di dalam dockerfile pada OS Windows, mereka dieksekusi di konsol cmd.exe. Untuk kenyamanan menulis skrip dan memperluas fungsionalitas perintah yang digunakan, kami akan mendefinisikan ulang konsol eksekusi perintah di Powershell melalui instruksi SHELL.

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

Langkah selanjutnya adalah menginstal pengelola paket coklat dan paket-paket 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 menginstal paket menggunakan chocolatey, Anda cukup meneruskannya sebagai daftar, atau menginstalnya satu per satu jika Anda perlu meneruskan parameter unik untuk setiap paket. Dalam situasi kami, kami menggunakan file manifes dalam format XML, yang berisi daftar paket yang diperlukan dan parameternya. Isinya terlihat 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>

Selanjutnya, kita menginstal lingkungan build aplikasi, yaitu MS Build Tools 2019 - ini adalah versi ringan dari Visual Studio 2019, yang berisi kumpulan komponen minimum yang diperlukan untuk mengkompilasi kode.
Untuk sepenuhnya bekerja dengan proyek C++ kita, kita memerlukan komponen tambahan, yaitu:

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

Anda dapat menginstal serangkaian alat tambahan secara otomatis menggunakan file konfigurasi dalam format JSON. Isi file konfigurasi:

Daftar lengkap komponen yang tersedia dapat ditemukan di situs 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"
  ]
}

dockerfile menjalankan skrip instalasi, dan untuk kenyamanan, menambahkan path ke file executable alat build ke variabel lingkungan PATH. Disarankan juga untuk menghapus file dan direktori yang tidak perlu untuk mengurangi ukuran gambar.

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 tahap ini, gambar kita untuk mengkompilasi aplikasi C++ sudah siap, dan kita dapat melanjutkan langsung ke pembuatan build aplikasi docker multi-tahap.

Aksi multi-tahap

Kami akan menggunakan gambar yang dibuat dengan semua alat yang ada sebagai gambar build. Seperti pada skrip dockerfile sebelumnya, kami akan menambahkan kemampuan untuk menentukan nomor versi/tag gambar secara dinamis untuk kemudahan penggunaan kembali kode. Penting untuk menambahkan label as builder ke gambar perakitan dalam instruksi FROM.

ARG WINDOWS_OS_VERSION=1809
FROM buildtools:$WINDOWS_OS_VERSION as builder

Sekarang saatnya membangun aplikasi. Semuanya di sini cukup sederhana: salin kode sumber dan segala sesuatu yang terkait dengannya, dan mulai proses kompilasi.

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

Tahap terakhir dalam pembuatan gambar akhir adalah menentukan gambar dasar aplikasi, di mana semua artefak kompilasi dan file konfigurasi akan ditempatkan. Untuk menyalin file yang dikompilasi dari gambar rakitan perantara, Anda harus menentukan parameternya --from=builder dalam petunjuk COPY.

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

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

Sekarang tinggal menambahkan dependensi yang diperlukan agar aplikasi kita berfungsi dan menentukan perintah peluncuran melalui instruksi ENTRYPOINT ΠΈΠ»ΠΈ CMD.

Kesimpulan

Dalam artikel ini, saya berbicara tentang cara membuat lingkungan kompilasi lengkap untuk aplikasi C++ di dalam container di Windows dan cara menggunakan kemampuan build multi-tahap buruh pelabuhan untuk membuat gambar lengkap aplikasi kita.

Sumber: www.habr.com

Tambah komentar