AWSブログAWS Distro for OpenTelemetry の Amazon EKS アドオンを使用したメトリクスとトレースの収集のメトリクス収集部分を確認したかったので、実際に実機確認した時のメモ。
やりたいこと
こちらのAWSブログにある構成に近いものを作って、EKS内にPrometheusを作らずにManaged Prometheusにメトリクスを飛ばし、Amazon Managed Grafanaでメトリクスを確認する。
前提条件
以下を満たしている必要がある。
- EKSのクラスターのk8sバージョンが1.19以降
- cert-managerを導入済み、かつversionが1.6未満
- EKSのAddon Manager用のRBAC設定
また、Amazon Managed PrometheusとAmazon Managed Grafanaが準備できている必要がある。こちらの準備方法は付録に記載した(大したこと書いてないけど)。
EKSは普通に作れば1.19以降なので割愛。
RBACに関してはこちらにManifestが用意されているので、これをそのままapplyすると良い。
cert-managerはhelmが用意されているので、こちらでインストールすると良い。
https://cert-manager.io/docs/installation/helm/
自環境だと1.7.0だったため、ダウングレードを実施した。
$ helm list -n cert-manager
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
cert-manager cert-manager 1 2022-02-04 11:26:40.968231 +0900 JST deployed cert-manager-v1.7.0 v1.7.0
$ helm upgrade -n cert-manager cert-manager jetstack/cert-manager --version v1.5.5
$ helm list -n cert-manager
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
cert-manager cert-manager 2 2022-06-20 11:45:15.434281 +0900 JST deployed cert-manager-v1.5.5 v1.5.5
なお、古いChartのバージョンはここで確認した。
また、新規にインストールする人はhelm install実行時に--set installCRDs=true
をつけることをお忘れなく。
ADOT Addonのインストール
ADOT Addonはawsコマンドでインストールする。
aws eks create-addon --addon-name adot --addon-version v0.45.0-eksbuild.1 --cluster-name $CLUSTER_NAME
実行直後は"status": "CREATING"
が表示されるので、これがACTIVE
に変わるのを待つ(2、3分くらい待つ)。
確認のためのコマンドは以下。
aws eks describe-addon --addon-name adot --cluster-name $CLUSTER_NAME
なお、前提条件のRBACを設定していないと、以下のようなエラーになる。
"status": "CREATE_FAILED",
"addonVersion": "v0.45.0-eksbuild.1",
"health": {
"issues": [
{
"code": "AccessDenied",
"message": "customresourcedefinitions.apiextensions.k8s.io \"opentelemetrycollectors.opentelemetry.io\" is forbidden: User \"eks:addon-manager\" cannot patch resource \"customresourcedefinitions\" in API group \"apiextensions.k8s.io\" at the cluster scope"
}
]
},
ADOT Collectorのインストール
メトリクスの収集はADOT Collectorというコンポーネントが実施する(下図)。
※引用元:https://aws.amazon.com/jp/blogs/news/metrics-and-traces-collection-using-amazon-eks-add-ons-for-aws-distro-for-opentelemetry/
これはOpenTelemetryController
というカスタムリソース(Addon追加時にインストールされる)で定義した情報を元にメトリクスを収集する。
$ kubectl api-resources | grep OpenTelemetryCollector
opentelemetrycollectors otelcol,otelcols opentelemetry.io/v1alpha1 true OpenTelemetryCollector
OpenTelemetryControllerで定義されたManifestが以下で公開されている。
https://github.com/aws-observability/aws-o11y-recipes/blob/main/sandbox/eks-addon-adot/otel-collector-xray-prometheus-complete.yaml
このManifestではAWS X-Rayにトレースを送るTrace PipelineとManaged Prometheusにメトリクスを送るMetrics Pipelineが用意されているそうだ。
中身を見ると、Prometheusのスクレイプ設定が入っていた。
元ネタのブログで興味深い記述として、
メトリクスパイプラインの Prometheus Receiver は、Prometheus サーバーの最小限の代替となることを目的としており、Prometheus クライアントライブラリでインストルメントされたマイクロサービスからメトリクスをスクレイピングすることができます。
とあり、Prometheusを立ててremote writeしなくても、Managed Prometheusにメトリクスを送れるようだ。
REGIONとWORKSPACEを置き換えれば動くようなので、sedで置き換える。WORKSPACEにはAMPのWorkspace IDを設定する。
wget https://raw.githubusercontent.com/aws-observability/aws-o11y-recipes/main/sandbox/eks-addon-adot/otel-collector-xray-prometheus-complete.yaml
sed -i "s/REGION/us-east-1/g" otel-collector-xray-prometheus-complete.yaml
sed -i "s/WORKSPACE/ws-xxxxx/g" otel-collector-xray-prometheus-complete.yaml
上記のManifestはkind: OpenTelemetryCollector
が稼働するNamespaceがaws-otel-eks
となっていたため、当該Namespaceを作成してopentelemetrycollectorをデプロイする。
kubectl create ns aws-otel-eks
kubectl apply -f otel-collector-xray-prometheus-complete.yaml
デプロイ後、リソースは以下の用に表示される。
$ kubectl get opentelemetrycollector.opentelemetry.io/observability -n aws-otel-eks
NAME MODE VERSION AGE
observability deployment 0.45.0 50s
ただし、このタイミングではManifest内で指定していたaws-otel-collector
というServiceAccountがないため、Podの起動に失敗する。
$ kubectl get all -n aws-otel-eks
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/observability-collector ClusterIP 10.100.232.27 <none> 2000/UDP 6m58s
service/observability-collector-headless ClusterIP None <none> 2000/UDP 6m58s
service/observability-collector-monitoring ClusterIP 10.100.7.243 <none> 8888/TCP 6m58s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/observability-collector 0/1 0 0 6m59s
NAME DESIRED CURRENT READY AGE
replicaset.apps/observability-collector-d4c8b8d6d 1 0 0 7m
そのため、こちらのページを参考に必要な権限を持ったServiceAccountを作成する。
※ヘルパースクリプトを見逃していたので以下の手順でやっているが、ヘルパースクリプトを流す方が早いかもしれない。
eksctl create iamserviceaccount \
--name aws-otel-collector \
--namespace aws-otel-eks \
--cluster ${CLUSTER_NAME} \
--attach-policy-arn arn:aws:iam::aws:policy/AmazonPrometheusRemoteWriteAccess \
--attach-policy-arn arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess \
--attach-policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy \
--approve \
--override-existing-serviceaccounts
なお、自分の環境ではServiceAccountが存在しないにも関わらず、以下のように表示されて作成が上手く行かなかった。
2022-06-20 16:22:00 [ℹ] 1 iamserviceaccount (aws-otel-eks/aws-otel-collector) was excluded (based on the include/exclude rules)
2022-06-20 16:22:00 [!] metadata of serviceaccounts that exist in Kubernetes will be updated, as --override-existing-serviceaccounts was set
2022-06-20 16:22:00 [ℹ] no tasks
この場合、eksctl delete iamserviceaccount
を実行して、再度createすると成功する。
作成した結果がこちら。
$ kubectl get sa -n aws-otel-eks
NAME SECRETS AGE
aws-otel-collector 1 88s
default 1 31m
observability-collector 1 30m
ServiceAccount作成後、ReplicaSetを削除して、Podの再作成を促す。
kubectl delete replicaset.apps/observability-collector-d4c8b8d6d
これでADOT Controllerが起動した。
$ kubectl get all -n aws-otel-eks
NAME READY STATUS RESTARTS AGE
pod/observability-collector-d4c8b8d6d-8wjbt 1/1 Running 0 38s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/observability-collector ClusterIP 10.100.232.27 <none> 2000/UDP 32m
service/observability-collector-headless ClusterIP None <none> 2000/UDP 32m
service/observability-collector-monitoring ClusterIP 10.100.7.243 <none> 8888/TCP 32m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/observability-collector 1/1 1 1 32m
NAME DESIRED CURRENT READY AGE
replicaset.apps/observability-collector-d4c8b8d6d 1 1 1 42s
AWSブログの図の通りであれば、既にメトリクスはManaged Prometheusに届いており、Managed Grafanaからも見れるはずだ。
動作確認
Amazon Grafanaにログインして、メトリクスが取れているか確認する。
左のExploreからkubelet_node_name
でクエリを発行すると、ノード名が取得できた。
付録:Amazon Managed Prometheus、Amazon Managed Grafanaの準備
Amazon Managed Prometheusの準備
AMPにアクセスし、「ワークプレイスを作成」で作成するだけ。
なお、メトリクスのストレージ的な機能しか持っていないので、expression browserは使用できない。
(試しに/graphにアクセスしてみたが、{"message":null}
が返ってくるだけだった)
Amazon Managed Grafanaの準備
Amazon Managed Grafanaを使うにはAWS SSOもしくはSAMLが必要となる。
AWS SSOは敷居が高いので、Auth0の無料アカウントを使ってSAMLにて設定した。
SAMLの利用に関してはこちらを参考にした。
参考にしたサイトが詳しいので設定方法は割愛する。
初期設定ではダッシュボードは空である。
左のAWSのアイコンからData sourcesをクリックし、ServiceでAMPを選択、RegionsでAMPのworkspaceがあるリージョンを選択すると、AMPのworkspaceが表示されるのでAddして初期設定は終了となる。