CI/CD Advent Calendar 2019 の 7日目
数日前に書いた記事のQiita向け調整版です。
AWS CLI on Alpine Docker Image 自動更新ビルド with Concourse - designetwork
ConcourseでのAWS関連作業用コンテナとして、AWS CLIのDocker Imageをビルドする。ビルドにはConcourse CIを使用することで継続的に更新し続ける仕組みを作る。
最終的な成果物としてのDocker Imageはこちら daichi703n/awscli
使い慣れているConcourseで仕組みを作ることができたので、他ツールのDocker Imageにも展開していきたい。
※試験的な実装部分も多いため、改善点等ありましたらご指摘ください。
- モチベーション
- アーキテクチャ
- Concourse Pipeline実装
- DockerHub - GitHub連携時のバージョン環境変数
- Docker in Docker構成
- TODO
- まとめ - CI/CD for CI/CDs Dockerイメージの継続的最新化 with ConcourseCI
モチベーション
- Concourseで各種Docker Imageを使用する際に、できるだけ最新にしておきたい。
- パッケージだけでなく、ベースイメージも基本的に最新にしておきたい。
- Docker HubのリポジトリでPull数の多いリポジトリでも未更新が多く悩ましい...
- 最新Docker Imageがいわゆる腐ってる状態で使えなくなるケースがある。
- Kubernetesなどの環境向けにDocker Image自動更新の仕組みを作っておきたい。
アーキテクチャ
全体の構成は以下の通り。
DockerHub (ベースイメージ)、パッケージ (PyPIリポジトリ) を監視し、新しいリリースがあったら取り込んでビルド・テスト・プッシュする。
更新検知
更新のトリガーは以下の2つ
- PyPI awscli Release
- DockerHub alpine:latest
Concourseでそれぞれ以下のresourceを使用して監視する。
Concourse Pipeline実装
作成したConcourse Pipelineはこちら
Job分割
Concourseでは大きく3つのJobに分けてPipelineを実装した。
- detect, build, push(dev release)
- test
- push(latest & tags), git commit(master & version tag)
1つのJobの中でtaskを分けて同様実装も可能だが、パイプラインっぽさ重視で分けた。疎結合なので他への展開もしやすいはず。
Detect, Build, Push
Detectでは、Concourseの各種Resource(DockerHub, GitHub, PyPI)を使用して新規バージョンのリリースを検知する。
最新バージョンを検知したら、Dockerfileに従って最新候補のDocker Image(develop)をビルドする。
ビルドが正常に完了したら、develop
タグでDocker ImageをDockerHubにpushする。
Test
ここを充実させるのが重要項目のひとつでもある。developとしてビルドしたイメージが期待通り動作することをテストする。docker-test.sh
として保証動作のテストをシェルスクリプトで作成する。テスト失敗時はここで終了し、latest
は据え置きなので、自動・定常運用への影響は発生しない。
awscliに関しては以下のテストを実装している。
Test Command | Note |
---|---|
aws --version | |
aws ec2 describe-instances | |
aws ec2 run-instances | |
aws ec2 terminate-instances | |
aws s3 ls | |
aws s3 mb | |
aws s3 cp local s3://xxx | |
aws s3 cp s3://xxx local | |
aws s3 rb |
Push, Git Commit
Testがパスしたら、各種タグを設定しDockerHubにプッシュする。latestに関してはDockerHubとGitHubの連携による自動ビルドを使用する。
version name(Tag) | Static/Dynamic | meaning |
---|---|---|
latest | Dynamic | Latest Build (with latest awscli & alpine version) (Automated Build by Docker Hub) |
x.x | Dynamic | AWS CLI minor version (with latest alpine version) |
x.x.x | Dynamic | AWS CLI patch version (with latest alpine version) |
x.x.x-alpinex.x.x | Static | AWS CLI patch version (with all alpine patch version) |
GitHub Commitはsemver resourceを使用して運用することもできるが、今回は手動(shellスクリプト)による実装とした。
- Git Commit
- Update versions file
- Tagging version
- Merge to master
DockerHub - GitHub連携時のバージョン環境変数
Dockerfile自体は汎用的にするために、awscliのバージョンを環境変数定義+ARG
, --build-arg
で設定している。DockerHubが自動的にイメージをビルドする際にも同様の設定が必要となるため、hooks/build
(https://github.com/daichi703n/docker-awscli/blob/master/awscli/hooks/build) を使用して、versionsに書き出したバージョン記載ファイルから読み込むよう、Dockerビルドコマンドを上書きしている。
Docker in Docker構成
ConcourseのTaskの中でDockerを扱う場合は、Docker in Dockerの構成となる。こちらを参考にdocker-lib.sh
を実装し動作できているが、仕様を理解できていない部分が多い...
TODO
- 脆弱性診断
- task shellを別ファイルにする
- docker pullなどはresourceでできるのでは?
REPOSITORY LINKS
を使えば自動的にbase imageを追従してくれるかも
まとめ - CI/CD for CI/CDs Dockerイメージの継続的最新化 with ConcourseCI
パッケージ・ベースイメージの更新を検知して、Docker Imageをビルド・テストするConcourseパイプラインを作成した。数日稼働させてみて正常に動作することを確認できている。
これからも各種ツールの同様パイプラインを整備していきたい。