Red Hat Training

A Red Hat training course is available for OpenShift Online

イメージの作成

OpenShift Online 3

OpenShift Online イメージ作成ガイド

Red Hat OpenShift Documentation Team

概要

以下のトピックでは、OpenShift Online で使用可能な Docker イメージの作成およびテストにおけるベストプラクティスを説明しています。

第1章 概要

本書では、OpenShift Online で使用可能なコンテナーイメージの作成およびテストに関するベストプラクティスを説明します。

第2章 ガイドライン

2.1. 概要

OpenShift Online で実行するコンテナーイメージを作成する場合には、イメージの作成者は、イメージの使いやすさの点で数多くのベストプラクティスを考慮する必要があります。イメージは変更不可で、そのままの状態で使用されることが意図されているため、以下のガイドラインは、イメージを使用しやすく、OpenShift Online で簡単に使用できるようにするのに役立ちます。

2.2. コンテナーイメージについての一般的なガイドライン

以下のガイドラインは、イメージが OpenShift Online で使用されるかどうかにかかわらず、コンテナーイメージの作成時に一般的に適用されます。

イメージの再利用

可能な場合は、FROM ステートメントを使用し、適切なアップストリームイメージをベースとしてイメージを設定することを推奨します。これにより、依存関係を直接更新する必要なく、イメージが更新時にアップストリームイメージからセキュリティー修正を簡単に取得できるようになります。

さらに、FROM 命令 (例: rhel:rhel7) のタグを使用して、お使いのイメージがどのバージョンのイメージをベースとしているかを明確にします。アップストリームイメージの latest バージョンを使用すると互換性に影響のある変更が組み込まれる可能性があるため、latest 以外のタグを使用することができます。

タグ内の互換性の維持

独自のイメージにタグを付ける場合には、タグ内で後方互換性が維持されるようにすることを推奨します。たとえば、foo という名前のイメージがあり、現時点でバージョン 1.0 が含まれている場合には、タグに foo:v1 を指定します。イメージの更新時には、元のイメージとの互換性がある限り、新しいイメージに foo:v1 のタグを付けることができ、このタグのダウンストリームのコンシューマーは、互換性に関する影響を被ることなく更新を取得できるようになります。

互換性のない更新を後にリリースした場合には、foo:v2 などの新しいタグに切り替える必要があります。これにより、ダウンストリームのコンシューマーはいつでも新しいバージョンに移行できますが、意図せずにこの互換性のない新規イメージによる影響を受けることはありません。foo:latest を使用するダウンストリームコンシューマーには、互換性のない変更が導入されるリスクがあります。

複数プロセスの回避

データベースや SSHD など複数のサービスを 1 つのコンテナー内で起動しないようにしてください。コンテナーは軽量で、複数のプロセスをオーケストレーションするために簡単にリンクできるので、複数プロセスの実行は不要です。OpenShift Online では、関連のあるイメージを 1 つの Pod にグループ化して、簡単に共存させ、共同管理することができます。

この共存により、コンテナーがネットワークの namespace とストレージを通信用に共有できるようになります。また、イメージの更新頻度が低く、個別に更新されるので、更新による中断の可能性が低くなります。シグナル処理のフローは、生成されたプロセスへのルーティングシグナルを管理する必要がないため、単一プロセスの場合により明確になります。

ラッパースクリプトでの exec の使用

詳細は、Project Atomic ドキュメントの「Always exec in Wrapper Scripts」セクションを参照してください。

また、コンテナー内で実行すると、プロセスは PID 1 として実行される点に留意してください。つまり、主なプロセスが中断された場合には、コンテナー全体が停止され、PID 1 プロセスから起動した子プロセスが終了します。

その他の影響については、Docker and the PID 1 zombie reaping problem のブログ記事を参照してください。また、PID 1 および init システムの詳細については、Demystifying the init system (PID 1) のブログ記事も参照してください。

一時ファイルの消去

ビルドプロセスで作成される一時ファイルはすべて削除する必要があります。これには、ADD コマンドで追加したファイルも含まれます。たとえば、yum install の操作を実行してから、yum clean コマンドを実行することを強く推奨します。

yum キャッシュがイメージレイヤーに残らないように、以下のように RUN ステートメントを作成します。

RUN yum -y install mypackage && yum -y install myotherpackage && yum clean all -y

以下のように記述した場合には注意してください。

RUN yum -y install mypackage
RUN yum -y install myotherpackage && yum clean all -y

上記のように記述すると、最初の yum 呼び出しにより、対象のレイヤーに追加のファイルが残り、yum clean 操作を後に実行してもこれらのファイルは削除できません。これらの追加ファイルは最終イメージでは確認できませんが、下位レイヤーには存在します。

現在の Docker ビルドプロセスでは、前のレイヤーで何かが削除された場合でも、後のレイヤーでコマンドを実行してイメージが使用する容量を縮小できません。ただし、これについては今後変更される可能性はあります。後のレイヤーでファイルが表示されていなくても rm コマンドを実行したとしても、ダウンロードするイメージの全体のサイズを縮小することになりません。そのため、yum clean の場合のように、可能な場合は後にレイヤーに書き込まれないように、ファイルの作成に使用したのと同じコマンドでファイルを削除することが最も適切と言えます。

また、単一の RUN ステートメントで複数のコマンドを実行すると、イメージのレイヤー数が減り、ダウンロードと実行時間が短縮されます。

適切な順序での命令の指定

Docker は Dockerfile を読み取り、トップダウンで命令を実行します。命令が正常に実行されると、同じイメージが次回ビルドされるときや、別のイメージがビルドされる時に再利用することができるレイヤーが作成されます。Dockerfile の上部にほとんど変更されない命令を配置することは非常に重要です。こうすることで、上位レイヤーで加えられた変更によってキャッシュが無効にならないので、同じイメージの次回のビルドをすばやく実行できます。

たとえば、反復するファイルをインストールするための ADD コマンドと、パッケージを yum install する RUN コマンドが含まれる Dockerfile で作業を行う場合には、ADD コマンドを最後に配置することが最善の方法です。

FROM foo
RUN yum -y install mypackage && yum clean all -y
ADD myfile /test/myfile

これにより、myfile を編集して、 docker build を返すたびに、システムは yum コマンドのキャッシュされたレイヤーを再利用し、ADD 操作に対してのみ新規レイヤーを生成します。

以下のように Dockerfile を記述した場合:

FROM foo
ADD myfile /test/myfile
RUN yum -y install mypackage && yum clean all -y

次に、myfile を変更して、docker build を再実行するたびに、ADD 操作は RUN 階層キャッシュを無効にするので、yum 操作も再実行する必要があります。

重要なポートへのマーキング

詳細は、『Project Atomic ドキュメント』の「Always EXPOSE Important Ports」のセクションを参照してください。

環境変数の設定

ENV 命令で環境変数を設定することが適切です。一例として、プロジェクトのバージョンを設定することなどが挙げられます。これにより、Dockerfile を確認せずにバージョンを簡単に見つけ出すことができます。別の例としては、JAVA_HOME など、別のプロセスで使用可能なシステムでパスを公開する場合などです。

デフォルトパスワードの回避

デフォルトのパスワードは設定しないことが最善の策です。イメージを拡張して、デフォルトのパスワードを削除または変更するのを忘れることが多くあります。これは、実稼働環境で使用するユーザーに誰でも知っているパスワードが割り当てられると、セキュリティーの問題に発展する可能性があります。パスワードは、環境変数を使用して設定できるようにする必要があります。詳細は、設定での環境変数の使用についてのトピックを参照してください。

デフォルトのパスワードを設定することにした場合には、コンテナーの起動時に適切な警告メッセージが表示されるようにしてください。メッセージはデフォルトパスワードの値をユーザーに通知し、環境変数の設定など、パスワードの変更方法を説明するものである必要があります。

SSHD の回避

イメージでの SSHD の実行を回避するようにしてください。ローカルホストで実行中のコンテナーにアクセスするには、docker exec コマンドを使用できます。または、oc exec コマンドまたは oc rsh コマンドを使用して OpenShift Online クラスターで実行されているコンテナーにアクセスできます。イメージを使用して SSHD をインストール、実行すると、攻撃の経路が増え、セキュリティー修正が必要になります。

永続データ向けのボリュームの使用

イメージは、永続データ用に Docker ボリューム を使用する必要があります。こうすることで、OpenShift Online により、コンテナーを実行するノードにネットワークストレージがマウントされ、コンテナーが新しいノードに移動した場合に、ストレージはそのノードに再度割り当てられます。永続ストレージのすべての要件に対応するようにボリュームを使用することで、コンテナーが再起動されたり、移動されたりしても、コンテンツは保存されます。イメージがコンテナー内の任意の場所にデータを書き込む場合には、コンテンツは保存されない可能性があります。

コンテナーが破棄された後も保存する必要のあるデータはすべて、ボリュームに書き込む必要があります。Docker 1.5 では、コンテナーに readonly フラグが使用され、これにより、コンテナーの一時ストレージにデータが記述されないようにすることができます。イメージをこの機能に基づいて設計すると、この機能を後に利用することがより簡単になります。

さらに、Dockerfile でボリュームを明示的に定義すると、イメージの利用者がイメージの実行時に定義する必要のあるボリュームがどれかを簡単に理解できるようになります。

OpenShift Online でのボリュームの使用方法についての詳細は、Kubernetes ドキュメントを参照してください。

注記

永続ボリュームでも、イメージの各インスタンスには独自のボリュームがあり、ファイルシステムはインスタンス間で共有されません。つまり、ボリュームを使用してクラスターの状態を共有できません。

外部のガイドライン

他のガイドラインについては、以下の資料を参照してください。

2.3. OpenShift Online 固有のガイドライン

以下は、OpenShift Online で使用するためのコンテナーイメージの作成時に適用されるガイドラインです。

権限およびボリュームビルド

Docker イメージは、DOCKERFILEVOLUME ディレクティブを使用してビルドすることはできません。読み取り/書き込みファイルシステムを使用するイメージは、ローカルストレージの代わりに永続ボリュームまたは emptyDir ボリュームを使用する必要があります。Dockerfile でボリュームを指定する代わりに、ローカルストレージのディレクトリーを指定し、Pod のデプロイ時に永続ボリュームまたは emptyDir ボリュームをそのディレクトリーにマウントします。

Source-To-Image (S2I) 向けのイメージの有効化

開発者が提供した Ruby コードを実行するように設計された Ruby イメージなど、サードパーティー提供のアプリケーションコードを実行することが目的のイメージの場合には、イメージを Source-to-Image (S2I) ビルドツールと連携できるようにすることができます。S2I は、インプットとして、アプリケーションのソースコードを受け入れるイメージを簡単に記述でき、アセンブルされたアプリケーションをアウトプットとして実行する新規イメージを簡単に生成することができるフレームワークです。

たとえば、この Python イメージは S2I スクリプトを定義して、Python アプリケーションのさまざまなバージョンをビルドします。

イメージ用に S2I スクリプトを記述する方法については、「S2I 要件」のトピックを参照してください。

任意のユーザー ID のサポート

デフォルトで、OpenShift Online は、任意に割り当てられたユーザー ID を使用してコンテナーを実行します。こうすることで、コンテナーエンジンの脆弱性が原因でコンテナーから出ていくプロセスに対して追加のセキュリティーを設定でき、ホストノードでパーミッションのエスカレーションが可能になります。

イメージが任意ユーザーとしての実行をサポートできるように、イメージ内のプロセスで記述される可能性のあるディレクトリーやファイルは、root グループが所有し、このグループに対して読み取り/書き込みの権限を割り当てる必要があります。実行予定のファイルには、グループの実行権限も必要です。

以下を Dockerfile に追加すると、root グループのユーザーがビルドされたイメージでアクセスできるように、ディレクトリーおよびファイルのパーミッションが設定されます。

RUN chgrp -R 0 /some/directory && \
    chmod -R g=u /some/directory

コンテナーユーザーは常に root グループのメンバーであるため、コンテナーユーザーはこれらのファイルに対する読み取り、書き込みが可能です。root グループには、(root ユーザーのように) 特別なパーミッションがないので、この設定ではセキュリティーに関する懸念点はありません。さらに、コンテナーで実行中のプロセスは、特権のあるユーザーとして実行されていないので、特権のあるポート (1024 未満のポート) をリッスンできません。

コンテナーのユーザー ID が動的に生成されるので、/etc/passwd に関連のあるエントリーがありません。これが原因で、ユーザー ID を検索する必要のあるアプリケーションで問題が発生する可能性があります。この問題に対応するには、イメージの起動スクリプトの一部として、コンテナーのユーザー ID を指定した passwd のファイルエントリーを動的に作成します。Dockerfile の内容は、以下のようになります。

RUN chmod g=u /etc/passwd
ENTRYPOINT [ "uid_entrypoint" ]
USER 1001

uid_entrypoint には、以下を含めてください。

if ! whoami &> /dev/null; then
  if [ -w /etc/passwd ]; then
    echo "${USER_NAME:-default}:x:$(id -u):0:${USER_NAME:-default} user:${HOME}:/sbin/nologin" >> /etc/passwd
  fi
fi

最後に、Dockerfile の最後の USER 宣言では、ユーザー名ではなく、ユーザー ID (数値) を指定してください。こうすることで、OpenShift Online は、イメージが実行時に使用しようとしている認証を検証でき、root ユーザーでのイメージの実行を防ぐことができます。特権のあるユーザーがコンテナーを実行するとリスクが発生するためです。イメージが USER を指定しない場合、親イメージから USER を継承します。

イメージ内の通信でのサービスの使用

データの保存や取得のためにデータベースイメージにアクセスする必要のある Web フロントエンドイメージなど、別のイメージが提供するサービスとイメージが通信する場合には、イメージは OpenShift Online サービスを使用する必要があります。サービスは、コンテナーが停止、開始、または移動しても変更されない静的アクセスエンドポイントを提供します。さらに、サービスにより、要求が負荷分散されます。

共通ライブラリーの提供

サードパーティーが提供するアプリケーションコードの実行を目的とするイメージの場合は、プラットフォーム用として共通に使用されるライブラリーをイメージに含めるようにしてください。とくに、プラットフォームで使用する共通のデータベース用のデータベースドライバーを設定してください。たとえば、Java フレームワークイメージを作成する場合に、MySQL や PostgreSQL には JDBC ドライバーを設定します。このように設定することで、アプリケーションのアセンブリー時に共通の依存関係をダウンロードする必要がなくなり、アプリケーションイメージのビルドがスピードアップします。また、すべての依存関係の要件を満たすためのアプリケーション開発者の作業が簡素化されます。

設定での環境変数の使用

イメージのユーザーは、ダウンストリームイメージをイメージに基づいて作成しなくても、イメージの設定が行えるようにしてください。つまり、ランタイム設定は環境変数を使用して処理される必要があります。単純な設定の場合、実行中のプロセスは環境変数を直接使用できます。より複雑な設定や、これをサポートしないランタイムの場合、起動時に処理されるテンプレート設定ファイルを定義してランタイムを設定します。このプロセス時に、環境変数を使用して渡される値は設定ファイルで置き換えることも、この値を使用して、設定ファイルに指定するオプションを決定することもできます。

環境変数を使用して、コンテナーに証明書やキーなどのシークレットを渡すこともでき、これは推奨されています。環境変数を使用することで、シークレット値がイメージにコミットされたり、Docker レジストリーに漏洩されることはありません。

環境変数を指定することで、イメージの利用者は、イメージ上に新しいレイヤーを作成することなく、データベースの設定、パスワード、パフォーマンスチューニングなどの動作をカスタマイズできます。Pod の定義時に環境変数の値を定義するだけで、イメージの再ビルドなしに設定を変更できます。

非常に複雑なシナリオの場合、ランタイム時にコンテナーにマウントされるボリュームを使用して設定を指定することも可能です。ただし、この方法を使用する場合には、必要なボリュームや設定が存在しない場合に明確なエラーメッセージが起動時に表示されるように、イメージが設定されている必要があります。

このトピックは、サービスエンドポイントの情報を渡す環境変数としてデータソースなどの設定において、 イメージ間の通信でのサービスの使用についてのトピックと関連しています。これにより、アプリケーションは、アプリケーションイメージを変更せずに、OpenShift Online 環境に定義されているデータソースサービスを動的に使用できます。

さらに、コンテナーの cgroups 設定を確認して、調整を行う必要があります。これにより、イメージは利用可能なメモリー、CPU、他のリソースに合わせてチューニングが可能になります。たとえば、Java ベースのイメージは、制限を超えず、メモリー不足のエラーが表示されないように、cgroup の最大メモリーパラメーターを基にヒープをチューニングする必要があります。

Docker コンテナーの cgroup クォータを管理する方法については、以下の資料を参照してください。

イメージメタデータの設定

イメージのメタデータを定義することで、OpenShift Online によるコンテナーイメージの使用が改善され、開発者が OpenShift Online でイメージを使用しやすくなります。たとえば、メタデータを追加して、イメージに関する役立つ情報を提供したり、必要とされる可能性のある他のイメージを提案したりできます。

サポートされるメタデータや、定義の方法に関する詳細は、「イメージのメタデータ」のトピックを参照してください。

クラスタリング

イメージの複数のインスタンスを実行するとはどういうことかを十分に理解しておく必要があります。最も単純な例では、サービスの負荷分散機能は、イメージのすべてのインスタンスにトラフィックをルーティングします。ただし、セッションの複製などで、リーダーの選択やフェイルオーバーの状態を実行するには、多くのフレームワークが情報を共有する必要があります。

OpenShift Online での実行時に、インスタンスでこのような通信を実現する方法を検討します。Pod 同士は直接通信できますが、Pod が起動、停止、移動するたびに IP アドレスが変更されます。そのため、クラスタリングスキームを動的にしておくことが重要です。

ロギング

すべてのロギングを標準出力に送信することが推奨されます。OpenShift Online はコンテナーから標準出力を収集し、表示が可能な中央ロギングサービスに送信します。ログコンテンツを分離する必要がある場合には、出力のプレフィックスに適切なキーワードを指定して、メッセージをフィルタリングできるようにしてください。

お使いのイメージがファイルにロギングをする場合には、手動で実行中のコンテナーに入り、ログファイルを取得または表示する必要があります。

Liveness および Readiness プローブ

イメージで使用可能な liveness および readiness プローブの例をまとめます。これらのプローブにより、処理の準備ができるまでトラフィックがコンテナーにルーティングされず、プロセスが正常でない状態になる場合にコンテナーが再起動されるので、ユーザーはイメージを安全にデプロイできます。

テンプレート

イメージと共にテンプレートサンプルを提供することを検討してください。テンプレートがあると、ユーザーは、正しく機能する設定を指定してイメージをすばやく簡単にデプロイ できるようになります。完全を期すため、テンプレートには、イメージに関連して記述した liveness および readiness プローブを含めるようにしてください。

2.4. 外部の参考資料

第3章 イメージのメタデータ

3.1. 概要

イメージのメタデータを定義することで、OpenShift Online によるコンテナーイメージの使用が改善され、開発者が OpenShift Online でイメージを使用しやすくなります。たとえば、メタデータを追加して、イメージに関する役立つ情報を提供したり、必要とされる可能性のある他のイメージを提案したりできます。

このトピックでは、現在の一連のユースケースに必要なメタデータのみを定義します。他のメタデータまたはユースケースは、今後追加される可能性があります。

3.2. イメージメタデータの定義

DockerfileLABEL 命令を使用して、イメージのメタデータを定義することができます。ラベルは、イメージやコンテナーに割り当てるキーと値のペアである点が環境変数に似ています。ただし、ラベルは、実行中のアプリケーションに表示されず、イメージやコンテナーをすばやく検索する場合にも使用できる点で、環境変数とは異なります。

LABEL 命令に関する詳細は、Docker ドキュメントを参照してください。

ラベル名には、通常 namespace を指定する必要があります。namespace は、対象のラベルを選択して使用するプロジェクトを反映するように設定してください。OpenShift Online の場合は、namespace は io.openshift に、Kubernetes の場合は、namespace は io.k8s に設定してください。

形式に関する詳細は、Docker のカスタムメタデータに関するドキュメントを参照してください。

表3.1 サポートされるメタデータ

変数説明

io.openshift.tags

このラベルには、カンマ区切りの文字列値の一覧として表現されているタグの一覧が含まれます。タグを使用して、コンテナーイメージを幅広い機能エリアに分類します。タグを使用すると、UI および生成ツールがアプリケーションの作成プロセスで適切なコンテナーイメージを提案しやすくなります。

LABEL io.openshift.tags   mongodb,mongodb24,nosql

io.openshift.wants

コンテナーイメージにすでにタグが指定されていない場合に、生成ツールと UI が適切な提案を行うのに使用するタグの一覧を指定します。たとえば、コンテナーイメージに mysqlredis が必要で、コンテナーイメージに redis タグが指定されていない場合には、UI はこのイメージをデプロイメントに追加するように提案する可能性があります。

LABEL io.openshift.wants   mongodb,redis

io.k8s.description

このラベルは、コンテナーイメージの利用者に、このイメージが提供するサービスや機能に関する詳細情報を提供するのに使用できます。UI は、この説明とコンテナーイメージ名を使用して、人間が解読しやすい情報をエンドユーザーに提供します。

LABEL io.k8s.description The MySQL 5.5 Server with master-slave replication support

io.openshift.non-scalable

イメージは、この変数を使用して、スケーリングがサポートされていない旨を示します。その後、UI はこれをそのイメージのコンシューマーに通知します。スケーリング不可にした場合は基本的に replicas の値を最初に 1 よりも大きい値に設定することはできません。

LABEL io.openshift.non-scalable     true

io.openshift.min-memory および io.openshift.min-cpu

このラベルは、コンテナーイメージが正しく機能するにはどの程度リソースが必要かを提案します。UI でユーザーに対し、このコンテナーイメージをデプロイすると、ユーザークォータを超過する可能性があることを警告します。この値は、Kubernetes の数量と互換性がある必要があります。

LABEL io.openshift.min-memory 8Gi
LABEL io.openshift.min-cpu     4

第4章 S2I の要件

4.1. 概要

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

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

4.2. ビルドプロセス

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

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

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

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

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

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

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

4.3. 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

表4.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. イメージを実行して、テストアプリケーションが機能していることを確認します。

詳細は、「S2I イメージのテスト」のトピックを参照してください。

注記

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

S2I スクリプトの例

注記

以下の例は Bash で記述されており、tar の内容はすべて /tmp/s2i ディレクトリーに展開されることが前提です。

例4.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

例4.2 run スクリプト:

#!/bin/bash

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

例4.3 save-artifacts スクリプト:

#!/bin/bash

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

例4.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

4.4. ONBUILD 命令でのイメージの使用

ONBUILD 命令は、正式な Docker イメージの多くに含まれています。以下は例になります。

  • Ruby
  • Node.js
  • Python

ONBUILD に関する詳細は、Docker ドキュメントを参照してください。

S2I は、開始されると、S2I プロセスでビルドインプットの注入に必要とされる shtar バイナリーが、ビルダーイメージに含まれているかどうかを検出します。ビルダーイメージでこれらの要件が満たされていない場合には、代わりにインプットを階層化するコンテナービルドの実行を試みます。ビルダーイメージに ONBUILD 命令が含まれる場合には、ONBUILD 命令が階層化プロセス中に実行され、S2I ビルドよりセキュリティーが低い一般的なコンテナーが実行されるのと同等で、明示的なパーミッションが必要となるので、S2I ではビルドが失敗します。

このように、S2I ビルダーイメージに ONBUILD 命令が含まれていないことを確認するか、shtar バイナリーの要件が満たされていることを確認してください。

4.5. 外部の参考資料

第5章 S2I イメージのテスト

5.1. 概要

Source-to-Image (S2I) ビルダーイメージの作成者は、S2I イメージをローカルでテストして、自動テストや継続的な統合に OpenShift Online ビルドシステムを使用できます。

注記

続行する前に、S2I アーキテクチャーの詳細について、「S2I 要件」のトピックを参照してください。

S2I 要件」のトピックに説明されているように、S2I ビルドを正常に実行するには、S2I に assemblerun スクリプトが必要です。S2I 外のコンテナーイメージを実行した場合に、save-artifacts スクリプトがあると、ビルドのアーティファクトが再利用され、usage スクリプトがあると、使用についての情報がコンソールに出力されるようになります。

S2I イメージのテストは、ベースのコンテナーイメージを変更したり、コマンドが使用するツールが更新されたりした場合でも、上記のコマンドが正しく機能することを確認するのが目的です。

5.2. テストの要件

test スクリプトは、基本的に test/run に配置されます。このスクリプトは、OpenShift Online S2I イメージビルダーが呼び出し、単純な Bash スクリプトか静的な Go バイナリーのいずれかの形式を取ることができます。

test/run スクリプトは S2I ビルドを実行するので、S2I バイナリーを $PATH で利用可能にしておく必要があります。必要に応じて、S2I README のインストール手順に従います。

S2I は、アプリケーションのソースコードおよびビルダーイメージを統合します。これをテストするには、ソースが実行可能なコンテナーイメージに変換されることを検証するためのサンプルアプリケーションのソースが必要です。サンプルアプリケーションは単純なものである必要がありますが、assemble および run スクリプトの重要な手順を実行できる必要があります。

5.3. スクリプトおよびツールの生成

S2I ツールは、新しい S2I イメージの作成プロセスを加速化する強力な生成ツールと共に提供されます。s2i create コマンドでは、Makefile 以外に、必要とされる S2I スクリプトとテストツールすべてが生成されます。

生成された test/run スクリプトは、より使いやすくするために調整する必要がありますが、このスクリプトを開発の開始段階で使用することが推奨されます。

注記

s2i create コマンドで生成した test/run スクリプトでは、サンプルアプリケーションのソースを test/test-app ディレクトリーに配置しておく必要があります。

法律上の通知

Copyright © 2020 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, the Red Hat logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.