不断のDevOps パイプライン: DynatraceとAWSで、シフトライト、シフトレフト、セルフヒーリングを実装する


本記事は、Dynatraceブログ にポストされた ” Unbreakable DevOps Pipeline: Shift-Left, Shift-Right & Self-Healing / Andreas Grabner ” の日本語翻訳(部分編集あり)になります。

本ブログは、"Dynatrace-AWS-DevOps チュートリアル" の技術解説であり、シフトライト、シフトレフト、及びセルフヒーリング(自己修復)を、どのように継続的デリバリとディプロイメントパイプラインに実装するか、その方法について説明するものです。

このチュートリアルでは、フルスタックモニタリングのためにDynatraceを、パイプライン、ディプロイメント、オーケストレーション、コンピューティング、ストレージのためにAWSのサービスを選択していますが、同じことを他のクラウドプラットフォームやCI/CDツールに対しても適用できるはずです。

次のアニメーションは、「プルリクエスト」(左側)から「プロダクション ディプロイメント」(右側)までのデリバリパイプラインのフローを示しています。この中で、Dynatraceは、各ステージ間(クオリティゲート)で監視者の役割と、プロダクション環境でのセルフヒーリングをコントロールする役割を担っています。
【画像】AWSとDynatraceを使用したシフトレフト(クオリティゲート)、シフトライト(モニタリングへのコンテキスト情報提供)、およびセルフヒーリング(自己修復)

このチュートリアルでは、モダンなデリバリパイプラインにおける、フルスタックモニタリングの果たし得る役割を示しています。Dynatraceを使用するか、他のツールを使用するかに関係なく、問題あるコード変更によってエンドユーザーが影響を受けないようにするために、パイプラインは次の要件を満たすべき だと考えます。

  • 自動化されたフルスタックモニタリング

    ホスト、PaaS( CloudFoundry、 OpenShift、 SAP Cloud Platform 等)または関数( Lambda、 Azure Functions 等)のモニタリングを自動でディプロイし有効化できること。使用される技術スタック(言語やフレームワーク等)に関係なく、すべてのプロセス、サービス、およびアプリケーションを自動で検出できること。

  • シフトライト

    ディプロイメント情報やメタデータをモニタリング環境にプッシュできること。例えば、ブルーとグリーンのディプロイメントを区別したり、ビルドまたはディプロイメントのリビジョン番号をプッシュし構成の変更を通知すること、など。

  • シフトレフト

    パイプラインを停止するか実行するかを決定するために、APIを介して特定のエンティティ(プロセス、サービス、アプリケーション、テストなど)のデータを取得できること

  • セルフヒーリング(自己修復)

    発生したシステムトラブルの根本原因に対応する様な、インテリジェンスな自動自己修復ができること。例えば、GC設定不良の自動修正

それではこれらの4つの要件を、上述のチュートリアルの中で実際にどう実装したか、解説していきます。

1. 自動化されたフルスタックモニタリングの実装例:

DynatraceのOneエージェントテクノロジーは、それぞれ異なるエージェントで監視するような対象(Java、.NET、Webサーバー、ノード、Lambdaなど)や、それぞれ異なるツールで監視するような対象(ネットワーク、ログ、コンテナ、クラウド)も、1つのエージェントでまとめてフルスタックの自動監視を実現します。

このチュートリアルでは、AWS CloudFormation を利用し、EC2インスタンス定義のUserDataセクションにダウンロードとインストールのスクリプトステップを追加するだけで、Dynatrace Oneエージェントを自動デプロイしています。

以下は、私のCloudFormationテンプレートの抜粋です。任意のDynatraceテナントで機能するように、実際のダウンロードURLがパラメーター化されています。

"UserData": {
  "Fn::Base64": {
     "Fn::Join": ["", [
       "#!/bin/bash -x\n",
       "# First: we download and install the Dynatrace OneAgent\n",
       "yum update -y\n",
       "yum install ruby wget -y\n",
       "wget -O Dynatrace-OneAgent-Linux.sh \"", {
         "Ref": "DynatraceOneAgentURL"
       }, "\"\n",
       "sudo /bin/sh Dynatrace-OneAgent-Linux.sh APP_LOG_CONTENT_ACCESS=1\n",
       "# Second: ...",

EC2インスタンスが起動すると、Dynatraceは次のスクリーンショットの様に、自動的にフルスタックの監視(フロントエンド、サーバサイド、インフラ、ログ、クラウド等)を開始します。

【画像】Dynatrace Oneエージェントをインストールすると、ホスト、すべてのプロセス、サービス、およびアプリケーションのフルスタックの可視性が得られます

上のスクリーンショットでは、左側にDynatrace スマートスケープが表示され、右側に各エンティティの一部のデータが自動的にキャプチャされています。このデータはすべて、Dynatrace スマートスケープ APIおよびTimeseries APIからもアクセスできます。

2. シフトライトの実装例:

私にとってシフトライトとは、ディプロイメントまたは変更に関するコンテキスト情報を、監視プロセスにプッシュすることを意味します。獲得するコンテキスト情報が多ければ多いほど、問題の根本原因をより適切に検出することも、セルフヒーリングをより効果的に実装することもできます。

メタデータ(タグ、プロパティなど)をフルスタック監視プロセスに渡す

シフトライトの最初の実装は、自動化されたディプロイメントプロセスのメタデータを取得することです。デフォルトでは、DynatraceはAWS EC2インスタンス、Docker、CloudFoundry、OpenShift、Kubernetes 等のタグなどのメタデータを自動でキャプチャします。これにより監視ツールでエンティティにタグを付け直す必要がなくなります。プラットフォームで既に指定したものを再利用するだけです。

それらプラットフォームからのメタデータの自動キャプチャに加え、Dynatraceは環境変数、Javaプロパティなどからも、メタデータを抽出できます。

私のチュートリアルでは、AWS CodeDeploy を利用し、アプリケーションを実行するシェルスクリプトで、環境変数 DT_TAGS、DT_CUSTOM_PROP および DT_CLUSTER_ID をエクスポートしています。

これらはDynatrace Oneエージェントがプロセスグループのメタデータとして取り扱う特別な環境変数です。ビルド固有の情報を含む独自の環境変数やJavaプロパティがある場合、Dynatraceのカスタムプロセスグループ検出ルールを設定することで、これらを取得できます。次のスクリーンショットは、AWS CodeDeployスクリプトがどのように見えるかを示しています。

【画像】ディプロイメントスクリプトを使用して、メタデータをDynatrace監視対象エンティティに渡します。CodeDeploy、Chef、Puppet、Ansible、Electric Flow、XLRelease 等で動作します

これは、"Monitoring as Code" または "Monitoring as Configuration" に呼ばれるものに相当します。なぜなら、監視対象に関するデータが、自動ディプロイメント構成スクリプトを介して渡されているためです!これらの重要な情報を2回設定する必要はありません!単に再利用するだけです!

デプロイ情報をフルスタック監視プロセスに渡す

シフトライトの2番目の実装は、Dynatrace API を使って実行できます。APIは、カスタムタグ、時系列、またはカスタムイベントを監視対象エンティティ(ホスト、プロセスグループインスタンス、サービス、またはアプリケーション)にプッシュする機能を提供します。

私のチュートリアルでは、Dynatrace Events API を使用して、AWS CodePipeline と AWS CodeDeploy のビルドおよびデプロイ情報を Dynatraceが監視しているサービスに対してプッシュしました。

【画像】AWS Lambdaを使用し、イベントAPIを介してCodePipelineとCodeDeployの情報をDynatrace に渡す

3. シフトレフトの実装例:

シフトレフトという用語が広まっていますが、恐らくDevOpsと同じくらい頻繁に誤解されているのではないでしょうか? 私見では、シフトレフトとは、次のきわめて重要な質問に答えるために、より多くのデータをライフサイクル初期に獲得することであると考えます。

この変更は、プロダクションにプッシュしても良いようなものなのか、それとも悪いものなのか?

そして、それが悪い変更であった場合は、決してパイプラインの先にプッシュさせてはいけません!

パイプラインで確認すべきデータはパフォーマンス関連の監視データだけではありませんが(コード品質に関するメトリックも確認しましょう)、ビルド検証を自動化するために、多くの人がそれらをパイプラインに自動的に含めることにトライしています。

このチュートリアルでは、Dynatrace Timeseries (時系列) API を使って、パイプラインによってプッシュされるサービスの異なる複数のメトリックを比較することで、ビルド検証プロセスを自動化させています。

プッシュされようとしているカレントビルドを、他のベースラインビルドと比較したり、更にはプロダクションの稼働状況と比較します。

次の図は、このタイプの比較を定義する方法(Monitoring as Code)を示しており、メトリックを取得する先(どの環境か)と、これが良いビルドか悪いビルドかを判断する方法(しきい値の定義)について説明しています。
【画像】ビルドまたは環境毎のメトリックを比較することにより、変更によって、パフォーマンスを改善させているか又は低下させているかどうか確認できます。

従来、ビルド検証はパフォーマンスエンジニアによって手動で行われ、パフォーマンスエンジニアはさまざまな時間枠のさまざまなダッシュボードをプルアップし、親指を上げたり下げたりしていました。多くの場合、これらのレポートの生成は自動化されていますが、最終的なレポートは手動で比較されているのです!

私のチュートリアルでは、このビルド検証プロセスを完全に自動化しました!ビルド検証(=比較)はパイプラインからトリガーされ、AWS Lambda 関数 によって実行されます。AWSLambda 関数は、パイプラインの承認ステージにおいて、次のステージへの移行を許可または拒否します。すべてのビルド検証結果と比較されたすべてのメトリックは、私が作成したHTMLレポートからもアクセスできます。

【画像】すべてのビルドについてのDynatraceによるビルド検証結果。新しいビルドのすべてのメトリックをベースラインと比較表示します!

次のアニメーションは、これがパイプラインにどのように統合されるかを示しています。重要な点は、有効な比較となるように、十分な長さの負荷テストで十分なデータを取得して初めて、ビルド検証プロセスを実行できることです。このための”待機”は、DynamoDBテーブルに入力された検証リクエストと、十分な時間が経過したときにのみそのリクエストを実行するLambda関数の、それぞれを実行する期間によって実現されます。


【画像】デプロイが成功すると、ビルド検証リクエストが発行されます。ビルド検証ワーカーは、適切なタイミングで検証を行い、承認ステージの承認または拒否を行います

4. セルフヒーリングの実装例

テストをしたからプロダクションで順風満帆だ、という訳では決してありません。したがって、プロダクション環境で何か問題が発生した場合の状況を自動化する方法も検討する必要があります。

ご存じのとおり、Dynatrace AIは自動的に発生した問題を検出し、Oneエージェントが収集したフルスタックすべてのデータの中から、根本原因を自動で検出します。問題が検出されるたびに、Dynatraceは外部ツール(ServiceNow、PagerDuty、xMattersなど)に通知したり、Webhookを呼び出したりできます。

このチュートリアルでは、問題が発生した場合に、DynatraceからAPI Gatewayを経由して呼び出されるAWS Lambda関数を実装しました。Lambda関数は、問題に関するDynatraceからの付加的情報を獲得します。たとえば、最新のディプロイメントが何で、いつ行われたか、などです。もしも最新のディプロイでディプロイ直後に問題が発生した場合、Lambda関数はAWS CodeDeployを呼び出して、プロダクション環境に以前のリビジョンをディプロイます。

【画像】古典的なロールバックシナリオ。AWS Lambdaと、Dynatrace AIで検出された問題とその根本原因のデータを使用して問題を解決する

以前のリビジョンをディプロイすることは、究極のセルフヒーリングプロセスではないことは理解しています。問題の根本原因と環境に応じて、システムを修復するための様々なアクションを実行する必要があります。宜しければ、私の最近のブログである ”デジタルパフォーマンスライフにおけるAIへの適用” をご参照ください。ここでは、実際に私が関わった3つの問題と、Lambda関数などで修復用スクリプトを使って、システムをセルフヒーリングするために何をしなければならなかったについて説明しています。

(了)

参照: 本ブログに連動するコンテンツは以下の通りです

著者の紹介:

Andreas Grabner は、ソフトウェア開発者、テスター、アーキテクトとして20年以上の経験があり、high-performing cloud scale applications の提唱者です。 彼はDevOpsコミュニティへの定期的な寄稿者であり、技術カンファレンスでも頻繁に講演を行っており、blog.dynatrace.comで定期的に記事を公開しています。 Twitterで彼をフォローできます:@grabnerandi