k8s環境のメトリクスやログを取得するマネージドサービス「CloudWatch Container Insights」が発表されました!
現在開催されているKubeCon + CloudNativeCon Europe 2019 - Linux Foundation Eventsにおいて、Kubernetes環境のコンテナ環境のメトリクスを取得する「CloudWatch Container Insights」が発表されました!
コンテナワークロードのためのメトリクス・ログモニタリングサービス、CloudWatch Container Insights の Public Preview を発表しました!! #KubeCon
— ポジティブな Tori (@toricls) May 20, 2019
従来、EKSにおいてPodの状態を監視したり各種ログを取得するには、サードパーティーのOSSや監視用のSaaSなどが実質的にほぼ必須だったんですが、これによりAWSのマネージドサービス(CloudWatch)だけで、それらが完結します。
パブリックプレビューなので、今すぐ動作確認できます。もちろん、東京リージョンもあるよ!!
- Canada (Central)
- US East (N. Virginia)
- US East (Ohio)
- US West (N. California)
- US West (Oregon)
- EU (Frankfurt)
- EU (Paris)
- Asia Pacific (Mumbai)
- Asia Pacific (Singapore)
- Asia Pacific (Sydney)
- Asia Pacific (Tokyo)
- Asia Pacific (Seoul)
- South America (São Paulo)
CloudWatch Container Insightsは、2019年5月21日現在、まだ正式リリースされていないパブリックプレビューの状態で、サービス内容はいつでも変更される可能性があることご注意ください。
k8sコンテナ丸見えきたか…!! ( ゚д゚) ガタッ / ヾ __L| / ̄ ̄ ̄/_ \/ /
CloudWatch Container Insightsとは?
公式ドキュメント:Using Container Insights - Amazon CloudWatch
従来、AWSにおけるk8s環境(EKS含む)において、そのNode(EC2)や各コンテナ、ネットワークのメトリクスやログを収集するためのマネージドの仕組みは存在せず、別途FluentdやDatadogなどのオープンソースやSaaSなどを利用する必要がありました。
今回のCloudWatch Container Insightsの登場により、CPU、メモリー、ディスク、ネットワークを収集し、かつコンテナ環境の問題の特定と解決に重要な、コンテナの再起動の失敗などの診断情報も取得できます。さらに、CloudWatchアラームとの連携ももちろんできます!
さらに、運用データはログイベントとして収集可能で、それらを組み合わせたダッシュボードやメトリクスを提供します。
EKS環境のセットアップ
もし、手元にEKSの環境がない場合は、クイックスタートを使うのが一番はやいです。こちらの記事を参考にしてみてください。
Container Insightsのセットアップ方法
まず最初に、導入の前提条件を確認します。
1. 導入前提条件の確認
改めて、現在利用できるリージョンを確認します。
導入にはkubectl
が必要となります。こちら(kubectl のインストール - Amazon EKS)を確認してください。
また、すでにk8s環境を動作させている場合は、いかが必要となります。
- k8sクラスターがrole-based access control(RBAC)で動作していること
- kubeletがWebhook認証モードで動作していること
2. ワーカーノードへのIAMロールの割当
k8sのワーカーノードとして動作しているEC2インスタンスのIAMロールにCloudWatchAgentServerPolicy
をアタッチします。
3. クラスターメトリクス収集のためのCloudWatch Agentの設定
CloudWatch用のネームスペースの作成
CloudWatch用のネームスペースをk8sクラスターに作成します。
$ curl -O https://s3.amazonaws.com/cloudwatch-agent-k8s-yamls/kubernetes-monitoring/cloudwatch-namespace.yaml
yamlの中はこんな感じです。
apiVersion: v1 kind: Namespace metadata: name: amazon-cloudwatch labels: name: amazon-cloudwatch
kubectl apply
で、名前空間を適用します。
$ kubectl apply -f cloudwatch-namespace.yaml
こんな感じでネームスペースが作成されていればOkです。
$ kubectl get namespace NAME STATUS AGE amazon-cloudwatch Active 16s default Active 33m kube-public Active 33m kube-system Active 33m
クラスター内にサービスアカウントを追加
まだ設定していない状態であれば、下記手順で、CloudWatch Agentのサービスアカウントを作成します。
$ curl -O https://s3.amazonaws.com/cloudwatch-agent-k8s-yamls/kubernetes-monitoring/cwagent-serviceaccount.yaml
$ kubectl apply -f cwagent-serviceaccount.yaml
CloudWatch Agent用のConfigMapを追加
CloudWatch agent用のConfigMapを追加します。CloudWatch agentの設定情報は、ConfigMapを利用して設定するのでkubernetesのバージョンは1.12
以上が必要となります。
$ curl -O https://s3.amazonaws.com/cloudwatch-agent-k8s-yamls/kubernetes-monitoring/cwagent-configmap.yaml
ファイルの中身はこんな感じになっています。
apiVersion: v1 data: # Configuration is in Json format. No matter what configure change you make, # please keep the Json blob valid. cwagentconfig.json: | { "structuredlogs": { "metrics_collected": { "kubernetes": { "cluster_name": "{{cluster-name}}", "metrics_collection_interval": 60 } }, "force_flush_interval": 5 } } kind: ConfigMap metadata: name: cwagentconfig namespace: amazon-cloudwatch
{{cluster-name}}
の部分を、適用するk8sクラスターのクラスター名に変更します。これにより、CloudWatch agentがEC2タグからクラスタ名をEC2タグから取得可能となります。
以下のコマンドで、ConfigMapを適用します。
$ kubectl apply -f cwagent-configmap.yaml
CloudWatch Agentをデーモンセットとして配置
最後に、CloudWatch agentを各ワーカーノードにデーモンセットとして配置します。
$ curl -O https://s3.amazonaws.com/cloudwatch-agent-k8s-yamls/kubernetes-monitoring/cwagent-daemonset.yaml
ファイルの内容はこんな感じ。
apiVersion: apps/v1 kind: DaemonSet metadata: name: cloudwatch-agent namespace: amazon-cloudwatch spec: selector: matchLabels: name: cloudwatch-agent template: metadata: labels: name: cloudwatch-agent spec: containers: - name: cloudwatch-agent image: amazon/cloudwatch-agent:latest imagePullPolicy: Always #ports: # - containerPort: 8125 # hostPort: 8125 # protocol: UDP resources: limits: cpu: 200m memory: 100Mi requests: cpu: 200m memory: 100Mi # Please don't change below envs env: - name: HOST_IP valueFrom: fieldRef: fieldPath: status.hostIP - name: HOST_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: K8S_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace # Please don't change the mountPath volumeMounts: - name: cwagentconfig mountPath: /etc/cwagentconfig volumes: - name: cwagentconfig configMap: name: cwagentconfig terminationGracePeriodSeconds: 60 serviceAccountName: cloudwatch-agent
適用します。
$ kubectl apply -f cwagent-daemonset.yaml
配置結果を確認します。
$ kubectl get pods -n amazon-cloudwatch NAME READY STATUS RESTARTS AGE cloudwatch-agent-6dwzv 1/1 Running 0 14s cloudwatch-agent-khmkx 1/1 Running 0 14s cloudwatch-agent-kq57t 1/1 Running 0 14s
ひとまずここまでで、最低限のインストールは完了です。
CloudWatchを確認してメトリクスとログを確認する
早速、CloudWatchを確認してみましょう。
ロググループに、以下のようなロググループが作成されていればOKです。
ドリルダウンすると、各ワーカーノード毎のログストリームが作成されています。
さらにドリルダウンすると、ワーカーノードで出力されたログが確認できます。
もちろん、CloudWatch Logs Insightsと統合されているため、クエリによるログの分析も可能です。
メトリクスももちろん取得可能。メトリクス直下にContainerInsightsのメトリクスが自動的に取得されています。
メトリクス名の「自動ダッシュボードの表示」から、各メトリクスの一覧をグラフ形式で表示可能です。
左上のドロップダウンからPodを選択すると…
Pod単位でのCPU、メモリ、ネットワーク関連のメトリクスを一括ダッシュボード表示可能です。いやぁこれは感動するわ。もちろん、このメトリクスからCloudWatch Alarmも設定が可能。
取得できるメトリクスやLogイベントは、下記ページに纏められています。合わせて参照ください。
- Metrics Collected by Container Insights - Amazon CloudWatch
- Relevant Fields in Performance Log Events - Amazon CloudWatch
Fluentdを利用したコンテナログのCloudWatch Logsへの転送
ここまでで、基本的なメトリクスやインフラ関連のログがCloudWatch Logsに転送されているところまで確認しました。
ここからは、肝心要のコンテナログのCloudWatch Logsへの転送設定をやります。ここでは、Fluentdを利用します。
この設定により、以下のロググループがCloudWatch Logsに作成されます。
Log Group Name | Log Source |
---|---|
/aws/containerinsights/Cluster_Name/application | All log files in /var/log/containers |
/aws/containerinsights/Cluster_Name/host | Logs from /var/log/dmesg, /var/log/secure, and /var/log/messages |
/aws/containerinsights/Cluster_Name/dataplane | Logs from /var/log/journal |
CloudWatch用のネームスペース作成
これはCloudWatchエージェント導入したときと同じです。既に導入してたら、不要です。
$ curl -O https://s3.amazonaws.com/cloudwatch-agent-k8s-yamls/kubernetes-monitoring/cloudwatch-namespace.yaml
$ kubectl apply -f cloudwatch-namespace.yaml
Fluentdのインストール
Fluentdデプロイ用の設定ファイルをダウンロードします。
$ curl -O https://s3.amazonaws.com/cloudwatch-agent-k8s-yamls/fluentd/fluentd.yml
ログを送信するクラスターとリージョン名を設定して、configmapを作成します。cluster_name
とregion_name
は、それぞれの環境に合わせて変更してください。
$ kubectl create configmap cluster-info \ --from-literal=cluster.name=cluster_name \ --from-literal=logs.region=region_name -n amazon-cloudwatch
上記コマンドでConfigmapの作成が完了したら、Fluentdをデーモンセットとしてクラスターに設定します。
$ kubectl apply -f fluentd.yml
しばらく待って、各ノードにデーモンセットとして、以下のpodが起動しているのが確認できればOKです。
$ kubectl get pods -n amazon-cloudwatch NAME READY STATUS RESTARTS AGE cloudwatch-agent-6dwzv 1/1 Running 0 4h21m cloudwatch-agent-khmkx 1/1 Running 0 4h21m cloudwatch-agent-kq57t 1/1 Running 0 4h21m fluentd-cloudwatch-6v6cv 1/1 Running 0 9m31s fluentd-cloudwatch-ccqzs 1/1 Running 0 9m31s fluentd-cloudwatch-j7hzx 1/1 Running 0 9m31s
CloudWatch Logsへのログ転送の確認
CloudWatch Logsコンソールを開いて、以下のロググループが作成されていればOKです。
ロググループの中に、アプリケーションログが転送されていることを確認できました。素晴らしい!
まとめ「Container InsightsでEKSのメトリクス監視〜ログ管理が超絶進化」
AWSの代表的なコンテナワークロードのECSやFargateは、既にCloudWatchと密接に統合されているため、ログの管理やメトリクスの取得は、他のAWSサービスと同じ手法で設定することができていました。はっきり言って設定はめっちゃ簡単です。
ただ、EKSに関しては、別途監視用のSaaSを契約したりPrometheusやGrafanaの導入が必要でした。
今回のContainer Insightsの発表により、サードパーティーのツールを組み合わせる面倒くささが解消され、慣れ親しんだCloudWathを使うことで、ログの管理、メトリクスの管理、アラームの設定が全て一括してマネージドサービスで完結します!
設定も特段難しいことはなく、k8sに適用するマニフェストファイルがAWSより提供されるので、それを順番にkubect apply
していくだけです。後は、ワーカーノードのEC2のIAMロールにポリシーを追加するぐらいですね。
2019年5月21日時点では、まだパブリックベータという位置付けですが、従来のEKS運用の面倒くささを大きな部分で解消するでかいアップデートなので、まずは手元の検証環境にいれて動作確認してみてください。
やっぱり、AWSのサービスはマネージド統合されてこそですから。
それでは、今日はこのへんで。濱田(@hamako9999)でした。