Docker マルチステージを使用して Windows イメージを構築する

こんにちは、みんな! 私の名前は Andrey です。Exness の開発チームで DevOps エンジニアとして働いています。 私の主な活動は、Linux オペレーティング システム (以下、OS と呼びます) 上の Docker でのアプリケーションの構築、デプロイ、およびサポートに関連しています。 少し前にも同じアクティビティを含むタスクがありましたが、プロジェクトのターゲット OS は Windows Server と一連の C++ プロジェクトでした。 私にとって、これは Windows OS 上の Docker コンテナー、そして一般的には C++ アプリケーションとの初めての緊密な対話でした。 このおかげで、私は興味深い経験をすることができ、Windows でのアプリケーションのコンテナ化の複雑さについて学びました。

Docker マルチステージを使用して Windows イメージを構築する

この記事では、私がどのような困難に直面し、どのようにしてそれらを解決できたのかをお話したいと思います。 これがあなたの現在および将来の課題に役立つことを願っています。 読書を楽しむ!

なぜコンテナなのか?

同社には、Hashicorp Nomad コンテナ オーケストレーターと関連コンポーネント (Consul と Vault) 用の既存のインフラストラクチャがあります。 したがって、完全なソリューションを提供するための統一された方法として、アプリケーションのコンテナ化が選択されました。 プロジェクト インフラストラクチャには Windows Server Core OS バージョン 1803 および 1809 の Docker ホストが含まれているため、1803 と 1809 用に別のバージョンの Docker イメージをビルドする必要があります。バージョン 1803 では、ビルド Docker ホストのリビジョン番号に注意することが重要です。ベースの Docker イメージのリビジョン番号と、このイメージのコンテナーが起動されるホストと一致する必要があります。 バージョン 1809 にはそのような欠点はありません。 もっと読むことができます ここで.

なぜマルチステージなのか?

開発チームのエンジニアには、ホストを構築するためのアクセス権がないか、非常に制限されています。たとえば、Visual Studio 用の追加のツールセットやワークロードをインストールするなど、これらのホスト上でアプリケーションを構築するためのコンポーネントのセットを迅速に管理する方法はありません。 したがって、アプリケーションをビルドするために必要なすべてのコンポーネントをビルド Docker イメージにインストールすることにしました。 必要に応じて、dockerfile のみをすばやく変更し、このイメージを作成するためのパイプラインを起動できます。

理論から行動へ

理想的な Docker マルチステージ イメージ ビルドでは、アプリケーションをビルドするための環境は、アプリケーション自体がビルドされるのと同じ Dockerfile スクリプトで準備されます。 ただし、私たちの場合は、中間リンク、つまり、アプリケーションの構築に必要なものすべてを備えた Docker イメージを事前に作成するステップが追加されました。 これは、Docker キャッシュ機能を使用してすべての依存関係のインストール時間を短縮したかったためです。

このイメージを作成するための dockerfile スクリプトの主要なポイントを見てみましょう。

異なる OS バージョンのイメージを作成するには、ビルド中にバージョン番号が渡される dockerfile 内で引数を定義できます。これはベース イメージのタグでもあります。

Microsoft Windows Server イメージ タグの完全なリストは次のとおりです。 ここで.

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

デフォルトでは、説明書のコマンドは RUN Windows OS 上の dockerfile 内では、cmd.exe コンソールで実行されます。 スクリプトの作成と使用されるコマンドの機能の拡張を容易にするために、Powershell のコマンド実行コンソールを次の命令によって再定義します。 SHELL.

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

次のステップでは、chocolatey パッケージ マネージャーと必要なパッケージをインストールします。

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'

Chocolatey を使用してパッケージをインストールするには、単純にパッケージをリストとして渡すか、各パッケージに固有のパラメーターを渡す必要がある場合は一度に XNUMX つずつインストールします。 この状況では、必要なパッケージとそのパラメータのリストが含まれる XML 形式のマニフェスト ファイルを使用しました。 その内容は次のようになります。

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

次に、アプリケーション ビルド環境、つまり MS Build Tools 2019 をインストールします。これは Visual Studio 2019 の軽量バージョンであり、コードのコンパイルに必要な最小限のコンポーネント セットが含まれています。
C++ プロジェクトを完全に操作するには、次の追加コンポーネントが必要です。

  • ワークロード C++ ツール
  • ツールセット v141
  • Windows 10 SDK (10.0.17134.0)

JSON 形式の構成ファイルを使用して、ツールの拡張セットを自動的にインストールできます。 設定ファイルの内容:

利用可能なコンポーネントの完全なリストは、ドキュメント サイトで見つけることができます。 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 はインストール スクリプトを実行し、便宜上、ビルド ツールの実行可能ファイルへのパスを環境変数に追加します。 PATH。 イメージのサイズを減らすために、不要なファイルやディレクトリを削除することもお勧めします。

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)

この段階では、C++ アプリケーションをコンパイルするためのイメージの準備ができているので、アプリケーションの Docker マルチステージ ビルドの作成に直接進むことができます。

マルチステージでの動作

すべてのツールが組み込まれた作成されたイメージをビルド イメージとして使用します。 前の dockerfile スクリプトと同様に、コードの再利用を容易にするために、バージョン番号/イメージ タグを動的に指定する機能を追加します。 ラベルを追加することが重要です as builder 説明書の組み立てイメージへ FROM.

ARG WINDOWS_OS_VERSION=1809
FROM buildtools:$WINDOWS_OS_VERSION as builder

次に、アプリケーションを構築します。 ここでの作業はすべて非常に簡単です。ソース コードとそれに関連するすべてのものをコピーし、コンパイル プロセスを開始します。

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

最終イメージ作成の最終段階では、すべてのコンパイル アーティファクトと構成ファイルが配置されるアプリケーションの基本イメージを指定します。 中間アセンブリ イメージからコンパイル済みファイルをコピーするには、パラメータを指定する必要があります --from=builder 説明書にある COPY.

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

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

あとは、アプリケーションが動作するために必要な依存関係を追加し、指示に従って起動コマンドを指定するだけです。 ENTRYPOINT または CMD.

まとめ

この記事では、Windows 上のコンテナ内に C++ アプリケーションの本格的なコンパイル環境を作成する方法と、Docker のマルチステージ ビルドの機能を使用してアプリケーションの本格的なイメージを作成する方法について説明しました。

出所: habr.com

コメントを追加します