コンテナ時代のDevOps 〜Azure Web Apps for Containers + Docker + Jenkins + SeleniumでイマドキのCI/CDをやってみる [実践編]〜

こんにちは、サイオステクノロジー技術部 武井です。全2回シリーズ「コンテナ時代のDevOps」第2回目は、Azure Web Apps for Containers + Docker + Jenkins + SeleniumでCI/CDを実践してみたいと思います。

※全シリーズの記事一覧はこちら

CI/CDの構成

本章では、今回、実践を行うCI/CDの構成をご説明します。

Screen Shot 2018-09-21 at 1.09.25

上図のそれぞれのフェーズの詳細を以下にご説明します。

※下記の数字は上図の数字に対応しております

(1) 開発エンジニアがソースをコミットします。
これは、開発エンジニアがバージョン管理システム(今回はGitHub)にソースコードをコミットする処理です。CI/CDのライフサイクルの起点はこの処理になり、人の手がかかるのはこの処理のみになります。これ以降の処理は、Jenkinsにより全て自動化されます。

(2) GitHubにソースがコミットされたことをwebhookでJenkinsに通知する。
GitHubのwebhookという機能を使って、GitHubにコミットされたことをトリガーにして、Jenkinsの特定のURLを叩きます。webhookとは、あるサービスに対して外部から何らかの操作が行われたとき、そのことを他のサービスにHTTP経由で通知する仕組みです。この場合は、開発エンジニアがGitHubにソースコードをコミットしたことをJenkinsに知らせるためにwebhookの機能を使っております。webhookのURLは、通知される側(この場合はJenkins)によって指定されたものを使います。

(3) webhookでの通知を受けて、最新のソースコードをGitHubから取得する。
(2)でのwebhookでの通知を受けて、Jenkinsは最新のソースコードをGItHubからpullします。

(4) ビルド、ユニットテスト、Dockerイメージの作成を行う。
GitHubからpullしたソースコードをMavenでビルド、JUnitでテスト、さらにそのビルドしたイメージを含むDockerイメージを作成します。

(5) ACRにDockerイメージをpushする。
GitHubからACR(Azure Container Registry)に、(4)で作成したDockerイメージをpushします。Azure Container Registryは、Azure上で構築することができるDocker Hubのようなイメージです。Docker Hubのような、誰にでも公開するレジストリではなく、限られた人のみに公開するプライベートレジストリになります。Azureの各種サービスとも相性がよくございますので、是非ご利用をお薦め致します。

(6) ACRにDockerイメージがpushされたことをwebhookでWeb App for Containersに通知する。
このwebhookのしくみは、(2)でご説明したGitHubと同様です。

今回の実践では、アプリケーションを稼働させる基盤に「Web App for Containers」を採用しました。Web App for Containersは、以前からWebアプリケーションを稼働させるための基盤として実績のある「Azure Web Apps」をベースにしており、Web App for Containersが指定するDockerレジストリにDockerイメージをpushするだけで、アプリケーションを稼働することができます。Web Appsにもあった負荷分散、ステージングスロットを利用したBlue-Green Deploymentなどの機能は、Web App for Containersでも利用することができます。

ちなみに同様のサービスに、Azure Kubernetes Serviceがあり、こちらは一つのVMに複数のコンテナを配置することができますが、Web App for Containersに配置できるコンテナは一つのみです。ただ、Web App for Containersの場合、負荷分散、ステージングスロットなどの機能がマネージドサービスとして用意されているので、そのあたりの機能をご利用になりたい場合、Azure Kubernetes Serviceのようにyamlをゴリゴリ書く必要がございません。単一コンテナでの運用で十分なのであれば、Web App for Containersを是非ご検討下さい。

(7) ACRからのwebhookを受けて、Dockerイメージをpullする。
(6)でACRにDockerイメージのpushが完了されたことを通知するwebhookを受けて、Web App for ContainersはACRからDockerイメージをpullします。

(8) ACRからpullしたDockerイメージをもとに、コンテナを作成する。
ACRからpullしたDockerイメージをもとにコンテナを生成しますと、Webアプリケーションが稼働します。今回稼働させるWebアプリケーションは、画面に「Hello World!!」とだけ表示する非常にシンプルなものです。

Screen Shot 2018-09-22 at 10.45.51

以降では、このアプリケーションのことを「Hello Worldアプリケーション」と呼びます。

(9) SeleniumでUIテストを実施する。
Seleniumを使いUIテストを実施します。SeleniumはWebアプリケーションのテストを自動化してくれるツールで、今までマンパワーを使ってブラウザで行っていたテストは、全てSeleniumが代行してくれます。JavaやPythonなど多数の言語向けのライブラリも用意されており、簡単なコードでブラウザの動きをエミュレーションできます。

今回は、画面に表示されているのが「Hello World!!」かどうかを確認するテストをSeleniumで実施します。

以降、今回のテストを実施するSeleniumスクリプトを「UIテスト自動化スクリプト」と呼びます。

実際にやってみる

では、実際にやってみましょう(๑•̀ㅂ•́)و✧

Jenkinsのインストール

まずJenkinsをインストールします。みんな大好きJavaのインストールからです。

# yum install java-1.8.0-openjdk
# yum install java-1.8.0-openjdk-devel

次にJenkinsのインストールです。

# wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins-ci.org/redhat-stable/jenkins.repo
# rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key
# yum install jenkins
# systemctl enable jenkins
# systemctl start jenkins

GitHubからソースコードをpullするので、gitのインストールが必要になります。

# yum install git

Seleniumを使うためにChrome Driverのインストールが必要になります。下記のURLにアクセスします。
https://chromedriver.chromium.org/downloads

2018年9月22日時点での画面になります。以下の「ChromeDriver 2.42」をクリックします。

Screen Shot 2018-09-22 at 14.29.59

 

「chromedriver_linux64.zip」をクリックして、ドライバーをダウンロードします。ZIPファイル解凍してできた「chromedriver」というファイルを/var/lib/jenkinsディレクトに置きます。

Screen Shot 2018-09-22 at 16.26.40

Seleniumを動作させるためにChromeが必要になりますので、インストールします。

# yum -y install https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm

 

ACRへのDockerイメージのpushにDockerが必要になりますので、インストールします。

# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# yum makecache fast
# yum install docker-ce

jenkinsユーザーでDockerを動かす必要があるので、dockerグループにjenkinsユーザーを追加します。そして、起動設定を行います。

# usermod -g docker jenkins
# systemctl start docker
# systemctl enable docker

次に、アプリケーションのビルドにMavenが必要になりますので、インストールします。これはJenkinsのGUIから行いますので、Jenkinsにアクセスします。URLは以下のとおりです。

https://[Jenkinsをインストールしたサーバーのホスト名]:8080/

以下の画面が表示されます。Jenkinsをインストールしたサーバーの/var/lib/jenkins/secrets/initialAdminPasswordのパスに記載のパスワードをテキストボックスに入力して、「Continue」をクリックします。

Screen Shot 2018-09-22 at 16.43.46

 

とりあえずJenkisnお薦めのプラグインを入れておきます。「Install suggested plugins」をクリックします。

Screen Shot 2018-09-22 at 16.47.14

 

しばらく待ちましょう。

Screen Shot 2018-09-22 at 16.48.45

 

ユーザ名やパスワードを入力して、「Save and Continue」をクリックします。

Screen Shot 2018-09-22 at 16.51.24

 

「Save and Finish」をクリックします。

Screen Shot 2018-09-22 at 16.53.37

 

「Start using Jenkins」をクリックします。

Screen Shot 2018-09-22 at 16.55.16

 

「Jenkinsの管理」をクリックします。

Screen Shot 2018-09-22 at 16.57.17

 

「Global Tool Configuration」をクリックします。

Screen Shot 2018-09-22 at 16.58.41

 

「Maven追加」をクリックします。「名前」のところに「M3」と入力して、「Save」をクリックします。

Screen Shot 2018-09-22 at 17.01.11

Jenkinsのインストールと設定はこれで終わりです。

Azure Container Registryの設定

Azure Container Registryを設定します。Azureポータルにアクセスします。「リソースの作成」をクリックして、虫眼鏡が書いてあるテキストボックスに「container」と記入して、Enterをクリックします。「Container Registry」をクリックします。

Screen Shot 2018-09-22 at 17.05.56

 

「作成」をクリックします。

Screen Shot 2018-09-22 at 17.08.22

 

レジストリ名は任意のものを、サブスクリプション、リソースグループ、場所は環境に応じたもの、管理者ユーザーは「有効にする」、その他はデフォルトのままにして、「作成」をクリックして下さい。

Screen Shot 2018-09-22 at 17.10.41

Hello WorldアプリケーションのDockerイメージ作成

先程ご紹介した「Hello World!!」を画面に表示するプリケーションのDockerイメージを作成します。以下のGitHubにあるソースコードをCloneして下さい。

https://github.com/noriyukitakei/spring-boot-hello-world

これは、JavaのアプリケーションフレームワークであるSpring Bootで作成されたものです。画面に「Hello World!!」と表示するだけの単純なアプリケーションです。アプリケーション自体のソースコードの説明は省きます。

Cloneしたソースコードのトップディレクトリに移動して、以下のコマンドでアプリケーションをビルドします。

# mvn clean package

本ブログでは、CI/CDの説明がメインなので、アプリケーションのソースコードやビルドについてのご説明は割愛させて頂きます。先のビルドコマンドもここでは、ご理解頂くなくても大丈夫です。

次にDockerfileによるビルドを行いますが、その前にDockerfileの中身を見てみます。先程CloneしたソースコードのトップディレクトリにDockerfileがあります。

FROM tomcat:8.5.33-jre10
COPY target/helloworld.war /usr/local/tomcat/webapps/helloworld.war

たった2行なのですが^^;1行目は、Docker HubからTomcatが稼働するイメージを取得してきています。2行目では、「mvn clean package」のコマンドでビルドしたアプリケーションをDockerイメージの/usr/local/tomcat/webappsディレクトリにコピーしています。これだけで、Tomcat上で稼働するWebアプリケーションのイメージが出来上がります。

では、Dockerビルドしましょう。

docker build -t helloworld .

きちんとイメージが出来上がっているかどうか確かめてみましょう。

i$ docker image ls
REPOSITORY                           TAG                 IMAGE ID            CREATED             SIZE
helloworld                           latest              XXXXXXXXXXXX        8 minutes ago       685MB

おおー(๑•̀ㅂ•́)و✧

では、これをAzure Container Registryにpushしてみましょう。

ここから先の作業は、Azure CLIが必要なので、以下のURLに従って、インストールして下さい。

https://docs.microsoft.com/ja-jp/cli/azure/install-azure-cli

Azure CLIでAzureにログインします。

$ az login
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code XXXXXXXXX to authenticate.

上記のメッセージに表示されているURL「https://microsoft.com/devicelogin」にアクセスして、「enter the code XXXXXXXXX to authenticate.」のXXXXXXXXXを入力しまと「続行」というボタンが表示されますのでクリックします。

Screen Shot 2018-09-22 at 18.22.24

しばらくすると、「az login」と入力したコンソールの方に、ずらずらーっとJSONが表示されたらログイン成功です。

次に、先程作成したAzure Container Registryにログインします。「–name」のオプションには、Azure Container Registryを作成した時に指定した「レジストリ名」を入力します。Login Succeededが表示されれば成功です。

$ az acr login --name devops2
Login Succeeded

Azure Container Registryのホスト名は、「レジストリ名.azurecr.io」となりますので、以下のようにpushします。

$ docker tag helloworld devops2.azurecr.io/helloworld
$ docker push devops2.azurecr.io/helloworld

これで、Dockerイメージのアップロードは完了です。

Hello WorldアプリケーションのソースコードのGitHubへのpush

先程CloneしたソースコードをGitHubにリポジトリを作成して、そのリポジトリにpushして下さい。

※本ブログではGitHubの詳細な操作は割愛させて頂いております

Web App for Containersの設定

Web App for Containersを設定します。Azureポータルにアクセスします。「リソースの作成」をクリックして、虫眼鏡が書いてあるテキストボックスに「web app」と記入して、Enterをクリックします。表示されるリストの中から「Web App」をクリックします。

Screen Shot 2018-09-22 at 17.20.25

 

「作成」をクリックします。

Screen Shot 2018-09-22 at 17.22.30

 

「アプリ名」は任意のもの、「サブスクリプション」「リソースグループ」は環境に応じたもの、「OS」は「Docker」を選択して下さい。「コンテナーの構成」をクリックして下さい。

Screen Shot 2018-09-22 at 17.31.28

「イメージのソース」に「Azure Container Registry」を選択、レジストリ名にはAzure Container Registry作成時に指定したレジストリ名、「helloworld」、タグには「latest」(こちらは先程Dockerイメージを作成したときの情報です)を選択して、「OK」をクリックします。

Screen Shot 2018-09-22 at 18.49.34

 

最後に「作成」をクリックして下さい。

Screen Shot 2018-09-22 at 18.58.31

以下のURLにアクセスすると、ブラウザに「Hello World!!」と表示されるはずです。

https://[先程入力したアプリ名].azurewebsites.net/helloworld/hello

SeleniumによるUIテスト自動化スクリプトの作成

Seleniumで自動化するためのスクリプトを用意します。

以下のGitHubに今回必要なSeleniumのスクリプトを用意しましたので、Cloneして下さい。

https://github.com/noriyukitakei/spring-boot-hello-world-e2e

今回、SeleniumのテストスクリプトはMavenプロジェクトにおけるJUnitのテストケースとして作成します。そのテストスクリプトはsrc/test/java/com/sios/test/E2ETest.javaに鬼窟されており、その詳細は以下の通りになります。

そして、GitHubにリポジトリを作成して、そのリポジトリにUIテスト自動化スクリプトのソースコードをpushして下さい。

※本ブログではGitHubの詳細な操作は割愛させて頂いております

パイプラインによる自動化スクリプトの作成

Jenkinsにはパイプラインという機能があり、自動化のスクリプトを作成することができます。今回はこれを使ってCI/CDを実現します。

その前にまず、自動化スクリプトを作成するために必要な情報をAzureポータルから取得します。Azure Container Registryを作成したリソースグループに移動して、表示されるリソースのリストから、種類が「コンテナーレジストリ」のリソースをクリックします。

Screen Shot 2018-09-23 at 0.09.03

 

「アクセスキー」をクリックして表示される「ログインサーバー」「ユーザー名」「password」をメモっておいて下さい。

Screen Shot 2018-09-23 at 0.12.12

 

Jenkinsの画面に戻って、「新規ジョブ作成」をクリックします。

Screen Shot 2018-09-22 at 16.57.17

 

「Enter an item name」というテキストボックスに任意のジョブ名(ここではhelloworld)と入力して、「パイプライン」を選択して「OK」をクリックします。

Screen Shot 2018-09-22 at 21.31.02

 

しばらくスクロールすると、「パイプライン」という項目が見えてきます。

Screen Shot 2018-09-22 at 22.24.36

 

上図のScriptの部分に以下のスクリプトを入力して、「保存」をクリックします。

Jenkinsによるメール通知の設定

パイプラインスクリプトにて、JenkinsによるCI/CDが失敗したらメールで通知する処理を記述しましたが、そもそもシステム設定にて、メールを送信できるようにしなければ、正常にメールは送信されません。

「Jenkinsの管理」→「システムの設定」の順にクリックします。

Screen Shot 2018-09-23 at 23.17.11

 

「システム管理者のメールアドレス」に通知メールの送信元アドレスを入力します。

Screen Shot 2018-09-23 at 23.20.08

 

「E-mail通知」の項目に、メールを送信するために必要な情報を入力します。こちらは環境に応じて適切な設定を行って下さい。最後に「保存」をクリックします。

Screen Shot 2018-09-23 at 23.21.31

GitHubのwebhookの設定

GitHubにソースがコミットされたことをJenkinsに通知するためのwebhookの設定を行います。

Jenkinsのトップ画面から、先程作成したジョブをクリックします。

Screen Shot 2018-09-23 at 23.26.12

 

「設定」をクリックします。

Screen Shot 2018-09-23 at 23.27.51

 

「ビルドトリガ」までスクロールして、「リモートからビルド」をチェックします。「認証トークン」の部分に任意の文字列を入力します。これはGitHubがJenkinsに対してwebhookする際の認証キーになりますので、「hoge」とか安易なものを指定しないで下さい。認証トークンは後ほど使いますので、メモっておいて下さい。最後に「保存」をクリックします。

Screen Shot 2018-09-23 at 23.29.12

 

次に、webhookの設定に必要なAPIトークンを取得します。Jenkinsのトップ画面に戻って、「Jenkinsの管理」をクリックします。

Screen Shot 2018-09-22 at 16.57.17

 

「ユーザーの管理」をクリックします。

Screen Shot 2018-09-23 at 23.40.15

 

適当なユーザー名をクリックします。

Screen Shot 2018-09-23 at 23.41.05

 

「設定」をクリックすると、画面右部に「APIトークン」が表示されます。「Add new Token」をクリックします。

Screen Shot 2018-09-23 at 23.42.10

 

「Generate」をクリックします。

Screen Shot 2018-09-23 at 23.44.28

 

APIトークンが生成され表示されます。このAPIトークンと、このトークンを割当てられたユーザー名をメモしておいて下さい。

Screen Shot 2018-09-23 at 23.47.43

 

Hello WorldアプリケーションをpushしたGitHubにアクセスします。「Settings」→「Webhooks」の順にクリックします。

Screen Shot 2018-09-23 at 23.49.37

 

「Add webhook」をクリックします。

Screen Shot 2018-09-24 at 0.01.04

「Payload URL」に以下のURLを設定して下さい。それ以外は、下図の画面の通りでOKです。最後に「Add webhook」をクリックします。

https://[Jenkinsのユーザー名]:[APIトークン]@[Jenkinsのホスト名]:8080/job/[Jenkinsのジョブ名]/build?token=[認証トークン]

Screen Shot 2018-09-23 at 23.55.24

これでGitHubへのwebhookの設定は完了です。

Azure Container Registryのwebhookの設定

Azure Container RegistryにDockerイメージがpushされたときに、Web Apps for ContainersがそのDockerイメージを取得してコンテナを自動で生成するためのwebhookを作成します。

まず、AzureポータルからWeb App for Containersのリソースにアクセスします。「コンテナーの設定」をクリックして、「継続的なデプロイ」を「オン」にして、「保存」をクリックします。

Screen Shot 2018-09-24 at 0.20.41

マイクロソフトのドキュメントを見ると、本当はこれだけでAzure Container Registryにwebhookが追加されるはずなのですが、なぜか追加されませんでした(´・ω・`)

しょうがないので、Azure Container Registryに手動でwebhookを追加することにしました(´・ω・`)

先程の「コンテナーの設定」をもう一度だけクリックします。「イメージのソース」のところで「Docker Hub」をクリックします。

Screen Shot 2018-09-24 at 0.34.58

 

下の方にスクロールすると「継続的なデプロイ」が見えてきます。「URLの表示」をクリックして表示されるURLをコピーします。

Screen Shot 2018-09-24 at 0.39.27

 

AzureポータルからAzure Container Registryのリソースにアクセスします。「Webhooks」をクリックします。画面右部に表示される「追加」をクリックします。

Screen Shot 2018-09-24 at 0.43.40

 

webhook名は任意の名称、「サービスURI」は先程、Web App for Containersの「継続的なデプロイ」の設定でコピーした「WEBHOOKのURL」を入力、後の項目は下図のままで、最後に「作成」をクリックします。

Screen Shot 2018-09-24 at 0.46.44

 

試しにやってみよう!!

さぁ、これで準備は整いました(๑•̀ㅂ•́)و✧

Hello Worldアプリケーションのソースコードに適当なコメント文を入れて、GitHubにpushしてみませう。

Jenkinsのジョブの画面を見てみると、何やら始まったと思います。

Screen Shot 2018-09-24 at 0.52.43

 

アプリケーションのビルドが終わって、Dockerイメージのpushが始まりました(๑•̀ㅂ•́)و✧

Screen Shot 2018-09-24 at 0.52.50

 

UIテストが始まりました。もうちょっと・・・(;´Д`)

Screen Shot 2018-09-24 at 0.53.47

 

終わったーヽ(=´▽`=)ノ 大成功です(๑•̀ㅂ•́)و✧

Screen Shot 2018-09-24 at 0.54.13

最後に

2回シリーズで「コンテナ時代のDevOps」という題材にして連載致しましたが、いかがでしょうか?なんとも抽象的なDevOpsというもののイメージを掴んで頂き、実践で投入頂く一助になれば、誠に幸いにございます。では、No CI/CD、No Lifeということで、楽しいDevOpsライフを楽しんで頂ければと思います。

 

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

1人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です