Container InsightsはまだEKS on Fargateをサポートしていないが、Prometheusメトリクスモニタリングを使用してFargate上のPodのメトリクスを取得してみるメモ。
クラスターの作成
1.21でクラスターを作成する。ノードなしで作成する。
cat << EOF > cluster.yaml apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: container-insights-fargate 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 fargateProfiles: - name: fp-default selectors: - namespace: default - namespace: kube-system - namespace: amazon-cloudwatch EOF
eksctl create cluster -f cluster.yaml
ロギング
Fargateでのマネージドなロギングを設定する。
まずNamespaceを作成する。
cat << EOF > aws-observability-namespace.yaml kind: Namespace apiVersion: v1 metadata: name: aws-observability labels: aws-observability: enabled EOF
kubectl apply -f aws-observability-namespace.yaml
ConfigMapを作成する。
cat << EOF > aws-logging-cloudwatch-configmap.yaml kind: ConfigMap apiVersion: v1 metadata: name: aws-logging namespace: aws-observability labels: data: output.conf: | [OUTPUT] Name cloudwatch_logs Match * region ap-northeast-1 log_group_name fluent-bit-cloudwatch log_stream_prefix from-fluent-bit- auto_create_group true parsers.conf: | [PARSER] Name crio Format Regex Regex ^(?<time>[^ ]+) (?<stream>stdout|stderr) (?<logtag>P|F) (?<log>.*)$ Time_Key time Time_Format %Y-%m-%dT%H:%M:%S.%L%z filters.conf: | [FILTER] Name parser Match * Key_name log Parser crio Reserve_Data On Preserve_Key On EOF
kubectl apply -f aws-logging-cloudwatch-configmap.yaml
IAMポリシーをダウンロードする。
curl -o permissions.json https://raw.githubusercontent.com/aws-samples/amazon-eks-fluent-logging-examples/mainline/examples/fargate/cloudwatchlogs/permissions.json
IAMポリシーを作成する。
aws iam create-policy --policy-name eks-fargate-logging-policy --policy-document file://permissions.json
IAMポリシーをPod実行ロールにアタッチする。
aws iam list-roles | jq -r '.Roles[].RoleName | select( . | contains("FargatePodExecutionRole") )' ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account) aws iam attach-role-policy \ --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/eks-fargate-logging-policy \ --role-name eksctl-container-insights-FargatePodExecutionRole-1M61R5UHYEUL
サンプルPodをデプロイする。
cat << EOF > sample-app-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: sample-app namespace: default spec: replicas: 3 selector: matchLabels: app: hey-yo template: metadata: labels: app: hey-yo spec: containers: - name: hey-yo image: public.ecr.aws/toricls/everlasting-hey-yo:latest EOF
kubectl apply -f sample-app-deployment.yaml
メトリクス
Container InsightsのPrometheusメトリクスのモニタリングを設定する。
- https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/ContainerInsights-Prometheus-Setup.html
- https://github.com/aws/containers-roadmap/issues/920#issuecomment-812021685
- https://github.com/aws-samples/amazon-cloudwatch-container-insights/tree/master/k8s-deployment-manifest-templates/deployment-mode/service/cwagent-prometheus
IAMロールを作成する。
eksctl create iamserviceaccount \ --name cwagent-prometheus \ --namespace amazon-cloudwatch \ --cluster container-insights-fargate \ --attach-policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy \ --approve \ --override-existing-serviceaccounts
Fargateプロファイルは作成済みなのでスキップ。
Deploymentのマニフェストをダウンロードして、クラスター名とリージョン名を書き換える。
wget https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/service/cwagent-prometheus/prometheus-eks-fargate.yaml sed -i -e "s/{{cluster_name}}/container-insights-fargate/;s/{{region_name}}/ap-northeast-1/" prometheus-eks-fargate.yaml
例のコメントにあるような設定を追加する。
cwagentconfig.jsonのmetric_declarationの下に以下を追加する。
{ "source_labels": ["job"], "label_matcher": "^kubernetes-nodes-cadvisor$", "dimensions": [["ClusterName","namespace","pod","container"]], "metric_selectors": [ "^container_cpu_usage_seconds_total$", "^container_memory_usage_bytes$" ] }, { "source_labels": ["job"], "label_matcher": "^kubernetes-nodes-cadvisor$", "dimensions": [["ClusterName","namespace","pod"]], "metric_selectors": [ "^container_network_(receive|transmit)_bytes_total$" ] },
prometheus.yamlのscrape_configsの下に下記を追加する。
- job_name: kubernetes-nodes-cadvisor sample_limit: 10000 kubernetes_sd_configs: - role: node relabel_configs: - replacement: kubernetes.default.svc:443 target_label: __address__ - source_labels: [__meta_kubernetes_node_name] regex: (.+) replacement: /api/v1/nodes/$1/proxy/metrics/cadvisor target_label: __metrics_path__ - action: labelmap regex: __meta_kubernetes_node_label_(.+) metric_relabel_configs: - source_labels: [namespace] action: drop regex: ^(amazon-cloudwatch|kube-system)$ - source_labels: [pod] regex: (.+)(-\w+-\w+)|(.+)(-\w+)|(.+) replacement: ${1}${3}${5} target_label: pod bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token scheme: https tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt insecure_skip_verify: true
Deploymentを作成する。
kubectl apply -f prometheus-eks-fargate.yaml
Podを確認する。
$ k get po -A NAMESPACE NAME READY STATUS RESTARTS AGE amazon-cloudwatch cwagent-prometheus-79db458586-lq9q6 1/1 Running 0 3m50s default sample-app-55947f9c75-bmddr 1/1 Running 0 26m default sample-app-55947f9c75-fqcgx 1/1 Running 0 26m default sample-app-55947f9c75-t88nm 1/1 Running 0 26m kube-system coredns-9f6f89c76-9ccp4 1/1 Running 0 51m kube-system coredns-9f6f89c76-lgkqs 1/1 Running 0 51m
CloudWatch Logsにログが収集できていることを確認する。
EMFを含まないログが多いが、たまにEMFを含むログが送られてきている。
こんな感じでEMFのログ取得できている。
{ "CloudWatchMetrics": [ { "Metrics": [ { "Name": "container_memory_usage_bytes" } ], "Dimensions": [ [ "ClusterName", "container", "namespace", "pod" ] ], "Namespace": "ContainerInsights/Prometheus" } ], "ClusterName": "container-insights-fargate", "Timestamp": "1629448193180", "Version": "0", "beta_kubernetes_io_arch": "amd64", "beta_kubernetes_io_os": "linux", "container": "hey-yo", "container_cpu_load_average_10s": 0, "container_file_descriptors": 7, "container_last_seen": 1629448195, "container_memory_cache": 0, "container_memory_mapped_file": 0, "container_memory_max_usage_bytes": 7573504, "container_memory_rss": 122880, "container_memory_swap": 0, "container_memory_usage_bytes": 1069056, "container_memory_working_set_bytes": 1069056, "container_processes": 2, "container_sockets": 0, "container_spec_cpu_period": 100000, "container_spec_cpu_shares": 2, "container_spec_memory_limit_bytes": 0, "container_spec_memory_reservation_limit_bytes": 0, "container_spec_memory_swap_limit_bytes": 0, "container_start_time_seconds": 1629446563, "container_threads": 2, "container_threads_max": 0, "eks_amazonaws_com_compute_type": "fargate", "failure_domain_beta_kubernetes_io_region": "ap-northeast-1", "failure_domain_beta_kubernetes_io_zone": "ap-northeast-1c", "id": "/kubepods/besteffort/podd568a774-833c-4bd0-bd94-9d9e5adaba4e/e078e206de637e5da80f357f49949739a5be1d10d758d381250b94017adf4860", "image": "public.ecr.aws/toricls/everlasting-hey-yo@sha256:00e3b7602c020a2a367dc0f75732c718a962898d80b02ca6ca3b30bce45c794c", "instance": "fargate-ip-10-0-126-158.ap-northeast-1.compute.internal", "job": "kubernetes-nodes-cadvisor", "kubernetes_io_arch": "amd64", "kubernetes_io_hostname": "ip-10-0-126-158.ap-northeast-1.compute.internal", "kubernetes_io_os": "linux", "name": "e078e206de637e5da80f357f49949739a5be1d10d758d381250b94017adf4860", "namespace": "default", "pod": "sample-app", "prom_metric_type": "gauge", "topology_kubernetes_io_region": "ap-northeast-1", "topology_kubernetes_io_zone": "ap-northeast-1c" }
この方法では、Container InsightsのダッシュボードにPodのメトリクスが出るわけではない。今回のクラスターが選択肢に出てこない。
メトリクスとしてはとれている。
ただし、container_cpu_usage_seconds_total
とかなので、そのままでは使いにくい値になっているし、個別のPodやコンテナではなく集約された値になっているので、用途が限られそう。
追記
Prometheus メトリクスの変換についてユーザーガイドに記載があった。
カウンタータイプのメトリクスは、前回のスクレイプからのデルタが送信される仕様になっている。スクレイプ間隔は1分なので、container_cpu_usage_seconds_total
を60で割るとCPU使用率になると思われる。
Metric Mathで計算したところ、それっぽい値になっている。
ここで表示しているのはnginxコンテナのメトリクスで、nginxのPodを起動して中でstressコマンドを実行して上限までCPUを使っている状態。topコマンドの結果とだいたい一致している。
$ k top pod -n default NAME CPU(cores) MEMORY(bytes) nginx 228m 51Mi sample-app-55947f9c75-bmddr 1m 0Mi sample-app-55947f9c75-fqcgx 1m 1Mi sample-app-55947f9c75-t88nm 1m 1Mi