ビルドは一度だけ!
継続的デリバリを実現するための鉄則の一つに「バイナリのビルドは一度だけ!」というものがあります。しかし、ソースコードリポジトリに登録されているソースコードを正として、ビルドやデプロイを行うツールを利用している場合には、この鉄則の実現が難しくなります。
OpenShiftでは、ビルド済みの Docker Image をバージョン管理しているので、「ビルドは一度だけ!」を容易に実現可能です。
ということで、OpenShift v3その実現方法をご紹介します。
「ビルドは一度だけ!」を実現するためのOpenShiftの概念
ImageStream
OpenShiftにデプロイするアプリケーションのDockerイメージへの参照。SCMのブランチのようなイメージで利用可能。
ServiceAccount
OpenShift APIを利用する権限を持つオブジェクト。Podのビルドを実行するsystem:image-builder
権限を持つbuilder
、Podのデプロイをするsystem:deployer
権限をもつdeployer
、builder, deployer以外のすべての権限をもつdefault
がある。
手順
アプリケーションの作成
ビルドは一度だけを実現するために元となるプロジェクトとアプリケーションを作成します。
1. テスト用プロジェクト(hello)の作成
oc new-project hello
2. アプリケーションの作成
oc new-app https://github.com/akubicharm/php-hello-world.git
3.ルーティングの設定と確認
oc expose service php-hello-world --hostname=php-hello-world.hello.apps.cloud
curl php-hello-world.hello.apps.cloud
「Hello World」と出力されれば OK です。
ビルド済みイメージをデプロイするプロジェクト(hello-prod)の作成
OpenShift v3.0.2.0 では、異なるプロジェクトのImageStreamを利用してアプリケーションがデプロイできるようになりました。
1. プロジェクトの作成
oc new-project prod-hello
2. helloプロジェクトのポリシーの確認
oc describe policyBindings :default -n hello
system:image-pullers ロールに Service Account が設定されていません。
RoleBinding[system:image-pullers]:
Role: system:image-puller
Users: <none>
Groups: system:serviceaccounts:hello
ServiceAccounts: <none>
Subjects: <none>
3.prod-hello プロジェクトに権限の付与
oc policy add-role-to-user system:image-puller system:serviceaccount:prod-hello:default -n hello
prod-helloプロジェクトのdefaultサービスアカウントにimage-pullerロールが付与されました。これでprod-helloプロジェクトはアプリケーションのデプロイ時にhelloプロジェクトのImageStreamを利用することができるようになります。
RoleBinding[system:image-pullers]:
Role: system:image-puller
Users: <none>
Groups: system:serviceaccounts:hello
ServiceAccounts:prod-hello/default
Subjects: <none>
ビルド済みイメージからのアプリケーションのデプロイ
1. テスト用プロジェクトからテンプレート作成
helloプロジェクトからアプリケーションのテンプレートを作成します。ビルドは行う必要がないので、buildConfigはエクスポート対象から除外し、deploymentConfig, service, route のみをエクスポートします。
oc export deploymentConfig,service,route -o yaml --as-template=php-hello-world > prod-php-hello-world.yaml
テンプレートの ImageStreamのタグとルーティングの設定を編集します。
perl -i -pe 's/name: php-hello-world:latest/name: php-hello-world:prod-hello/g' prod-php-hello-world.yaml
perl -i -pe 's/php-hello-world.hello.apps.cloud/php-hello-world.prod.apps.cloud/g' prod-php-hello-world.yaml
この段階ではhello-prod
というタグの付いた php-hello-worldのImageStreamがまだないので、デプロイはされません。
2. プロダクション用プロジェクトへアプリケーションのデプロイ
oc project prod-hello
oc new-app -f prod-php-hello-world.yaml
3. ImageStream の確認
oc project hello
oc get imageStream
oc describe is php-hello-world
Name: php-hello-world
Created: 28 minutes ago
Labels: app=php-hello-world
Docker Pull Spec: 172.30.131.34:5000/hello/php-hello-world
Tag Spec Created PullSpec Image
latest <pushed> 26 minutes ago 172.30.131.34:5000/hello/php-hello-world@sha256:a94f7113d501dea557c952886d099b59825ad14e2a3f25aa545fe0311aef7b4c
4. タグ付け
oc tag hello/php-hello-world@sha256:a94f7113d501dea557c952886d099b59825ad14e2a3f25aa545fe0311aef7b4c prod-hello/php-hello-world:prod
5. デプロイ
oc deploy prod-php-helo-world --latest -n prod-hello
これで、hello プロジェクトで動作確認されたアプリケーションをprod-helloにデプロイすることができました。 この後は、以下の手順を繰り返すことで「ビルドは一度だけ!」を実現できるようになります。
- ソースコードの変更
- hello プロジェクトのビルド
- hello プロジェクトでのテスト
- 最新のイメージへのタグ付け
修正履歴
- [2015/10/21] oc tag の第2引数を修正しました。他のプロジェクトで作成されたイメージを利用するには、[MyProjectName]/[Image Stream]:[tag] とする必要があります。