5.2. Source-to-Image (S2I) ビルド

Source-to-Image (S2I) は再現可能な Docker 形式のコンテナーイメージをビルドするためのツールです。これはアプリケーションソースをコンテナーイメージに挿入し、新規イメージをアセンブルして実行可能なイメージを生成します。新規イメージはベースイメージ (ビルダー) とビルドされたソースを組み込み、buildah run コマンドで使用することができます。S2I は増分ビルドをサポートします。 これは以前にダウンロードされた依存関係や、以前にビルドされたアーティファクトなどを再利用します。

S2I の利点には以下が含まれます。

イメージの柔軟性

S2I スクリプトを作成して、アプリケーションコードをほとんどすべての既存の Docker 形式コンテナーに挿入し、既存のエコシステムを活用することができます。現時点で S2I は tar を使用してアプリケーションソースを挿入するため、イメージは tar が実行されたコンテンツを処理できる必要があることに注意してください。

速度

S2I の場合、アセンブルプロセスは、各手順で新規の層を作成せずに多数の複雑な操作を実行でき、これによりプロセスが高速になります。さらに、S2I スクリプトを作成すると、ビルドが実行されるたびにダウンロードまたはビルドを実行することなく、アプリケーションイメージの以前のバージョンに保存されたアーティファクトを再利用できます。

パッチ容易性 (Patchability)

S2I により、基礎となるイメージがセキュリティー上の問題でパッチを必要とする場合にアプリケーションを一貫して再ビルドできるようになります。

運用効率

Dockerfile が許可するように任意のアクションを実行する代わりにビルド操作を制限することで、PaaS オペレーターはビルドシステムの意図しない、または意図した誤用を避けることができます。

運用上のセキュリティー

任意の Dockerfile をビルドすると、root の権限昇格のためにホストシステムを公開します。これは、Docker ビルドプロセス全体が Docker 権限を持つユーザーとして実行されるため、悪意あるユーザーが悪用する可能性があります。S2I は root ユーザーとして実行される操作を制限し、スクリプトを root 以外のユーザーとして実行できます。

ユーザー効率

S2I は開発者が任意の yum install タイプの操作を実行することを防ぐため、アプリケーションのビルド時の開発の反復スピードを低下させる可能性があります。

エコシステム

S2I により、アプリケーションのベストプラクティスを利用できるイメージの共有されたエコシステムが促進されます。

再現性

生成されるイメージには、特定バージョンのビルドツールおよび依存関係などのすべての入力が含まれる可能性があります。これにより、イメージを正確に再現できます。

5.2.1. Source-to-Image (S2I) 増分ビルドの実行

S2I は増分ビルドを実行できます。 つまり、以前にビルドされたイメージからアーティファクトが再利用されます。

手順

増分ビルドを作成するには、ストラテジー定義に以下の変更を加えて BuildConfig を作成します。

strategy:
  sourceStrategy:
    from:
      kind: "ImageStreamTag"
      name: "incremental-image:latest" 1
    incremental: true 2
1
増分ビルドをサポートするイメージを指定します。この動作がサポートされているか判断するには、ビルダーイメージのドキュメントを参照してください。
2
このフラグでは、増分ビルドを試行するかどうかを制御します。ビルダーイメージで増分ビルドがサポートされていない場合は、ビルドは成功しますが、save-artifacts スクリプトがないため、増分ビルドに失敗したというログメッセージが表示されます。

追加リソース

  • 増分ビルドをサポートするビルダーイメージを作成する方法の詳細については、S2I 要件について参照してください。

5.2.2. Source-to-Image (S2I) ビルダーイメージスクリプトの上書き

ビルダーイメージによって提供される assemblerun、および save-artifacts S2I スクリプトを上書きできます。

手順

ビルダーイメージによって提供される assemblerun、および save-artifacts S2I スクリプトを上書きするには、以下のいずれかを実行します。

  1. アプリケーションのソースリポジトリーの .s2i/bin ディレクトリーに assemble, run または save-artifacts スクリプトを指定します。
  2. ストラテジー定義の一部として、スクリプトを含むディレクトリーの URL を指定します。以下は例になります。
strategy:
  sourceStrategy:
    from:
      kind: "ImageStreamTag"
      name: "builder-image:latest"
    scripts: "http://somehost.com/scripts_directory" 1
1
このパスに、run, assemble および save-artifacts が追加されます。一部または全スクリプトがある場合、そのスクリプトが、イメージに指定された同じ名前のスクリプトの代わりに使用されます。
注記

scripts URL にあるファイルは、ソースリポジトリーの .s2i/bin にあるファイルよりも優先されます。

5.2.3. Source-to-Image (S2I) 環境変数

ソースビルドのプロセスと生成されるイメージで環境変数を利用できるようにする方法として、2 種類 (環境ファイルおよび BuildConfig 環境の値) あります。 指定される変数は、ビルドプロセスでアウトプットイメージに表示されます。

5.2.3.1. Source-to-Image (S2I) 環境ファイルの使用

ソースビルドでは、ソースリポジトリーの .s2i/environment ファイルに指定することで、アプリケーション内に環境の値 (1 行に 1 つ) を設定できます。このファイルに指定される環境変数は、ビルドプロセス時にアウトプットイメージに表示されます。

ソースリポジトリーに .s2i/environment ファイルを渡すと、S2I はビルド時にこのファイルを読み取ります。これにより assemble スクリプトがこれらの変数を使用できるので、ビルドの動作をカスタマイズできます。

手順

たとえば、Rails アプリケーションのアセットコンパイルを無効にするには、以下を実行します。

  • DISABLE_ASSET_COMPILATION=true.s2i/environment ファイルに追加します。

ビルド以外に、指定の環境変数も実行中のアプリケーション自体で利用できます。たとえば、Rails アプリケーションが production ではなく development モードで起動できるようにするには、以下を実行します。

  • RAILS_ENV=development.s2i/environment ファイルに追加します。

追加リソース

  • サポートされる環境変数の完全なリストについては、各イメージのイメージの使用についてのセクションを参照してください。

5.2.3.2. Source-to-Image (S2I) BuildConfig 環境の使用

環境変数を BuildConfigsourceStrategy 定義に追加できます。ここに定義されている環境変数は、assemble スクリプトの実行時に表示され、アウトプットイメージで定義されるので、run スクリプトやアプリケーションコードでも利用できるようになります。

手順

  • たとえば、Rails アプリケーションのアセットコンパイルを無効にするには、以下を実行します。
sourceStrategy:
...
  env:
    - name: "DISABLE_ASSET_COMPILATION"
      value: "true"

追加リソース

  • ビルド環境のセクションでは、より詳細な説明を提供します。
  • oc set env コマンドで、BuildConfig に定義した環境変数を管理することも可能です。

5.2.4. Source-to-Image (S2I) ソースファイルを無視する

Source to image は .s2iignore ファイルをサポートします。このファイルには、無視すべきファイルパターンの一覧が含まれます。 .s2iignore ファイルにあるパターンと一致する、さまざまな入力ソースで提供されるビルドの作業ディレクトリーにあるファイルは assemble スクリプトでは利用できません。

.s2iignore ファイルの形式についての詳細は、 source-to-image ドキュメントを参照してください。

5.2.5. S2I によるソースコードからのイメージの作成

Source-to-Image (S2I) は、アプリケーションのソースコードを入力として取り、アセンブルされたアプリケーションを出力として実行する新規イメージを生成するイメージを簡単に作成できるようにするフレームワークです。

再生成可能なコンテナーイメージのビルドに S2I を使用する主な利点として、開発者の使い勝手の良さが挙げられます。ビルダーイメージの作成者は、イメージが最適な S2I パフォーマンスを実現できるように、ビルドプロセスと S2I スクリプトの基本的なコンセプト 2 点を理解する必要があります。

5.2.5.1. S2I ビルドプロセスについて

ビルドプロセスは、以下の 3 つの要素で構成されており、これら 3 つを組み合わせて最終的なコンテナーイメージが作成されます。

  • ソース
  • S2I スクリプト
  • ビルダーイメージ

ビルドプロセス中に、S2I はソースとスクリプトをビルダーイメージ内に配置する必要があります。ビルダーイメージ内にソースとスクリプトを配置するために、S2I はソースとスクリプトを含む tar ファイルを作成してから、このファイルをビルダーイメージにストリーミングします。assemble スクリプトを実行する前に、S2I はファイルを展開して、ビルダーイメージからコンテンツを、デフォルトの /tmp ディレクトリーではなく、io.openshift.s2i.destination ラベルが指定する場所に配置します。

このプロセスでは、イメージに tar アーカイブユーティリティー (tar コマンドは $PATH にあります) とコマンドラインインタープリター (/bin/sh コマンド) が必要です。これにより、イメージが最速のビルドパスを使用できるようになります。 tar または /bin/sh コマンドが利用できない場合には s2i ビルド プロセスにより、イメージ内にソースとスクリプトが配置されるように、追加のコンテナーが自動で強制実行されて初めて、通常のビルドが実行されます。

基本的な S2I ビルドワークフローについては、以下の図を参照してください。

図5.1 ビルドのワークフロー

S2I ワークフロー

ビルドの実行では、ソース、スクリプト、アーティファクト (ある場合) を展開して、assemble スクリプトを実行します。2 回目の実行の場合には (tar または /bin/sh を検出できないエラーが発生した後など)、スクリプトとソースの両方があるので、assemble スクリプトの呼び出しのみを行います。

5.2.5.2. S2I スクリプトの作成

S2I スクリプトは、ビルダーイメージ内でスクリプトを実行できる限り、どのプログラム言語でも記述できます。S2I は assemble/run/save-artifacts スクリプトを提供する複数のオプションをサポートします。ビルドごとに、これらの場所はすべて、以下の順番にチェックされます。

  1. BuildConfig に指定されるスクリプト
  2. アプリケーションソースの .s2i/bin ディレクトリーにあるスクリプト
  3. デフォルトの URL (io.openshift.s2i.scripts-url ラベル) にあるスクリプト

イメージで指定した io.openshift.s2i.scripts-url ラベルも、BuildConfig で指定したスクリプトも、以下の形式のいずれかを使用します。

  • image:///path_to_scripts_dir: S2I スクリプトが配置されているディレクトリーへのイメージ内の絶対パス
  • file:///path_to_scripts_dir: S2I スクリプトが配置されているディレクトリーへのホスト上の相対パスまたは絶対パス
  • http(s)://path_to_scripts_dir: S2I スクリプトが配置されているディレクトリーの URL

表5.1 S2I スクリプト

スクリプト説明

assemble (必須)

assemble スクリプトは、ソースからアプリケーションアーティファクトをビルドし、イメージ内の適切なディレクトリーに配置します。このスクリプトのワークフローは以下のとおりです。

  1. ビルドのアーティファクトを復元します。save-artifacts も定義するようにしてください (オプション)。
  2. 任意の場所に、アプリケーションソースを配置します。
  3. アプリケーションのアーティファクトをビルドします。
  4. 実行に適した場所に、アーティファクトをインストールします。

run (必須)

run スクリプトはアプリケーションを実行します。

save-artifacts (オプション)

save-artifacts スクリプトは、次に続くビルドプロセスを加速できるようにすべての依存関係を収集します。以下は例になります。

  • Ruby の場合は、Bundler でインストールされる gems
  • Java の場合は、.m2 のコンテンツ

これらの依存関係は tar ファイルに集められ、標準出力としてストリーミングされます。

usage (オプション)

usage スクリプトでは、ユーザーに、イメージの正しい使用方法を通知します。

test/run (オプション)

test/run スクリプトでは、イメージが正しく機能しているかどうかを確認するための単純なプロセスを作成できます。このプロセスの推奨フローは以下のとおりです。

  1. イメージをビルドします。
  2. イメージを実行して usage スクリプトを検証します。
  3. s2i build を実行して assemble スクリプトを検証します。
  4. 再度 s2i build を実行して、save-artifactsassemble スクリプトの保存、復元アーティファクト機能を検証します (オプション)。
  5. イメージを実行して、テストアプリケーションが機能していることを確認します。
注記

test/run スクリプトでビルドしたテストアプリケーションを配置する推奨の場所は、イメージリポジトリーの test/test-app ディレクトリーです。詳しい情報は、S2I ドキュメント を参照してください。

5.2.5.2.1. S2I スクリプトの例

以下の S2I スクリプトの例は Bash で記述されています。それぞれの例では、tar の内容は/tmp/s2i ディレクトリーに展開されることが前提とされています。

例5.1 assemble スクリプト:

#!/bin/bash

# restore build artifacts
if [ "$(ls /tmp/s2i/artifacts/ 2>/dev/null)" ]; then
    mv /tmp/s2i/artifacts/* $HOME/.
fi

# move the application source
mv /tmp/s2i/src $HOME/src

# build application artifacts
pushd ${HOME}
make all

# install the artifacts
make install
popd

例5.2 run スクリプト:

#!/bin/bash

# run the application
/opt/application/run.sh

例5.3 save-artifacts スクリプト:

#!/bin/bash

pushd ${HOME}
if [ -d deps ]; then
    # all deps contents to tar stream
    tar cf - deps
fi
popd

例5.4 usage スクリプト:

#!/bin/bash

# inform the user how to use the image
cat <<EOF
This is a S2I sample builder image, to use it, install
https://github.com/openshift/source-to-image
EOF