CodeBuild における DockerInDocker(dind) の活用

はじめに

必要なリソースを短時間で起動させて使用が終わったら破棄できる Docker 等のコンテナ環境は、以前のコンピューティング環境に無かった利便性をもたらしました。開発者環境において活用されるケースも多いのではないかと思います。

AWS では、"AWS 開発者用ツール" としてDevOps における様々な自動化を実現するためのツール群が提供されています。"AWS 開発者用ツール" のツール群の中で、CI/CD におけるアプリケーションのビルド/ユニットテストの機能を提供する CodeBuild においても、コンテナ環境を活用することが可能です。

本稿では、開発者環境でよくある Docker を使用したユニットテスト環境を、AWS CodeBuild を使用した CI/CD パイプラインにおいても活用できるかどうかを、AWS CodeBuild で実際に Docker コンテナ環境を起動させて確認してみます。

1. よくある開発者環境

開発/ユニットテスト用のデータストアとして、または、Webアプリ開発時のテスト環境として、などなど、開発者自身の作業端末上でコンテナ環境を活用されているケースは増加しているかと思います。以下のような、ソースからのビルド/ユニットテストは開発者端末のOS上で実行して、アプリランタイムが使用するデータストアはコンテナとして起動しているような開発環境も多いのではないでしょうか。場合によっては、コンテナが提供する仮想ネットワーク機能を使用して、プロダクションと同じネットワーク構成のコンテナ環境で結合テストまで実行するようなことも不可能ではありません。

図1-1. よくある開発者環境

 

本稿では、このような開発環境で使用されているコンテナを使用したユニットテストを、AWS CodeBuild へ組込む方法を確認してみたいと思います。

2. AWS CodeBuildへの、コンテナを使用したビルド/UTの組込み

AWS CodeBuild は、フルマネージド型のビルド環境を提供するサービスです。AWS コードサービスに含まれる AWS CodePipeline などと組み合わせて、CI/CD 環境を構築することができます。

CodeBuild のビルドやユニットテストが実行される環境はコンテナとして起動しています。上記のコンテナを使用した開発者環境と同じ構成でビルド/ユニットテストを実行するには、コンテナとして起動している CodeBuild の実行環境上へ、さらにコンテナ環境を起動させることになります。

 

図2-1. CodeBuild 上でのコンテナを使用したビルド/ユニットテストイメージ

 

CodeBuild のビルド/ユニットテスト実行環境のイメージは、Ubuntu 14/Docker 17 をベースとしたものが提供されています(2018/04 現在)。

以下のマニュアルに、Github 上で公開されている イメージ作成時に使用された Dockerfile を参照することができます。

マニュアル:
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-env-ref-available.html

 

図2-2. マニュアル: AWS CodeBuild に用意されている Docker イメージ

 

Dockerfile の内容を確認すると、以下のように Docker の実行エンジンがインストールされていることが判ります。

 

図2-3. CodeBuild/java 実行環境イメージの Dockerfile 抜粋

 

また、CodeBuild のビルド処理の実体となる "ビルドプロジェクト" の設定に、ビルド/ユニットテスト実行環境中でコンテナ環境を起動できるかどうかを指定する項目があります。コンテナ環境を起動させるには、以下のチェックを有効にしておく必要があります。

 

図2-4. CodeBuild の設定画面

3. 動作確認

では、実際に CodeBuild のビルド/ユニットテスト実行環境中でコンテナ環境を起動できるかどうかを確認してみます。

Docker hello-world のカスタムイメージを作成するソースと CodeBuild の処理を記載する buildspec.yml を含むリポジトリを Github 上に用意しました。(パブリックリポジトリですが、CodeBuild へ組込む際は Github のアカウントが必要になります。実際にお試しの際は Github のアカウントをご用意ください)

Github リポジトリ:
https://github.com/CI-CD-Lab/aws-codebuild-dind-simple-test.git

Dockerfile は、Docker hello-world イメージへダミーのテキストファイルをコピーしてカスタムイメージを作成する簡単なものです。CodeBuild の動作を記述する buildspec.yml は以下のようになっています。これらの操作(コンテナの起動)が、CodeBuild の処理を実行しているコンテナ上で実行されます。

  • install : 環境の確認 (OS環境と docker の version 確認)
  • pre_build : 作成されているコンテナの確認、登録されているイメージの確認と カスタムイメージのビルド
  • build: 作成したカスタムイメージから Docker コンテナを起動
  • post_build : 作成されているコンテナ、登録されているイメージの確認

 

図3-1. buildspec.yml

 

この Github プロジェクトのソースを clone して処理を行う CodeBuild プロジェクトを作成して、カスタムした hello-world イメージからコンテナ環境が起動するかどうかを見てみましょう。

まず、CodeBuild の設定、環境:ビルド方法 → 特権付与 にチェックを入れていない状態(CodeBuild の処理実行コンテナ内でコンテナの起動が許可されていない状態)でビルドプロジェクトを作成して実行してみます。

 

図3-2. CodeBuild の設定個所

 

この状態でビルドプロジェクトを実行すると、Docker はインストールされているものの、CodeBuild の処理実行コンテナ内で Docker エンジン自体が起動していないことがログから確認できます。

 

図3-3. CodeBuild プロジェクトのエラー画面

 

では、CodeBuild の設定、環境:ビルド方法 → 特権付与 にチェックを入れて、再度、ビルドプロジェクトを実行してみます。今度は カスタム hello-world イメージが作成されて起動されていることがログから確認できます。

 

図3-4. CodeBuild プロジェクトの実行成功時のログ画面

4. おわりに

本稿では、CodeBuild の ビルド/ユニットテストの際に、Docker コンテナを使用するための設定に関して確認してみました。

本稿では触れていませんが、ビルド/ユニットテストの際のログの確保方法に工夫が必要です。

開発環境上で起動させたコンテナであればユニットテスト後のデータの状況を後から確認するといったことも可能ですが、CodeBuild で実行する際は後から確認したい情報をコンソール出力するように buildspec.yml を調整しておく等のひと工夫が必要になります。

CodeBuild で、gradle から実行されるユニットテストレポートをどのようにすればエレガントに確保できるか、模索中の今日この頃。

著者プロフィール

著者アイコン
中島健
伊藤忠テクノソリュージョンズ株式会社在籍中 | 1. 現在の担当業務 : オンプレから クラウドネイティブ DevOps へ移行中のエンジニア
2. これまでの担当業務 : 商用/OSS のサーバサイドミドルウェア (なぜか OpenStack も) を担当
3. 最近の想い・考えていること : SE = Senior Engineer・・・ ("上級" じゃなくて "高齢者" のほう)

関連記事はこちら