Promeetheus Agent를 사용하여 ECS Fargate 메트릭을 AMP에 전송하고 Grafana에서 모니터링
개시하다
이 글은 AWS Advent Calendar 2021의 다섯째 날의 글이다.
Fargate 노드에 있습니다.js가 응용한 양도Prometheus Agent를 사이드카 컨테이너로 이동하여 Amazon Managed Service for Prometheus (AMP)에 전송Grafana에서 볼 수 있다.
참고로 Promeethus Agent는 아직 실험적 기능 없기 때문에 실제 업무에서 사용하는 것을 추천하지 않습니다.
본 보도의 환경 구축은 AWS CDK을 이용했다.
작업 환경
환경 구조
환경 구축을 즉시 추진하다.AMP는 아직 CDK에서 조작할 수 없기 때문에 AWS 콘솔에서 수동으로 작업공간을 제작한다.(2021/12/06)
aws-aps AWS CDK를 사용해서도 아마존 Managed Service for Promeetheus를 제작하는 작업공간을 확인했기 때문에 추천합니다..🙇🙇
lib/prometheus-agent-test-stack.ts의 코드도 수정되어 AWS CDK에서 Amazon Managed Service for Proometheus를 만드는 작업 공간으로 편집되었습니다.(2021/12/18 보충)
AMP 작업공간을 수동으로 작성하려면
먼저 작업공간을 만들기 위해 AMP 콘솔 화면로 마이그레이션합니다.
1. AMP 콘솔 화면에서 작업공간으로 이동하여 화면 만들기
2. AMP의 작업공간 만들기
3. AMP의 작업공간 제작 완료를 확인하면서 설정 값을 제어합니다.
AMP 작업공간
エンドポイント - リモート書き込み URL
은 Promoetheus Agent를 통해 AMP에 데이터를 보낼 때나Grafana에 데이터 원본을 등록할 때 필요하기 때문에 제어가 필요하다.AWS CDK로 환경 구축
CDK로 구축 작업을 추진하다.먼저 다음 명령을 사용하여 CDK 프로젝트를 만듭니다.언어 선택
TypeScript
을 사용합니다.mkdir prometheus-agent-test && cd prometheus-agent-test
cdk init --language typescript
먼저 CDK가 인프라 시설을 건설하기 전에 수집 테스트의 노드를 측정하는 데 사용한다.js 프로그램을 준비합니다.ECS Fargate가 시작되는 노드입니다.js 응용 프로그램 준비
이용prom-client, 노드.js 도량의 노드를 얻을 수 있습니다.js 프로그램을 준비합니다.
prometheus-agent-test
폴더에서 다음 명령을 실행합니다.mkdir metrics-app && cd metrics-app
npm init -y
npm install --save prom-client
다음metrics-app
폴더에 만들기index.js
다음 내용을 편집합니다.metrics-app/index.js
'use strict';
const http = require('http');
const server = http.createServer();
const client = require('prom-client');
const register = new client.Registry()
// 5秒間隔でメトリクスを取得する
client.collectDefaultMetrics({ register, timeout: 5 * 1000 });
server.on('request', async function(req, res) {
// /metrics にアクセスしたら、Prometheus のレポートを返す
if (req.url === '/metrics') {
res.setHeader('Content-Type', register.contentType)
const metrics = await register.metrics()
return res.end(metrics)
} else {
return res.writeHead(404, {'Content-Type' : 'text/plain'});
}
});
server.listen(8080);
node index.js
명령을 실행하고 방문해 보세요http://localhost:8080/metrics
.아래의 각종 양도 출력의 상황을 확인할 수 있다면 OK입니다.Promeetheus의 보고서가 정상적으로 출력되는 모습
이번에는 ECS에서 노드를js 응용 프로그램의 동작을 위해
Dockerfile
도 제작합니다.metrics-app/Dockerfile
FROM public.ecr.aws/docker/library/node:16-alpine3.12 AS builder
EXPOSE 8080
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --max-old-space-size=4096
COPY . .
CMD [ "node", "index.js" ]
위Dockerfile
를 제작한 후 동작을 재검증하기 위해 아래 명령을 실행한 후 방문http://localhost:8080/metrics
을 시도한다.docker build -t prometheus-agent-test/metrics-app .
docker run -p 8080:8080 prometheus-agent-test/metrics-app:latest
아까와 같은http://localhost:8080/metrics
방문 시 각종 도량 출력을 확인할 수 있으면 OK.Node.js 애플리케이션을 모니터링할 Promeetheus Agent 준비
먼저 Promaetheus 관련 파일을 구성하는 폴더를 만듭니다.
prometheus-agent-test
폴더에서 다음 명령을 실행합니다.mkdir prometheus-agent && cd prometheus-agent
Proometheus의 설정 템플릿 파일을 생성합니다.템플릿 파일sed을 이용하여 내용을 다시 쓴다__TASK_ID__
와 __REMOTE_WRITE_URL__
.prometheus-agent/prometheus.tmpl.yml
global:
scrape_interval: 5s
external_labels:
monitor: 'prometheus'
scrape_configs:
- job_name: 'prometheus-agent-test'
static_configs:
- targets: ['localhost:8080']
labels:
# デフォルトの localhost:8080 がインスタンスとして利用されると、
# メトリクスの判別がしづらくなるため ECS Task の ID を利用する
instance: '__TASK_ID__'
remote_write:
# AMP ワークスペース作成時に控えておいた、
# `エンドポイント - リモート書き込み URL` を設定する箇所
- url: '__REMOTE_WRITE_URL__'
sigv4:
region: ap-northeast-1
queue_config:
max_samples_per_send: 1000
max_shards: 200
capacity: 2500
설정 파일 제작이 완료되면 템플릿 파일을 이용하여 Proometheus의 설정 파일을 만들고 Proometheus Agent를 시작하는 하우징 스크립트를 만듭니다.prometheus-agent/docker-entrypoint.sh
#!/bin/sh
while [ -z "$taskId" ]
do
# ECS Fargate で起動したタスク ID を取得する
taskId=$(curl --silent ${ECS_CONTAINER_METADATA_URI}/task | jq -r '.TaskARN | split("/") | .[-1]')
echo "waiting..."
sleep 1
done
echo "taskId: ${taskId}"
echo "remoteWriteUrl: ${REMOTE_WRITE_URL}"
# タスク ID `taskId` および、環境変数 `REMOTE_WRITE_URL` で、
# Prometheus のテンプレートファイル `prometheus.tmpl.yml` の内容を書き換え、
# その結果を `/etc/prometheus/prometheus.yml` に出力する
cat /etc/prometheus/prometheus.tmpl.yml | \
sed "s/__TASK_ID__/${taskId}/g" | \
sed "s>__REMOTE_WRITE_URL__>${REMOTE_WRITE_URL}>g" > /etc/prometheus/prometheus.yml
# --enable-feature=agent で Prometheus を Agent モードで起動する
# Prometheus のコンフィグファイルには上記で出力した `/etc/prometheus/prometheus.yml` を利用する
/usr/local/bin/prometheus \
--enable-feature=agent \
--config.file=/etc/prometheus/prometheus.yml \
--web.console.libraries=/etc/prometheus/console_libraries \
--web.console.templates=/etc/prometheus/consoles
이렇게 되면 Promeetheus Agent의 시작 준비가 완료되고 최종 준비가 완료됩니다Dockerfile
.참고로 Proometheus Agentv2.32.0
는 나중에 사용할 수 있습니다.이 기사는 v2.32.1
를 사용합니다.prometheus-agent/Dockerfile
FROM alpine:3.15
ADD prometheus.tmpl.yml /etc/prometheus/
RUN apk add --update --no-cache jq sed curl
# ARM64 で動作する Prometheus v2.32.1 を curl でダウンロード展開する
RUN curl -sL -O https://github.com/prometheus/prometheus/releases/download/v2.32.1/prometheus-2.32.1.linux-arm64.tar.gz
RUN tar -zxvf prometheus-2.32.1.linux-arm64.tar.gz && rm prometheus-2.32.1.linux-arm64.tar.gz
# `prometheus` コマンドを `/usr/local/bin/prometheus` に移動する
RUN mv prometheus-2.32.1.linux-arm64/prometheus /usr/local/bin/prometheus
COPY ./docker-entrypoint.sh /
RUN chmod +x /docker-entrypoint.sh
CMD ["/docker-entrypoint.sh"]
CDK는 지금까지 인프라 정비 추진을 위한 사전 준비를 마쳤다.ECS Fargate 상위 노드js 애플리케이션 및 Promeetheus Agent 실행
그리고 CDK가 ECS Fargate에서 Node를js 애플리케이션과 Promeetheus Agent,Grafana의 운영 환경을 정비하기 위해
다시 쓰기
lib/prometheus-agent-test-stack.ts
의 내용.lib/prometheus-agent-test-stack.ts
import { Construct } from 'constructs';
import {
Stack,
StackProps,
aws_ecs as ecs,
aws_logs as logs,
aws_aps as aps,
aws_ecs_patterns as ecs_patterns,
aws_iam as iam,
aws_elasticloadbalancingv2 as elbv2,
Duration,
CfnOutput,
} from 'aws-cdk-lib';
export class PrometheusAgentTestStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// Node.js アプリに ecs_patterns.ApplicationLoadBalancedFargateService を利用して ALB 経由でアクセス可能にする
const projectName = 'prometheus-agent-test';
const fargateService = new ecs_patterns.ApplicationLoadBalancedFargateService(this, `${projectName}-fargate-service`, {
serviceName: `${projectName}-fargate-service`,
cpu: 256,
desiredCount: 3,
listenerPort: 80,
taskImageOptions: {
family: `${projectName}-taskdef`,
image: ecs.ContainerImage.fromAsset('metrics-app'),
containerPort: 8080,
logDriver: ecs.LogDrivers.awsLogs({
streamPrefix: `/${projectName}/metrics-app`,
logRetention: logs.RetentionDays.ONE_DAY
})
},
cluster: new ecs.Cluster(this, `${projectName}-cluster`, {
clusterName: `${projectName}-cluster`
}),
memoryLimitMiB: 512,
});
fargateService.targetGroup.configureHealthCheck({
path: "/metrics",
timeout: Duration.seconds(8),
interval: Duration.seconds(10),
healthyThresholdCount: 2,
unhealthyThresholdCount: 4,
healthyHttpCodes: "200",
});
// 本質ではないが、Gravition2 で動作させたいために RuntimePlatform のプロパティを上書きしている
const fargateServiceTaskdef = fargateService.taskDefinition.node.defaultChild as ecs.CfnTaskDefinition
fargateServiceTaskdef.addPropertyOverride('RuntimePlatform', {
CpuArchitecture: "ARM64",
OperatingSystemFamily: "LINUX"
});
// AMP への書き込み権限を付与する
fargateService.taskDefinition.taskRole.addManagedPolicy(
iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonPrometheusRemoteWriteAccess')
)
// (2021/12/18) Amazon Managed Service for Prometheus のワークスペースを作成して、Prometheus の remote-write URL を取得する
const apsWorkspace = new aps.CfnWorkspace(this, `${projectName}-prom-workspace`, {
alias: `${projectName}-prom-workspace`,
});
const apsWorkspaceRemoteUrl = `${apsWorkspace.attrPrometheusEndpoint}api/v1/remote_write`;
// (2021/12/18) 本記事で頻出する "エンドポイント - リモート書き込み URL" をコンソールに出力する
new CfnOutput(this, 'prom-remote-write-url', {
value: apsWorkspaceRemoteUrl,
description: 'Prometheus Workspace の remote-write URL',
exportName: 'PromRemoteWriteURL',
});
// AMP へメトリクス情報を送信するための Prometheus Agent コンテナを追加する
const containerName = `${projectName}-prometheus-agent`
fargateService.taskDefinition.addContainer(containerName, {
containerName,
image: ecs.ContainerImage.fromAsset('prometheus-agent'),
memoryReservationMiB: 128,
environment: {
// (2021/12/18) CDK 経由で作成した Prometheus の remote-write URL を設定する
REMOTE_WRITE_URL: apsWorkspaceRemoteUrl
},
logging: new ecs.AwsLogDriver({
streamPrefix: `/${projectName}/prometheus-agent`,
logRetention: logs.RetentionDays.ONE_DAY,
})
});
// Grafana のタスク定義を作成する
const grafanaDashboardTaskDefinition = new ecs.FargateTaskDefinition(this, `${projectName}-grafana-taskdef`, {
family: `${projectName}-grafana-taskdef`
});
// Grafana のタスクが Prometheus Query を叩けるように権限付与する
grafanaDashboardTaskDefinition.taskRole.addManagedPolicy(
iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonPrometheusQueryAccess')
)
// Grafana のコンテナを追加する。パスプレフィクスには dashboard を設定する
const grafanaDashboardContainerName = `${projectName}-grafana-dashboard`
grafanaDashboardTaskDefinition.addContainer(grafanaDashboardContainerName, {
containerName: grafanaDashboardContainerName,
image: ecs.ContainerImage.fromRegistry('public.ecr.aws/ubuntu/grafana'),
environment: {
AWS_SDK_LOAD_CONFIG: 'true',
GF_AUTH_SIGV4_AUTH_ENABLED: 'true',
GF_SERVER_SERVE_FROM_SUB_PATH: 'true',
GF_SERVER_ROOT_URL: '%(protocol)s://%(domain)s/dashboard'
},
portMappings: [{ containerPort: 3000 }],
memoryLimitMiB: 512,
logging: new ecs.AwsLogDriver({
streamPrefix: `/${projectName}/grafana-dashboard`,
logRetention: logs.RetentionDays.ONE_DAY,
})
});
const grafanaDashboardServiceName = `${projectName}-grafana-dashboard-service`
const grafanaDashboardService = new ecs.FargateService(this, grafanaDashboardServiceName, {
serviceName: grafanaDashboardServiceName,
cluster: fargateService.cluster,
taskDefinition: grafanaDashboardTaskDefinition,
desiredCount: 1
});
// Grafana のタスクを ALB のターゲットグループに紐づける
fargateService.listener.addTargets(`${projectName}-grafana-dashboard-target`, {
priority: 1,
conditions: [
elbv2.ListenerCondition.pathPatterns(['/dashboard/*']),
],
healthCheck: {
path: '/dashboard/login',
interval: Duration.seconds(10),
timeout: Duration.seconds(8),
healthyThresholdCount: 2,
unhealthyThresholdCount: 3,
healthyHttpCodes: "200"
},
port: 3000,
protocol: elbv2.ApplicationProtocol.HTTP,
targets: [grafanaDashboardService],
});
}
}
이후 cdk deploy
인프라 시설을 건설한다.CDK의 인프라 시설 건설이 정상적으로 실시되었을 때의 상황
depuro가 정상적으로 완료되었음을 확인한 후
Outputs
출력된 PrometheusAgentTestStack.prometheusagenttestfargateserviceServiceURL<識別子>
의 URL 끝에 부여/metrics
에 접근해 보십시오.출력된 URL 형식은 http://<識別子>.ap-northeast-1.elb.amazonaws.com
입니다.방문
http://<識別子>.ap-northeast-1.elb.amazonaws.com/metrics
이라는 것이다.ALB 노드를 경유합니다.js 응용 프로그램에 접근할 수 있는지 확인
또한
Outputs
에 출력된 PrometheusAgentTestStack.promremotewriteurl
는 이후 사용エンドポイント - リモート書き込み URL
할 때 사용되므로 제어해 주십시오.이로써 AWS CDK의 인프라 구축 작업은 완료됐다.마지막으로 Grafana에서 AMP의 메트릭을 시각화하는 작업을 진행합니다.
Grafana에서 AMP(Aroometheus)의 메트릭 시각화
이전 액세스
/metrics
경로와 마찬가지로 출력Outputs
된 URL의 끝에 액세스/dashboard/login
를 추가합니다.Grafana의 초기 사용자 및 비밀번호는 admin
입니다.즉, 방문을 시도해 본다
http://<識別子>.ap-northeast-1.elb.amazonaws.com/dashboard/login
.로그인 정보가 정확하면 새 비밀번호를 설정하는 화면으로 이동하고 새 비밀번호를 입력하여 로그인을 종료합니다.로그인한 후 Promaetheus(AMP)를 데이터 소스로 추가하려면 다음과 같이 하십시오.
1. 톱니바퀴 아이콘
Data sources
을 클릭2.
Add data source
버튼 클릭3. Promaetheus를 데이터 소스로 선택
4. Proometheus를 데이터 소스로 추가
그래파나로 Promeetheus(AMP)에 보내는 메트릭을 시각화할 준비가 됐기 때문에 실제로 그래파나의 대시보드로 메트릭을 시각화해 보았다.빠른 가시화 양도를 위해 계기판NodeJS Application Dashboard을 사용합니다.
1.클릭+아이콘, 클릭
Import
2.
NodeJS Application Dashboard
의 ID를 입력하고 Load
버튼을 클릭3. 필요한 정보를 입력하고
NodeJS Application Dashboard
가져오기 완료4. 대시보드의 Nodejs 프로그램의 양도를 확인할 수 있습니다
지금까지의 절차는 양도의 가시화를 완성했지만 부하의 실제 양도 변화 상황에 따라 확인해 보았다.사용Vegeta실제 부하.다음 명령을 실행합니다.
echo 'GET http://<識別子>.ap-northeast-1.elb.amazonaws.com/metrics' | vegeta attack -duration=5s | vegeta report
이후 다시 Grafana의 계기판을 보러 갔다.부하를 가하는 시간대 도표만 달라질 수 있다는 것을 확인할 수 있을 것이다.대시보드의 CPU 사용률 차트가 변경되었는지 확인할 수 있습니다.
끝말
이번에는 Amazon Managed Service for Proometheus(AMP)에 ECS Fargate의 메트릭을 보내고Grafana로 시각화하는 방법을 소개했다.
ECS의 서비스에서 작업을 수행할 때서비스 할인를 사용할 수 있기 때문에Promoetheus서비스 할인 설정를 실행하면 모든 용기의 도량을 단일 Promoetheus로 처리할 수 있습니다.
또 노드야.js 프로그램을 제작할 때 사용하는
prom-client
에서 제작레이어드 스케일하면 감시하고 싶은 항목을 자유롭게 추가할 수 있습니다.이번 보도가 ECS Fargate를 감시할 때 논의 자료 중 하나가 되면 좋겠다.
참조 링크
Reference
이 문제에 관하여(Promeetheus Agent를 사용하여 ECS Fargate 메트릭을 AMP에 전송하고 Grafana에서 모니터링), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/nikaera/articles/aws-ecs-fargate-amp-grafana텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)