ISID テックブログ

ISIDが運営する技術ブログ

GAされたAmazon Managed Service for Prometheus + GrafanaでEKSにホストしたマイクロサービスを可視化してみた

メリークリスマス✨ISID 金融ソリューション事業部 市場系イノベーション部の寺山です!
新型コロナ禍の日々ですが、クリスマスイブはちょうど金曜日でしたし、皆さま楽しく過ごせましたかね??
さて、本記事は 電通国際情報サービス Advent Calendar 2021 の最終日のポストとなります。前回は、浦本さんの「フロントエンド依存ライブラリのバージョンアップ戦略」でした。
いやぁ、Advent Calendarに参加するぜ!ってエントリーしてしばらく経ってから、あれ??トリじゃん!?って気づきましたよ。。笑
しかしながらそんなことは気にせず、私が興味を持ったことについて投稿させていただきたいと思います!

はじめに

インフラ・クラウドというエンジニアリング領域を担当している私は、Kubernetes(以下K8s)を以下のように認識しております。

  • インフラストラクチャをソフトウェアでハイレベルに抽象化して制御する強力なテクノロジー
  • コミュニティが活発でありデベロッパーやインフラ管理者を支援するツールが日々進化している

2点目に関連し、コンテナレベルでの監視や可視化をサポートするエコシステムである、PrometheusGrafanaがそれぞれAWSのマネージドサービスとしてGAされました。

GAされてから4カ月ほど経過しますが、EKS+AMP+AMGという記事は以外と私の目に入っておりません。そこで、AMPとAMGを用いてAmazon EKSにホストしたマイクロサービスの可視化をやってみた!というのが、本記事の主旨となります。 K8sに対してはキャッチアップ中というスキルセット&ブログを書くのが初めてということもあり、誤りや至らぬ点もあるかと存じますが、ご指摘等はコメントいただけるとありがたいです(>人<;)

EKSにホストしたマイクロサービスの構成

本題へ入る前に、モニタリング対象のマイクロサービスのインフラ構成をご説明します。

EKSCluster-Mircoservice-Only

コンポーネントは全てAWSのサービスで構成しています。リージョンはアジアパシフィック(東京)です。
マイクロサービスアプリケーションは、バックエンドとして、認証/認可機能、共通機能、これらの機能を用いてビジネスロジックを実装し機能として提供するコンテナーをそれぞれのPod内で実行しています。コンテナーのイメージはAmazon ECR(以下ECR)から取得します。
コンテナランタイムの実行環境はサーバレスコンピューティングサービスであるAWS Fargate(以下Fargate)を利用しています。
ステートフルな情報は永続化層としてプロビジョニングしたAmazon Aurora(以下Aurora)より取得・保管します。
EKSクラスターにデプロイしたAWS Load Balancer Controllerにより、ACM証明書を適用してSSLTLS接続をオフロードするApplication Load Balancer(以下ALB)をプロビジョニングしています。
ALBは、フロントエンド(クライアント)からのREST APIリクエストラフィックビジネスロジックServiceにパスベースでルーティングします。
これらのコンテナー関連リソースを制御するK8sマスターがAWSマネージドとして作成/運用されるAmazon EKS(以下EKS)でクラスターを構成しています。
エンドユーザーはSPAを取得して、REST APIでバックエンドとリソースのやり取りをするというマイクロサービスにおける代表的なアーキテクチャです。SPAはS3に格納し、CloudFrontによりHTTPSで配信します。ただし、オリジンはS3バケットのみであり、バックエンド(ALB)は指定していません。
全体的に、(プライベートサブネットとCloudFrontの構成をサボっているところ以外は)AWSでの典型的なアーキテクチャだと思っています。ちなみに、フロントエンド・バックエンドのアプリケーションを開発したのは私ではありません。ありがとう、チームのみんな〜

コンテナー型マイクロサービスの可視化

PodのログはFluent Bitを利用すれば比較的簡単(Fargate ログ記録参照)にCloudWatch Logsで収集可能となります。
Fluent Bitは一部のメトリクスもログストリームに含めることをサポートしています1
そのため、CloudWatchでメトリクスフィルターを頑張って設定すれば、可視化もできそうです。
ただし、せっかくK8s使用しているのですから、有用(というか人気)なエコシステムは活用したいですよね?!というのが本件のモチベーションとなります。

K8sおよびエコシステムのバージョン

  • EKS:Kubernetes 1.21、eks.3
  • Prometheus:14.11.1
  • Grafana:8.3

AMPのアドオン

AMPユーザーガイドのGetting startedに従って、前述のEKSクラスターにPrometheusをアドオンします。ガイドと違いがある点や特にコメントしたい内容以外は単に作業内容を記述するのみにとどめて説明します。

  • AMP ワークスペースの作成

      $ aws amp create-workspace --alias tech-research-workspace
    
  • Prometheus 用の Namespace と ServieAccount 作成

      $ kubectl create namespace prometheus 
      namespace/prometheus created
    
      $ kubectl create serviceaccount prometheus -n prometheus
      serviceaccount/prometheus created
    
  • サービスロールを作成して Service Account に関連付け

    Set up IAM roles for service accountsで案内されているスクリプトを作成して実行します。
    ガイドのスクリプトではeksctlを利用しており、実際にEKSを構築や運用する際には有用なCLIツールかと思いますが、K8sの理解を深めるためにkubectlで書き直しました。
    と言っても、差分は以下のみなのですが。。。

      eksctl utils associate-iam-oidc-provider --cluster $CLUSTER_NAME --approve
    
    • 私が書き直したスクリプト

      kubectl annotate serviceaccount -n ${SERVICE_ACCOUNT_NAMESPACE} ${SERVICE_ACCOUNT_NAMESPACE} \
      eks.amazonaws.com/role-arn=${SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE_ARN}
      

    実行します。

    $ ./createIRSA-AMPIngest.sh
    arn:aws:iam::XXXXXXXXXXXX:role/amp-iamproxy-ingest-role
    serviceaccount/prometheus annotated
    
  • EKSノードグループの作成

    ここで、Prometheusのアーキテクチャを確認すると、Prometeheus ServerのTSDBの保存先にストレージが要求されています。
    ※下図はPrometeheus Overview - Architectureより抜粋したものです。

    EKSクラスターはデフォルトでAmazon EBSのStorage Classがデプロイ済みの環境となりますが、私が構築したクラスターはFargateプロファイルのみを作成していたので、EBSをストレージとするPersistent Volumeを利用できません。Amazon EFSのStorage Classを追加してFargate上で実行するか、EC2ノードでEBSを利用するか、なのですが本件では後者としました。

    EC2ノードを利用する場合はEKSクラスターにノードグループを追加します。ノードグループはマネージドノードグループとしました。
    作成方法はAWSユーザーガイドのステップ 4 ノードを作成するManaged nodes – Linuxをご参照ください。

  • Prometheusのインストール

    • Helm チャートリポジトリを追加

      互換性があるということで、AMP用のHelmリポジトリがあるのではなく、コミュニティのリポジトリを追加していますね。マネージドサービスでありながらコミュニティのアップデートを利用できるのは嬉しいですね!

      $ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
      $ helm repo add kube-state-metrics https://kubernetes.github.io/kube-state-metrics
      $ helm repo list
      NAME                    URL
      prometheus-community    https://prometheus-community.github.io/helm-charts
      kube-state-metrics      https://kubernetes.github.io/kube-state-metrics
      
      $ helm repo update
      Hang tight while we grab the latest from your chart repositories...
      ...Successfully got an update from the "kube-state-metrics" chart repository
      ...Successfully got an update from the "prometheus-community" chart repository
      Update Complete. ⎈Happy Helming!⎈
      
    • Helmチャートに渡すパラメーターファイルの作成

      リモート書き込みエンドポイント(remoteWrite)は、AMPコンソールのワークスペースの概要欄や、aws amp describe-workspace --workspace-id <ワークスペースID>より確認可能です。

      amp-ingest-values.yaml

       serviceAccounts:
           server:
               name: "amp-iamproxy-ingest-service-account"
               annotations:
                   eks.amazonaws.com/role-arn: "arn:aws:iam::XXXXXXXXXXXX:role/amp-iamproxy-ingest-role"
       server:
           remoteWrite:
             - url: https://aps-workspaces.ap-northeast-1.amazonaws.com/workspaces/ws-XXXXXXXX-XXXXXXXXXXXXXXXX/api/v1/remote_write
               sigv4:
                   region: ap-northeast-1
                   queue_config:
                       max_samples_per_send: 1000
                       max_shards: 200
                       capacity: 2500
      
    • Prometheus Serverのインストール

      $ helm install tech-research-prometheus-chart prometheus-community/prometheus -n prometheus -f ./amp-ingest-values.yaml 
      NAME: tech-research-prometheus-chart
      LAST DEPLOYED: Tue Dec 14 22:31:55 2021
      NAMESPACE: prometheus
      STATUS: deployed
      REVISION: 1
      TEST SUITE: None
      NOTES:
      The Prometheus server can be accessed via port 80 on the following DNS name from within your cluster:
      tech-research-prometheus-chart-server.prometheus.svc.cluster.local
      #(省略)
      
  • リソースの作成を確認

      $ kubectl get all -n prometheus                                                                                        
      NAME                                                                  READY   STATUS    RESTARTS   AGE
      pod/tech-research-prometheus-chart-alertmanager-646ff55c84-fmzfp      2/2     Running   0          2m19s
      pod/tech-research-prometheus-chart-kube-state-metrics-869b89746zhd5   1/1     Running   0          2m19s
      pod/tech-research-prometheus-chart-node-exporter-pft8p                1/1     Running   0          2m19s
      pod/tech-research-prometheus-chart-pushgateway-6cb64c488f-wrvdx       1/1     Running   0          2m19s
      pod/tech-research-prometheus-chart-server-76f7b57784-k8xj6            2/2     Running   0          2m19s
    
      NAME                                                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
      service/tech-research-prometheus-chart-alertmanager         ClusterIP   192.168.0.150   <none>        80/TCP     2m19s
      service/tech-research-prometheus-chart-kube-state-metrics   ClusterIP   192.168.0.47    <none>        8080/TCP   2m19s
      service/tech-research-prometheus-chart-node-exporter        ClusterIP   None            <none>        9100/TCP   2m19s
      service/tech-research-prometheus-chart-pushgateway          ClusterIP   192.168.0.221   <none>        9091/TCP   2m19s
      service/tech-research-prometheus-chart-server               ClusterIP   192.168.0.244   <none>        80/TCP     2m19s
    
      NAME                                                          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
      daemonset.apps/tech-research-prometheus-chart-node-exporter   1         1         1       1            1           <none>          2m19s
    
      NAME                                                                READY   UP-TO-DATE   AVAILABLE   AGE
      deployment.apps/tech-research-prometheus-chart-alertmanager         1/1     1            1           2m20s
      deployment.apps/tech-research-prometheus-chart-kube-state-metrics   1/1     1            1           2m20s
      deployment.apps/tech-research-prometheus-chart-pushgateway          1/1     1            1           2m20s
      deployment.apps/tech-research-prometheus-chart-server               1/1     1            1           2m20s
    
      NAME                                                                           DESIRED   CURRENT   READY   AGE
      replicaset.apps/tech-research-prometheus-chart-alertmanager-646ff55c84         1         1         1       2m20s
      replicaset.apps/tech-research-prometheus-chart-kube-state-metrics-869b8974ff   1         1         1       2m20s
      replicaset.apps/tech-research-prometheus-chart-pushgateway-6cb64c488f          1         1         1       2m20s
      replicaset.apps/tech-research-prometheus-chart-server-76f7b57784               1         1         1       2m20s
    

AMGのアドオン

こちらもAMGGetting startedに従って進めていきましょう!

  • Grafanaワークスペース作成

    Create your first workspaceに従って作成します。
    Grafanaワークスペース・コンソールには、SSOで認証を行いアクセスする必要があるのですが、本件ではSSOの方式にSAMLを選択しました。

    • Amazon Grafana > Workspacesよりワークスペースを作成を押下
    • 名前と説明
    • 認証アクセス
      • Security Assertion Markup Language (SAML)
    • アクセス許可タイプ
      • サービスマネージド
    • IAM アクセス許可アクセス設定
      • 現在のアカウント
      • データソース
        • Amazon Managed Service for Prometheus
    • ワークスペースを作成を押下
    • ステータスがアクティブとなることを確認する

ワークスペースの作成は一旦終了しますが、SAMLの設定を完了させるにあたり、SAML IdPの構築が必要となります。

  • SAML IdPの構築

    本件ではIDaaSであるOktaを利用しました。AWSにて動作確認済みのIdPはConnecting to your identity providerに一覧化されています。こちらに記載のないIdPは、Grafanaに必要なSAMLアサーション属性をマッピングできるかの検証が必要ですね。

    • Oktaコンソール > 管理者より管理者ページにサインインする
      • その際、多要素認証の設定を求められるので、Okta Verifyを利用しました。
    • Directory > Profile Editorと遷移
      • UsersにてOkta用のプロファイルであるUser(default)を選択
      • AttributesのAdd Attributeを押下
      • Add Attribute
        • Display name
          • Role
        • Variable name
          • Role
      • Saveを押下
      • Role属性が追加されていること
    • Directory > Peopleと遷移
      • 自分のアカウントを選択
      • ProfileタブにてAttributesのEditを押下
        • 前述の手順で追加したRole属性にADMINを設定
        • Saveを押下
    • Applictions > Applicationsと遷移
    • Browse App Integration Catalogにて「Amazon Managed Grafana」をSearchして選択
    • アプリケーションの詳細画面にてAddを押下
    • General Settings
      • デフォルトのままでDoneを押下
      • Amazon Managed GrafanaアプリケーションのSing Onタブに遷移
      • SettingsにおいてEditを押下
      • ユーザーのアサイ
        • Amazon Managed GrafanaアプリケーションのAssignmentsタブに遷移
        • AssignプルダウンメニューよりAssign to Peopleを選択
        • 作成済みのアカウント(今回は私のOktaアカウント)をAssign
        • Doneを押下
  • AMGSAML設定

    OktaをIdPとしたSAML認証に必要な設定を行います。

    • Amazon Grafana > Workspaces > 作成したワークスペースを選択
    • 認証タブのSecurity Assertion Markup Language (SAML)セットアップを完了にするを押下
    • Security Assertion Markup Language (SAML)
    • GrafanaワークスペースSAML設定が有効となることを確認する
  • Grafana workspace consoleにアクセスする

    SSOが設定できたかの動作確認も兼ねて、GrafaraのUI(ワークスペース・コンソール)にアクセスします。

    • Amazon Grafana > Workspacesより作成したワークスペースを選択し、Grafana ワークスペース URLに表示されているリンクを開く
    • Sign in with SAMLを押下

      AMG-SAML-SignIn

    • Oktaと未認証状態の場合は、Oktaにサインインする

      AMG-Okta-SignIn

    • Grafanaワークスペース・コンソールが表示されることを確認する。

      AMG-WorkspaceConsole

可視化

Grafana上でのメトリクスの可視化が行える状態になったので、実際にダッシュボードを作成してみます。

  • AMPのデータソースを追加

    • Grafana ワークスペースコンソール> 左部メニューのAWSアイコン > AWS Data Sourcesを選択
    • AWS Data Sources
      • Data sourcesタブ
      • Service
        • Amazon Managed Service for Prometheus
      • Regions
        • Asia Pacific (Tokyo)
      • AMPのワークスペースを選択してAdd data source
    • Provisioned data sourcesにAMPのワークスペースが追加されていることを確認する。
  • ダッシュボードの追加

    Grafana.comに公開されているダッシュボードをインポートして、EKSクラスターの可視化を行います。

無事、EKSクラスターとPodのメトリクスを可視化することができました!

  • CPU使用率

    AMG-Dashboard-CPU-Usages

  • メモリ使用率

    AMG-Dashboard-Memory-Usages

まとめと今後の展望

「やってみた」感想は以下のとおりです。

  • K8sはキャッチアップ中、PrometheusとGrafanaを触るのが初めての私でも、クラスターやPodのメトリクス収集と可視化を行うことができました。
  • Contributorの貢献、情報量の多さというOSSのメリットと、それをAWSがマネージドサービスとしてナレッジの集約・導入ハードルを下げて提供しているというメリットの両方を体感しました。
    • これはEKSにも当てはまると考えております。

今後の展望としては以下を検討しております。

  • 各エコシステムのアーキテクチャや仕様、制約の理解
  • ダッシュボードのカスタマイズやCloudWatchとの棲み分け整理
  • 監視・可視化という運用機能ならなおさらFargateで実行したい

特に3点目は、調査できたら改めて記事にしたいと思っております!
(実はFargateでトライして、苦戦したのでEC2で妥協したのはナイショ♡)

おまけ:VSCodeKubernetes拡張機能

毎日VSCodeのお世話になっております。VSCodeを使い始める前の日々には戻れないです。
ご存じの方も多いかと思いますが、VSCodeにはMicrosoft社製のKubernetes 拡張機能があります。
この拡張機能YAMLスキーママニフェストの入力補助を行う目的で導入していたのですが、左部パネルのK8sアイコンより、色々できることに気づきました。
K8sクラスターやNamespaceの切り替え、各リソースの情報の取得もできます。
便利〜!という蛇足でした。

最後までご覧いただきありがとうございました。
この記事がお一人でも多く方の参考になる、または、弊社に少しでも興味も持った方がいらっしゃいましたら幸甚です。 それでは、良いお年を〜!

参考文献

執筆:寺山 輝 (@terayama.akira)、レビュー:@sato.taichiShodoで執筆されました