MENU

クラウド・ネイティブ・アプリケーションとマイクロサービスによる自動化 ~IT運用自動化の新しい方向性|第5回

 今回はシステム運用の枠から一歩踏み出して、クラウド基盤を前提に稼働する最新のアプリケーション開発・運用の自動化を概観してみたい。
 
 クラウドを基盤とする環境では、もはや自動化は前提であり、自動化なくしては実現できない。本稿では、「そもそもクラウド上でアプリケーションを稼働させるとはどういうことか」を起点に自動化の実現を考える。
 
 

クラウド・ネイティブ・アプリケーションの条件

 稼働プラットフォームに、クラウドを採用するシステムが増加している。現在のクラウド利用の目的は、コスト削減や構築の迅速化だけではない。多様な環境にデプロイされたアプリケーションを有機的に結び付け、新しい価値をタイムリーに提供する。つまりイノベーションの基盤として利用することに本質がある。
 
 クラウドを基盤とするアプリケーションを、今までのオンプレミス同様に開発・運用するのは無理がある。クラウド・ネイティブ・アプリケーションとして、クラウド上での稼働を前提に開発・運用せねばならない。
 
 それでは、クラウド・ネイティブ・アプリケーションをどう開発すればよいのか。Herokuの開発者が自らの経験をもとに、「The Twelve-Factor App」(https://12factor.net/ja/)でクラウド・ネイティブ・アプリケーションが備えるべき特徴を12の要素にまとめた。これが公開されたのは2012年。すでに時代にそぐわない記載も散見されるので、現在では米Pivotal社が「Beyond the Twelve-Factor App」(http://bit.ly/is18apps)として、15の要素に再編している。それらを図表1にまとめた。クラウド・ネイティブ・アプリケーションでは、運用管理などの非機能的側面もアプリケーションで実装すべきことがわかる。
 

マイクロサービスの特徴

 最近よく耳にするマイクロサービス・アーキテクチャは、クラウド・ネイティブ・アプリケーションの稼働プラットフォームとして、以下の3つの特徴を備える。
 
分散アーキテクチャ 
 アプリケーションを構成する個々の機能と
してサービスを開発し、これらのサービスの
連携で全体のアプリケーションを構成する分散アーキテクチャである。各サービスはそれぞれ独立してスケールアップやリリースを実施し、データもサービスごとに保持する。外部とはRESTなど軽量なAPIで通信するので、サービスが稼働するランタイムや開発言語はサービスごとに自由に選択できる。
 
 
運用面に目を向けた方法論 
 近年のビジネスは変化が激しく、アプリケーションもそれに合わせて絶えず変化することが求められる。従来のような、アプリケーション全体を1つの塊(モノリス)として管理するスタイル(モノリシック・アプリケーション)では、大規模化・複雑化するシステムの変更に迅速に対応できない。また、障害やパフォーマンス低下などの影響がシステム全体に波及する懸念もある。
 
 そこでマイクロサービス・アーキテクチャでは、サービスごとの継続的運用サイクルや、DevOpsプラクティスの実践など、運用的な側面まで考慮した方法論を提唱している。
 
 
機能横断型チーム編成
 コンウェイの法則では、「システムをデザインする組織は、その組織の実際のコミュニケーション構造を模倣したシステムを作る傾向がある」とされるが、マイクロサービス・アーキテクチャではこれを逆手にとり、各サービスで完結したチームを構成する。
 
 つまり従来のようにアプリ担当、サーバー担当、DB担当などの縦割りの編成ではなく、1つのサービス担当チームにこれらすべてのメンバーを揃えた形でチームを構成する。
 
 このようにアプリケーションの在り方を示す「クラウド・ネイティブ・アプリケーション」と、開発・運用までを含んだプラットフォームの在り方を示す「マイクロサービス」は、クラウド上で稼働するモダンアプリケーションの両輪として欠かせないのである。
 
 

マイクロサービスとコンテナ

 本連載第2回で取り上げたDockerとKubernetesもまた、クラウド・ネイティブ・アプリケーションやマイクロサービスと深い関係がある。
 
 Dockerによる仮想化は、コンテナ間でOSを共有する。そのためOS下でハイパーバイザーを共有するVM型仮想化に比較すると、オーバーヘッドが小さく、より集約度を高めて高密度でサーバーリソースを活用できる。Dockerコンテナの起動時間は圧倒的に短く(数秒単位)、軽量で、OS単位に必要なコードセットを集約するのでポータビリティが高い。図表1が示す廃棄容易性(Disposability)、環境一致(Environment Parity)などは、まさにコンテナ技術の特性を利用することで実現可能である。
 
 一方のKubernetesはDockerを統合管理するためのツールであり、以下の機能を備える。
 
・複数ホスト上でコンテナを管理
・関連するコンテナごとにグルーピング(このコンテナのグループをPodと呼ぶ)
・コンテナの死活監視
・コンテナ間の仮想ネットワーク環境
・コンテナの負荷分散
 
 Kubernetesもまた、上記の機能により図表1のポートバインディング(Port binding)、並行性(Concurrency)、設計・ビルド・リリース・実行(Design 、Build、Release、Run)などのプラクティス実現に貢献する。
 
 Kubernetesでは主な作業として、アプリケーション(コンテナ)のデプロイ(podと呼ばれる単位でデプロイされる)、デプロイ後のアプリケーションのネットワーク設定、各コンテナに接続するストレージ設定(コンテナ上のデータは揮発)などを実行する必要があるが、これらの設定をまとめて定義できる便利な仕組みがある。これは「Helm」と呼ばれ、実際の設定ファイル群のパッケージは「Chart」と呼ばれる。
 
 なおIBMではKubernetesをベースに機能拡張を加えた「IBM Cloud Private」を提供している。コミュニティ版は無償で使用できるので、ぜひ実際に導入して試してほしい。
 
 このようにコンテナ技術も、クラウド・ネイティブ・アプリケーションやマイクロサービスと親和性の高いことがわかる。マイクロサービスの実装は、コンテナ技術なしでは大きな困難を伴うだろう。
 
 

ライフサイクルの自動化

 本連載はIT運用自動化がテーマなので、ここからクラウド・ネイティブ・アプリケーションの開発、およびマイクロサービス環境での運用における自動化を考えてみよう。
 
 マイクロサービス・アーキテクチャでは、自動化が前提である。アプリケーションの開発ライフサイクルの自動化では、従来からDevOpsの代表的なプラクティスとされる「継続的インテグレーション」(CI)や「継続的デリバリー」(CD)があるが、マイクロサービスの開発でも同じく適用し、自動化されたパイプライン上でインクリメンタルな開発を実施する。
 
 図表2にサービスの開発からリリースまでを含むライフサイクルをモデル化し、それぞれのステップでどのような作業を実施し、自動化するのか、実装を例示する(これはあくまで一例であり、実際にはテストの実施タイミングや種別など、各組織のポリシーによって異なる)。
 
 
ソースコードリポジトリ
 開発者は、中央の単一リポジトリからコードをチェックアウトし、ブランチを切り、そのブランチ上でコードを開発する。ソースコードリポジトリとしては、Gitが使用されることが多い。開発が完了したら、コードをコミット/PUSHする。
 
 ここでの自動化実装は、コードのコミット/PUSHをトリガーに、ビルドプロセスを起動する部分である。ビルドプロセスは、CIツールであるJenkins側でGit用のプラグインを導入し、Git 上のブランチの変更を監視する形でトリガーされる。
 
 この時の注意点は、マイクロサービスの利点を活かすべく、サービスごとに独立してデプロイできるように、サービス単位で1つのデリバリーパイプラインを構成することである。それゆえ、ソースコードリポジトリもサービス単位で分割するのが望ましい。これは図表1の「One Codebase、One Application」に該当する。
 
ビルド
 ビルドは前述したように、ソースコードリポジトリへの更新をトリガーに、Jenkinsが起動する。アプリケーションのビルドは、Mavenで実装されることが多い。
 
 従来のモノリシックなアプリケーションであれば(Javaの場合)、ソースコードをコンパイルし、WAR/EARなどのアプリケーションアーカイブを生成する、というプロセスが実行される。
 
 これに対しマイクロサービスでは、さらにアプリケーションをDockerコンテナに組み込んで、Liberty Profileなどのランタイムまでを含めたDockerイメージを生成することで、より多くのメリットを享受できる。
 
 図表1の廃棄容易性、環境一致、ポートバインディングなどのプラクティスは、サービスをコンテナ化することで容易に実現できる。こうした理由により、ビルドプロセスではアプリケーションビルドだけでなく、Dockerビルドも併せて実行し、デプロイもコンテナで実施する、というコンテナベースでの継続的デリバリーが強く推奨される。
 
 
テスト
 マイクロサービスによらず、テストの自動化で扱うべき内容は広範囲に及ぶ。ここでは、実施すべきテストとその方法について簡単に述べたい。
 
 サービスと言っても、その中身はアプリケーションコードなので、まずはコードレベルでのユニットテストを実施すべきである。ここではJUnitなどのツールを利用する。Mavenで実行されるビルドプロセス内で、自動実行されるように組み込む場合もある。
 
 サービステストやEnd to Endテストでは、テストシナリオの管理や対応する結果のトラッキングが複雑になるため、テストを統合的に管理するテスト・スイートを使用してテストを自動化する。
 
 
デプロイ
 デプロイでは各環境へビルド生成物を配布し、サービスを稼働できる状態にする。本番環境へのデプロイは、テスト環境やステージング環境へのデプロイを実施し、End to Endテストなどを実行したあとのリリースのみを対象とする。
 
 本番環境へのデプロイは、ブルー・グリーンデプロイやカナリア・リリースなどの手法を用いて安全に実施する(図表3)。
 
 ブルー・グリーンデプロイは、現行稼働しているブルー環境と並行稼働する新しいリリース用のグリーン環境を用意し、リクエストのルーティングをブルーからグリーンへ切り替える方法である。これによってサービスのダウンタイムを排除し、かつ新リリースに不具合があった場合のロールバックも可能にする。
 
 一方のカナリア・リリースは、新リリースを一部のインスタンスのみにデプロイし、このカナリア環境にリクエストの一部のみをルーティングして様子を見る方法である。カナリア環境での稼働に問題がなければ、全体へのリリースを実施する。
 
 

自動化の実装例

 プライベート・クラウドに前述の自動化を実装したのが、図表4である(パブリック環境では、IBM Cloud 上でToolchain というサービスが提供されている)。コンテナのランタイムはIBM Cloud Private を前提にする。また最終的に稼働させるのは、Liberty プロファイルのコンテナに組み込んだWebアプリケーションを想定している。
 
 以下に、ここでの自動化の流れを順に説明する。①~⑤では、開発者がコードをGitに登録しただけで、Dockerイメージが生成される。⑥以降で、アプリケーションをデプロイする。
 
①開発者は作成・改修したコードをGitにPUSHする。
 
②Jenkinsはブランチへの変更を検知して、Mavenのビルドプロセスを開始する。
 
③Mavenはコードのコンパイル・パッケージングを実施し、アプリケーションのアーカイブを生成する。
 
④JenkinsはDockerビルドを開始。LibertyプロファイルのDockerイメージをレジストリから取得し、③で生成したアプリケーションアーカイブを導入。最終的にアプリケーション導入済みのLibertyプロファイルのDockerイメージを生成する。
 
⑤Jenkinsは、④で生成したDockerイメージをレジストリに登録する。
 
⑥開発者はIBM Cloud Private の管理画面から、該当アプリケーションを含むHelm Chart を選択して必要事項を入力し、デプロイする(ここでの入力パラメータがChartに渡されてデプロイが実行される。Chartは事前に作成し、登録しておく)。
 
⑦IBM Cloud Privateは、指定されたChartの内容に基づいてDockerイメージをデプロイする。実際には、Worker Node側から⑤で登録されたレジストリ上のDockerイメージを取得する。
 
 最後にデプロイされたアプリケーションのテストを実行する。テストの実装方法はいろいろあるが、ここではJenkinsのタスクとしてSelenium(Web UIのテスト自動化ツール)によるテストを自動実行している。なお、Seleniumもコンテナとして稼働する。
 
⑧開発者は、Jenkinsに登録されたテスト実行タスクを開始する。
 
⑨Jenkinsは、Seleniumサーバー上のテスト実行をトリガーする。
 
⑩Seleniumは、定義されたテストシナリオに従ってブラウザの操作をシミュレートし、実行結果を確認する。
 
 上記の例ではアプリケーションのデプロイとテスト実行のトリガーを手動で実行しているが、すべてをJenkinsのパイプライン上に定義し、自動実行させることもできる。
 
 またJenkinsのパイプライン定義、Mavenのビルド定義、Helm Chartの定義、Dockerビルドファイルなどは自前で用意する必要がある。IBM Cloud Privateには、「Microservice Builder」というツールが付属しており、これらの定義ファイルをコマンド実行のみで簡単に生成できる。
 
 このように自動化は、ツールの連携によって従来よりも簡単に実現可能である。
 
 本稿では、クラウドでの稼働を前提とするクラウド・ネイティブ・アプリケーションを、マイクロサービスとして稼働させることについて解説した。さらに、「サービス」として稼働するアプリケーションの開発・ビルド・テスト・デプロイのプロセスを自動化するソリューションおよび実装例を示した。
 
 ここでの説明はいずれも誌面の都合上、概要レベルでの記述にとどまっているが、クラウド上にシステムを展開する際には非常に重要な概念なので、ぜひ詳細情報を収集してほしい。
 
[IS magazine No.18(2018年1月)掲載]
 
・・・・・・・・
 

著者|太田 智之 氏 

日本アイ・ビー・エム システムズ・エンジニアリング株式会社
クラウド・ソリューション
クラウド・アプリケーション
シニアITスペシャリスト
 
1999年、日本アイ・ビー・エム システムズ エンジニアリングに入社。WebSphere製品テクニカルサポート、Webシステムインフラ構築、Webアプリケーション開発などを経て、近年はクラウド、マイクロサービス関連のソリューション開発に従事。剣道三段。