ADOTとContainer Insights Prometheusを試す

以下のAWSブログにしたがってAWS Distro for OpenTelemetryでPrometheusメトリクスをCloudWatchに送る方法を試したメモ。

クラスターの作成

1.21でクラスターを作成する。ノードなしで作成する。

cat << EOF > cluster.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: adot
  region: ap-northeast-1
  version: "1.21"
vpc:
  cidr: "10.0.0.0/16"

availabilityZones:
  - ap-northeast-1a
  - ap-northeast-1c

cloudWatch:
  clusterLogging:
    enableTypes: ["*"]

iam:
  withOIDC: true
EOF
eksctl create cluster -f cluster.yaml

ノードを作成する。

cat << "EOF" > managed-ng-1.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: adot
  region: ap-northeast-1

managedNodeGroups:
  - name: managed-ng-1
    minSize: 2
    maxSize: 2
    desiredCapacity: 2
    privateNetworking: true
    iam:
      attachPolicyARNs:
        - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
        - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
EOF
eksctl create nodegroup -f managed-ng-1.yaml

Adminロールにも権限をつけておく。

CLUSTER_NAME="adot"
USER_NAME="Admin:{{SessionName}}"
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
ROLE_ARN="arn:aws:iam::${AWS_ACCOUNT_ID}:role/Admin"
eksctl create iamidentitymapping --cluster ${CLUSTER_NAME} --arn ${ROLE_ARN} --username ${USER_NAME} --group system:masters

ADOT のデプロイ

オールインワンの設定を使ってデプロイする。

export CLUSTER_NAME=adot
export AWS_REGION=ap-northeast-1
wget https://raw.githubusercontent.com/aws-observability/aws-otel-collector/main/deployment-template/eks/otel-container-insights-prometheus.yaml
cat otel-container-insights-prometheus.yaml |sed "s/{{region}}/$AWS_REGION/g" | sed "s/{{cluster_name}}/$CLUSTER_NAME/g" | kubectl apply -f -
namespace/aws-otel-eks created
serviceaccount/aws-otel-collector created
clusterrole.rbac.authorization.k8s.io/otel-prometheus-role created
clusterrolebinding.rbac.authorization.k8s.io/otel-prometheus-role-binding created
deployment.apps/aws-otel-collector created

Podを確認する。

$ k get po -n aws-otel-eks
NAME                                  READY   STATUS    RESTARTS   AGE
aws-otel-collector-685565dd6c-gmjcn   1/1     Running   0          10m

どのIAM権限が必要なのかはっきりわからない。

CloudWatchAgentServerPolicyをIRSAでアタッチする。

AWS_ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
CLUSTER_NAME=adot
NAMESPACE=aws-otel-eks
SERVICE_ACCOUNT=aws-otel-collector
POLICY_ARN="arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"
eksctl create iamserviceaccount \
    --name ${SERVICE_ACCOUNT} \
    --namespace ${NAMESPACE} \
    --cluster ${CLUSTER_NAME} \
    --attach-policy-arn ${POLICY_ARN} \
    --override-existing-serviceaccounts \
    --approve

Podを再起動する。

k delete -n aws-otel-eks po --all

サンプルアプリケーションのデプロイ

リポジトリをクローンする。

git clone https://github.com/aws-observability/aws-otel-test-framework.git
cd aws-otel-test-framework/sample-apps/jmx/

ECRにログインする。

AWS_ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
AWS_REGION=$(aws configure get region)
aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com

リポジトリを作成する。

aws ecr create-repository --repository-name prometheus-sample-tomcat-jmx \
  --image-scanning-configuration scanOnPush=true \
  --region ${AWS_REGION}

イメージをビルドしてPushする。

docker build -t ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/prometheus-sample-tomcat-jmx:latest .
docker push ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/prometheus-sample-tomcat-jmx:latest

アプリケーションをデプロイする。

SAMPLE_TRAFFIC_NAMESPACE=javajmx-sample
curl https://raw.githubusercontent.com/aws-observability/aws-otel-test-framework/terraform/sample-apps/jmx/examples/prometheus-metrics-sample.yaml |
sed "s/{{aws_account_id}}/${AWS_ACCOUNT_ID}/g" |
sed "s/{{region}}/${AWS_REGION}/g" |
sed "s/{{namespace}}/$SAMPLE_TRAFFIC_NAMESPACE/g" |
kubectl apply -f -
namespace/javajmx-sample created
deployment.apps/tomcat-example created
service/tomcat-war-example created
pod/tomcat-traffic-generator created
pod/tomcat-bad-traffic-generator created

Podを確認する。

$ k get po -n javajmx-sample
NAME                              READY   STATUS    RESTARTS   AGE
tomcat-bad-traffic-generator      1/1     Running   0          5m39s
tomcat-example-78cf48d869-khb6n   1/1     Running   0          5m39s
tomcat-traffic-generator          1/1     Running   0          5m39s

CloudWatchコンソールを確認する。

f:id:sotoiwa:20210916181928p:plain

パフォーマンスログが送られ、メトリクスはとれているが、Container Insightsのダッシュボードにadotクラスターが出てこない。普通のContainer Insightsのメトリクス収集をデプロイする必要がありそう。

先ほどデプロイしたPrometheus用のものと、普通のコンテナメトリクス用のマニフェストが以下にあるが、独立していそう。

ServiceAccountも違うし、DaemonSetか、Deploymentかという点でも違う。

デプロイする。

kubectl apply -f https://raw.githubusercontent.com/aws-observability/aws-otel-collector/main/deployment-template/eks/otel-container-insights-infra.yaml
namespace/aws-otel-eks unchanged
serviceaccount/aws-otel-sa created
clusterrole.rbac.authorization.k8s.io/aoc-agent-role created
clusterrolebinding.rbac.authorization.k8s.io/aoc-agent-role-binding created
configmap/otel-agent-conf created
daemonset.apps/aws-otel-eks-ci created

Podを確認する。

$ k get po -n aws-otel-eks
NAME                                  READY   STATUS    RESTARTS   AGE
aws-otel-collector-685565dd6c-crh5f   1/1     Running   0          24m
aws-otel-eks-ci-4tsc5                 1/1     Running   0          57s
aws-otel-eks-ci-lgp9r                 1/1     Running   0          57s

CloudWatchAgentServerPolicyをIRSAでアタッチする。

AWD_ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
CLUSTER_NAME=adot
NAMESPACE=aws-otel-eks
SERVICE_ACCOUNT=aws-otel-sa
POLICY_ARN="arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"
eksctl create iamserviceaccount \
    --name ${SERVICE_ACCOUNT} \
    --namespace ${NAMESPACE} \
    --cluster ${CLUSTER_NAME} \
    --attach-policy-arn ${POLICY_ARN} \
    --override-existing-serviceaccounts \
    --approve

Podを再起動しておく。

k -n aws-otel-eks delete po --all

これでadotクラスターが出てくるようになった。

f:id:sotoiwa:20210916181848p:plain

JMXのメトリクスも見られた。

f:id:sotoiwa:20210916181906p:plain