Red Hat Training

A Red Hat training course is available for Red Hat Enterprise Linux

第3章 コンテナーを最新かつ更新可能な状態にする

このセクションでは、コンテナーを最新で更新可能の状態にするプロセスと方法について説明します。

3.1. 素の Pull を FROM 命令に入れない

使用する FROM コマンドにプルするレジストリーを常に一覧表示します。つまり、Red Hat の場合は Red Hat Docker レジストリーの名前全体を組み込む必要があります。

以下は素の pull です。

$ docker pull rhel7

以下は素の pull ではありません。

$ docker pull registy.redhat.com/rhel7

3.2. yum update ツールの使用

ベースイメージが最新になるように yum update && yum clean all または同等のコマンドを常に実行します。これらのコマンドは、ベースイメージに関連付けられた RPM コンテンツを更新します。これにより、攻撃対象となる可能性のある領域が縮小します。

3.3. Docker キャッシュの活用

このセクションでは、Dockerfile をワークフローに合わせて効率化するために Docker キャッシュを使用する方法について説明します。

3.3.1. キャッシュを利用するための順序命令

Docker はそれぞれの命令が確定的であると仮定します。さらに Docker はこれらの命令には関連性がないと仮定します。Docker は同じ命令が同じ順序で出されると、結果をキャッシュします。つまり FROM foo: dnf -y update の命令が 2 つの同じ Dockerfile に同じ順序で存在する場合、Docker はその命令が出される時点から同じベースイメージを作成します。

Docker キャッシュを活用するには、Dockerfile によるインストールを常に同じ順序で実行してください。Docker のキャッシュユーティリティーを最大限に活用するには、タスクをテーマごとのコンポーネント (例: 「ユーザーの追加」または「ソフトウェアのアップグレード」) に分割してください。時間とリソースに余裕がある場合は Dockerfile スタイルガイドを作成することをお勧めします。

3.3.2. キャッシュを意図的に分割する必要のある状況

Docker のデフォルトのキャッシュ動作を無効にする必要がある状況があります。このセクションではどんな場合に何を実行する必要があるのかについて説明します。

次のシナリオを考えてみましょう。アップデートが必要であると認識しているものの、Docker は "yum update" が同じ状態を返すと誤って仮定しているため、そのアップデートは Dockerfile のアップデートでは扱われません。しかし、"yum update" は確定的なコマンドではないため、いつも同じ状態を返す訳ではありません。以下は、アップデートを強制実行する 3 つのメソッドです。(1) 単一マシンの場合は、イメージを削除し、再作成する。(2) キャッシュを意図的に分割する "echo uniquething" などのナンス (nonce) コマンドを挿入する。(3) OpenShift ビルドシステムのようなビルドシステムを使用する。このビルドシステムはこの問題を認識して OSBS (OpenShift ビルドシステム) から新規イメージを要求することを許可します。

3.4. コンテナーの出所の確認

コンテナーの出所を確認するためにできる最も簡単なことは、プライベートレジストリーを各自で実行することです。OpenShift および Satellite はどちらも、組み込みイメージサービスオプションを持つ Red Hat 製品です。お使いのイメージには機密情報を含めないことをお勧めします。機密情報がなければ、誰かがイメージをたまたま閲覧することがあっても問題にはなりません。つまり、TLS (トランスポート層セキュリティー) を常に使用する必要がありますが、認証を使用する必要はありません。機密情報として保持する必要のある情報はオーケストレーションレベルまで抽象化される必要があります。これについては、本書の Kubernetes および OpenShift のセクションで論じます。

3.4.1. レジストリーなしの Docker イメージの配布

レジストリーなしに Docker イメージを配布するための最も良い方法は何でしょうか。Docker イメージは "docker save" コマンドで作成され、"docker load" でロードされる tarball として配布できます。これらの出所のセキュリティーは、他のセキュリティー保護の場合と同様に署名付きハッシュを使用して保護できます。

http://fedora.uberglobalmirror.com/fedora/linux//releases/21/Docker/x86_64/: fedora の場合、このリンクに示されるようにハッシュファイルとそのハッシュファイルに関連付けられた tarball があります。

3.5. コンテナーを不変にするために Kubernetes および OpenShift を活用する

不変性がセキュリティーにとって重要なのはなぜでしょうか。不変性により、ローカル侵害によって加えられる可能性のある損害が軽減されます。イメージ自体には秘密情報が含まれず、破損する可能性のある状態は保存されません。さらにそれらのイメージは変更されないため、確認が必要な箇所はわずかになります。

(この文脈での「不変 (immutable)」とは、変更される状態を持たないコンテナーを意味します。)

3.5.1. Kubernetes および OpenShift を活用する方法

このセクションでは、不変な (ステートレスな) コンテナーイメージを作成するために Kubernetes および OpenShift を活用する方法について説明します。

  1. ボリュームマウントの使用: 変更可能な外部データ (WordPress コンテンツまたはデータベースなど) を取り込みます。
  2. サービスの使用: Kubernetes および OpenShift にはマッチメイキング (matchmaking) サービスがあります。コンテナーは、一般的にデータベースに依存させるように設計でき、その場合データベースへのログインの詳細情報はランタイム時に提供されます。
  3. テンプレートの作成: これは上記のアイデアと同じですが、ビルド時に適用されます。コンテナーが特定のクラスターを実行するためにユーザーに特定の UID を持たせる必要がある場合、Dockerfile ではこれを実行することができません。このタスクを実行する必要がある場合は、OpenShift ビルドシステムへのプラグインを使用して所定のビルドをカスタマイズすることができます。
  4. Github リポジトリーの使用: docker pull を使用して、ランタイム時にプライベートまたはパブリック git リポジトリーのライブコンテンツをプルします。OpenShift には、これをさらに別のレベルへと引き上げる機能があります。これらの機能により、すべてのコンテナー詳細情報を無視し、すべての詳細情報が github リポジトリーでホストされるアプリケーションを使用できます。

3.5.2. コンテナーが秘密情報または機密情報を保存しないように Kubernetesを活用する

Kubernetes には、メモリーでホストされる秘密情報をランタイム時に仮想ファイルとして挿入する「シークレット (secrets)」機能があります。これは、認証の詳細情報や暗号化キーなどのすべての秘密情報に使用されます。