のべラボ.blog

Tech Blog | AWS や サーバーレスやコンテナ などなど

Amazon EKS に Container Insights を導入する手順をまとめてみた

Amazon EKS には、Amazon CloudWatch Container Insights (以降、Container Insights )を導入できます。 Container Insights を導入すると、Amazon EKS クラスターやノード、Pod などといった単位でメトリクスを収集し、Amazon CloudWatch アラームを設定できます。またログを収集して Amazon CloudWatch Logs で参照・分析することもできるので、AWS に慣れた人には Amazon EKS のモニタリングやロギングを行う仕組みとして取り組みやすいのではないでしょうか。

docs.aws.amazon.com

Amazon EKS クラスターに Container Insights を導入する手順は下記の AWS のドキュメントに記載されています。

docs.aws.amazon.com

ただこのドキュメントに目を通していて、個人的に「おや?」と思いました。 というのも、メトリクスやログを収集する Agent に Amazon CloudWatch へのアクセスを許可するという重要な部分の設定については他のドキュメントを読んで実施してね、という流れになっているからです。

個人的には、何かを操作する手順をドキュメントに記載するときには、そのページに必要な説明や手順をすべて掲載し、読者は 1つのページを上から下に読めば必要な手順を理解・実行できるようにすべきと思っています。 なので、自分のメモ用に、もしくは他の人への説明用に、具体的な手順をまとめておこうと思い立ちました。

なお、今回まとめた手順は、2023年4月時点の検証に基づいています。 Amazon EKS クラスターと、Amazon EC2 インスタンスを使用するマネージドノードグループも作成済です。また、メトリクスやログを収集する Agent として CloudWatch AgentFluent Bit の Agent を使用する前提とします。


目次


Agent への Amazon CloudWatch へのアクセスの許可について

Amazon EKS では、 CloudWatch AgentFluent Bit の AgentKubernetes の DaemonSet で管理される Pod として実行されます。これらの Agentに Amazon CloudWatch へのアクセスを許可する方法は 2種類です。 どちらも AWS IAM の管理ポリシーである CloudWatchAgentServerPolicy を設定した IAM ロールを使用しますが、その IAM ロールの適用方法が異なります。

1. ノードである EC2 インスタンスに IAM のロールを設定する。

この方法は設定自体はシンプルですが、Agent 以外の Pod にも Amazon CloudWatch へのアクセスを許可してしまうことになります。これは最小権限の原則の観点から望ましくありません。

https://cdn-ak.f.st-hatena.com/images/fotolife/n/neob/20230410/20230410083759.png

2. Agent の Pod に IAM ロール と関連付けた Service Account を設定する。

この方法の場合、Service Account を設定した Pod だけに Amazon CloudWatch へのアクセスを許可できます。よって今回は、こちらの方法を使用する前提とします。

https://cdn-ak.f.st-hatena.com/images/fotolife/n/neob/20230410/20230410083840.png


手順 1. クイックスタートセットアップの実施

この手順は、次のドキュメント通りに実施することで完了できます。

docs.aws.amazon.com

下記は、クラスター名が test-cluster という東京リージョンの Amazon EKS クラスターにクイックスタートセットアップを実施する例です。

ClusterName=test-cluster
RegionName=ap-northeast-1
FluentBitHttpPort='2020'
FluentBitReadFromHead='Off'
[[ ${FluentBitReadFromHead} = 'On' ]] && FluentBitReadFromTail='Off'|| FluentBitReadFromTail='On'
[[ -z ${FluentBitHttpPort} ]] && FluentBitHttpServer='Off' || FluentBitHttpServer='On'
curl https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/quickstart/cwagent-fluent-bit-quickstart.yaml | sed 's/{{cluster_name}}/'${ClusterName}'/;s/{{region_name}}/'${RegionName}'/;s/{{http_server_toggle}}/"'${FluentBitHttpServer}'"/;s/{{http_server_port}}/"'${FluentBitHttpPort}'"/;s/{{read_from_head}}/"'${FluentBitReadFromHead}'"/;s/{{read_from_tail}}/"'${FluentBitReadFromTail}'"/' | kubectl apply -f - 

この手順により amazon-cloudwatch という名前の Namespace が作成され、主要なオブジェクトが作成されます。

Agent となる Pod の起動を次のコマンドで確認します。

kubectl get pods -n amazon-cloudwatch

Pod は DaemonSet で管理されているので、ノード数分の Pod が表示されれば OK です。

NAME                     READY   STATUS    RESTARTS   AGE
cloudwatch-agent-5b4hb   1/1     Running   0          2m22s
cloudwatch-agent-6n5qc   1/1     Running   0          2m22s
fluent-bit-d2gfh         1/1     Running   0          2m22s
fluent-bit-hncw9         1/1     Running   0          2m22s

手順 2. IRSA(IAM Roles for Service Accounts)による既存の Service Accountのオーバーライド

次に Agent の Pod に Amazon CloudWatch へのアクセスを許可します。

手順 1. が完了した段階で、CloudWatch Agent の Pod には、cloudwatch-agent という Service Accountが、Fluent Bit の Agent には fluent-bit という Service Account が設定されています。

これらの Service Account に、AWS IAM のロールを関連付ける必要があります。 これは、Amazon EKS でサポートされている IRSA(IAM Roles for Service Accounts) という仕組みを使用することで実現できます。

IRSA を使用するには、まず Amazon EKS クラスターの OpenID Connect プロバイダ (OIDC プロバイダ)を AWS IAM に登録します。 これは次のコマンドにて行えますが、クラスター毎に 1 回実施すれば OK です。

eksctl utils associate-iam-oidc-provider --cluster ${ClusterName} --approve

次に Service Account cloudwatch-agent に CloudWatchAgentServerPolicy を設定した IAM ロールを設定します。

eksctl create iamserviceaccount \
  --name cloudwatch-agent \
  --namespace amazon-cloudwatch \
  --role-name ${ClusterName}-cloudwatch-agent-role  \
  --cluster ${ClusterName}  \
  --attach-policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy \
  --override-existing-serviceaccounts \
  --approve

Service Account fluent-bit にも同じように CloudWatchAgentServerPolicy を設定した IAM ロールを設定します。

eksctl create iamserviceaccount \
  --name fluent-bit \
  --namespace amazon-cloudwatch \
  --role-name ${ClusterName}-fluent-bit-role  \
  --cluster ${ClusterName}  \
  --attach-policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy \
  --override-existing-serviceaccounts \
  --approve

ここで ポイント になるのは、7 行目の --override-existing-serviceaccounts オプションです。 手順 1. のクイックスタートセットアップですでに Service Account は作成されています。--override-existing-serviceaccounts オプションを付けることで作成済の Service Account に AWS IAM のロールを設定できます。

この後、Agent の Pod の再起動が必要になるので、DaemonSet をリスタートしておきましょう。

kubectl rollout restart ds cloudwatch-agent -n amazon-cloudwatch
kubectl rollout restart ds fluent-bit -n amazon-cloudwatch

手順 3. 動作確認

この後 1~2分ほど待って、Container Insights が使用できるか確認してみます。

AWS マネジメントコンソール で Amazon CloudWatch のページ左側のメニューから [ インサイト ] - [ Container Insights ] を選択します。 下図では、[ パフォーマンスのモニタリング ] で test-cluster のメトリクスの表示を確認しています。

他にも、様々な切り口でメトリクスを確認してみて下さい。

また、ログの収集も確認してみます。Amazon CloudWatch のページ左側のメニューから [ ログ ] - [ ロググループ ] を選択します。 下図では、test-cluster のロググループが作成されていることを確認しています。


今回の所感

今回紹介した手順でポイントになるのは、手順 2. です。手順 2. については、AWS の Container Insights のドキュメントには具体的な記載がありません。ただ、手順 2.の実施においては、Kubernetes の RBAC や Service Account、Amazon EKS の IRSA の仕組みの理解が必要になるので、AWS のドキュメントのように他のページで確認して下さい、という記述になるのは、仕方がない部分もあるのかもしれません。

とはいうものの、Container Insights を導入する具体的な手順は明確に示しておくことは必要かと思いますので、この記事でそれをまとめることができてよかったと思ってます!


/* -----codeの行番号----- */