この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
現在開催されている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の中はこんな感じです。
cloudwatch-namespace.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
ファイルの中身はこんな感じになっています。
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
ファイルの内容はこんな感じ。
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)でした。