本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
使用 在 Amazon ECS 上啟用 Application Signals AWS CDK
若要使用 在 Amazon ECS 上啟用 Application Signals AWS CDK,請執行下列動作。
為您的應用程式啟用 Application Signals – 如果您尚未在此帳戶中啟用 Application Signals,您必須授予 Application Signals 探索服務所需的許可。
import { aws_applicationsignals as applicationsignals } from 'aws-cdk-lib'; const cfnDiscovery = new applicationsignals.CfnDiscovery(this, 'ApplicationSignalsServiceRole', { } );
Discovery CloudFormation 資源會授予 Application Signals 下列許可:
-
xray:GetServiceGraph
-
logs:StartQuery
-
logs:GetQueryResults
-
cloudwatch:GetMetricData
-
cloudwatch:ListMetrics
-
tag:GetResources
如需有關此角色的詳細資訊,請參閱 CloudWatch Application Signals 的服務連結角色許可。
-
使用 AWS CDK 中的 AWS::ApplicationSignals 建構程式庫
來檢測您的應用程式。本文件中的程式碼片段提供於 TypeScript。如需其他特定語言的替代方案,請參閱 AWS CDK 支援的程式設計語言。 使用附屬模式在 Amazon ECS 上啟用 Application Signals
設定
instrumentation
以使用 AWS Distro for OpenTelemetry (ADOT) SDK Agent 檢測應用程式。以下是檢測 Java 應用程式的範例。如需所有支援的語言版本,請參閱 InstrumentationVersion。指定 將 CloudWatch Agent
cloudWatchAgentSidecar
設定為附屬容器。import { Construct } from 'constructs'; import * as appsignals from '@aws-cdk/aws-applicationsignals-alpha'; import * as cdk from 'aws-cdk-lib'; import * as ec2 from 'aws-cdk-lib/aws-ec2'; import * as ecs from 'aws-cdk-lib/aws-ecs'; class MyStack extends cdk.Stack { public constructor(scope?: Construct, id?: string, props: cdk.StackProps = {}) { super(); const vpc = new ec2.Vpc(this, 'TestVpc', {}); const cluster = new ecs.Cluster(this, 'TestCluster', { vpc }); const fargateTaskDefinition = new ecs.FargateTaskDefinition(this, 'SampleAppTaskDefinition', { cpu: 2048, memoryLimitMiB: 4096, }); fargateTaskDefinition.addContainer('app', { image: ecs.ContainerImage.fromRegistry('test/sample-app'), }); new appsignals.ApplicationSignalsIntegration(this, 'ApplicationSignalsIntegration', { taskDefinition: fargateTaskDefinition, instrumentation: { sdkVersion: appsignals.JavaInstrumentationVersion.V2_10_0, }, serviceName: 'sample-app', cloudWatchAgentSidecar: { containerName: 'ecs-cwagent', enableLogging: true, cpu: 256, memoryLimitMiB: 512, } }); new ecs.FargateService(this, 'MySampleApp', { cluster: cluster, taskDefinition: fargateTaskDefinition, desiredCount: 1, }); } }
使用常駐程式模式在 Amazon ECS 上啟用 Application Signals
注意
Amazon ECS Fargate 不支援協助程式部署策略,且僅支援 Amazon ECS on Amazon EC2。
以
HOST
網路模式執行 CloudWatch Agent 做為協助程式服務。設定
instrumentation
以使用 ADOT Python Agent 檢測應用程式。import { Construct } from 'constructs'; import * as appsignals from '@aws-cdk/aws-applicationsignals-alpha'; import * as cdk from 'aws-cdk-lib'; import * as ec2 from 'aws-cdk-lib/aws-ec2'; import * as ecs from 'aws-cdk-lib/aws-ecs'; class MyStack extends cdk.Stack { public constructor(scope?: Construct, id?: string, props: cdk.StackProps = {}) { super(scope, id, props); const vpc = new ec2.Vpc(this, 'TestVpc', {}); const cluster = new ecs.Cluster(this, 'TestCluster', { vpc }); // Define Task Definition for CloudWatch agent (Daemon) const cwAgentTaskDefinition = new ecs.Ec2TaskDefinition(this, 'CloudWatchAgentTaskDefinition', { networkMode: ecs.NetworkMode.HOST, }); new appsignals.CloudWatchAgentIntegration(this, 'CloudWatchAgentIntegration', { taskDefinition: cwAgentTaskDefinition, containerName: 'ecs-cwagent', enableLogging: false, cpu: 128, memoryLimitMiB: 64, portMappings: [ { containerPort: 4316, hostPort: 4316, }, { containerPort: 2000, hostPort: 2000, }, ], }); // Create the CloudWatch Agent daemon service new ecs.Ec2Service(this, 'CloudWatchAgentDaemon', { cluster, taskDefinition: cwAgentTaskDefinition, daemon: true, // Runs one container per EC2 instance }); // Define Task Definition for user application const sampleAppTaskDefinition = new ecs.Ec2TaskDefinition(this, 'SampleAppTaskDefinition', { networkMode: ecs.NetworkMode.HOST, }); sampleAppTaskDefinition.addContainer('app', { image: ecs.ContainerImage.fromRegistry('test/sample-app'), cpu: 0, memoryLimitMiB: 512, }); // No CloudWatch Agent sidecar is needed as application container communicates to CloudWatch Agent daemon through host network new appsignals.ApplicationSignalsIntegration(this, 'ApplicationSignalsIntegration', { taskDefinition: sampleAppTaskDefinition, instrumentation: { sdkVersion: appsignals.PythonInstrumentationVersion.V0_8_0 }, serviceName: 'sample-app' }); new ecs.Ec2Service(this, 'MySampleApp', { cluster, taskDefinition: sampleAppTaskDefinition, desiredCount: 1, }); } }
使用複本模式在 Amazon ECS 上啟用 Application Signals
注意
使用複本模式執行 CloudWatch Agent 服務需要特定的安全群組組態,才能與其他 服務通訊。對於 Application Signals 功能,使用最低傳入規則設定安全群組:連接埠 2000 (HTTP) 和連接埠 4316 (HTTP)。此組態可確保 CloudWatch Agent 與相依服務之間的適當連線。
執行 CloudWatch Agent 做為具有服務連線的複本服務。
設定
instrumentation
以使用 ADOT Python Agent 檢測應用程式。將 設定為
overrideEnvironments
使用服務連線端點與 CloudWatch 代理程式伺服器通訊,以覆寫環境變數。import { Construct } from 'constructs'; import * as appsignals from '@aws-cdk/aws-applicationsignals-alpha'; import * as cdk from 'aws-cdk-lib'; import * as ec2 from 'aws-cdk-lib/aws-ec2'; import * as ecs from 'aws-cdk-lib/aws-ecs'; import { PrivateDnsNamespace } from 'aws-cdk-lib/aws-servicediscovery'; class MyStack extends cdk.Stack { public constructor(scope?: Construct, id?: string, props: cdk.StackProps = {}) { super(scope, id, props); const vpc = new ec2.Vpc(this, 'TestVpc', {}); const cluster = new ecs.Cluster(this, 'TestCluster', { vpc }); const dnsNamespace = new PrivateDnsNamespace(this, 'Namespace', { vpc, name: 'local', }); const securityGroup = new ec2.SecurityGroup(this, 'ECSSG', { vpc }); securityGroup.addIngressRule(securityGroup, ec2.Port.tcpRange(0, 65535)); // Define Task Definition for CloudWatch agent (Replica) const cwAgentTaskDefinition = new ecs.FargateTaskDefinition(this, 'CloudWatchAgentTaskDefinition', {}); new appsignals.CloudWatchAgentIntegration(this, 'CloudWatchAgentIntegration', { taskDefinition: cwAgentTaskDefinition, containerName: 'ecs-cwagent', enableLogging: false, cpu: 128, memoryLimitMiB: 64, portMappings: [ { name: 'cwagent-4316', containerPort: 4316, hostPort: 4316, }, { name: 'cwagent-2000', containerPort: 2000, hostPort: 2000, }, ], }); // Create the CloudWatch Agent replica service with service connect new ecs.FargateService(this, 'CloudWatchAgentService', { cluster: cluster, taskDefinition: cwAgentTaskDefinition, securityGroups: [securityGroup], serviceConnectConfiguration: { namespace: dnsNamespace.namespaceArn, services: [ { portMappingName: 'cwagent-4316', dnsName: 'cwagent-4316-http', port: 4316, }, { portMappingName: 'cwagent-2000', dnsName: 'cwagent-2000-http', port: 2000, }, ], }, desiredCount: 1, }); // Define Task Definition for user application const sampleAppTaskDefinition = new ecs.FargateTaskDefinition(this, 'SampleAppTaskDefinition', {}); sampleAppTaskDefinition.addContainer('app', { image: ecs.ContainerImage.fromRegistry('test/sample-app'), cpu: 0, memoryLimitMiB: 512, }); // Overwrite environment variables to connect to the CloudWatch Agent service just created new appsignals.ApplicationSignalsIntegration(this, 'ApplicationSignalsIntegration', { taskDefinition: sampleAppTaskDefinition, instrumentation: { sdkVersion: appsignals.PythonInstrumentationVersion.V0_8_0, }, serviceName: 'sample-app', overrideEnvironments: [ { name: appsignals.CommonExporting.OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT, value: 'http://cwagent-4316-http:4316/v1/metrics', }, { name: appsignals.TraceExporting.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, value: 'http://cwagent-4316-http:4316/v1/traces', }, { name: appsignals.TraceExporting.OTEL_TRACES_SAMPLER_ARG, value: 'endpoint=http://cwagent-2000-http:2000', }, ], }); // Create ECS Service with service connect configuration new ecs.FargateService(this, 'MySampleApp', { cluster: cluster, taskDefinition: sampleAppTaskDefinition, serviceConnectConfiguration: { namespace: dnsNamespace.namespaceArn, }, desiredCount: 1, }); } }
使用 ESM 模組格式設定 Node.js 應用程式。ESM 模組格式的 Node.js 應用程式支援有限。如需詳細資訊,請參閱使用 ESM 的 Node.js 的已知限制。
對於 ESM 模組格式,使用
init
容器注入 Node.js 檢測 SDK 來啟用 Application Signals 不適用。略過此程序的步驟 2,並改為執行下列動作。將相關的相依性安裝到您的 Node.js 應用程式以進行自動檢測。
npm install @aws/aws-distro-opentelemetry-node-autoinstrumentation npm install @opentelemetry/instrumentation@0.54.
更新 TaskDefinition。
將其他組態新增至您的應用程式容器。
設定
NODE_OPTIONS
.(選用) 如果您選擇附屬模式,請新增 CloudWatch Agent。
import { Construct } from 'constructs'; import * as appsignals from '@aws-cdk/aws-applicationsignals-alpha'; import * as ecs from 'aws-cdk-lib/aws-ecs'; class MyStack extends cdk.Stack { public constructor(scope?: Construct, id?: string, props: cdk.StackProps = {}) { super(scope, id, props); const fargateTaskDefinition = new ecs.FargateTaskDefinition(stack, 'TestTaskDefinition', { cpu: 256, memoryLimitMiB: 512, }); const appContainer = fargateTaskDefinition.addContainer('app', { image: ecs.ContainerImage.fromRegistry('docker/cdk-test'), }); const volumeName = 'opentelemetry-auto-instrumentation' fargateTaskDefinition.addVolume({name: volumeName}); // Inject additional configurations const injector = new appsignals.NodeInjector(volumeName, appsignals.NodeInstrumentationVersion.V0_5_0); injector.renderDefaultContainer(fargateTaskDefinition); // Configure NODE_OPTIONS appContainer.addEnvironment('NODE_OPTIONS', '--import @aws/aws-distro-opentelemetry-node-autoinstrumentation/register --experimental-loader=@opentelemetry/instrumentation/hook.mjs') // Optional: add CloudWatch agent const cwAgent = new appsignals.CloudWatchAgentIntegration(stack, 'AddCloudWatchAgent', { containerName: 'ecs-cwagent', taskDefinition: fargateTaskDefinition, memoryReservationMiB: 50, }); appContainer.addContainerDependencies({ container: cwAgent.agentContainer, condition: ecs.ContainerDependencyCondition.START, }); }
部署更新的堆疊 – 在應用程式的主目錄中執行
cdk synth
命令。若要在 AWS 帳戶中部署服務,請在應用程式的主目錄中執行cdk deploy
命令。如果您使用附屬策略,您會看到已建立一項服務:
APPLICATION_SERVICE
是您應用程式的服務。它包含以下三個容器:init
– 初始化 Application Signals 所需的容器。ecs-cwagent
– 執行 CloudWatch 代理程式的容器
– 這是我們文件中的範例應用程式容器。在您的實際工作負載中,此特定容器可能不存在,或者可能會取代為您自己的服務容器。my-app
如果您使用 協助程式策略,您會看到已建立兩個 服務:
CloudWatchAgentDaemon
是 CloudWatch 代理程式協助程式服務。APPLICATION_SERVICE
是您應用程式的服務。它包含下列兩個容器:init
– 初始化 Application Signals 所需的容器。
– 這是我們文件中的範例應用程式容器。在您的實際工作負載中,此特定容器可能不存在,或者可能會取代為您自己的服務容器。my-app
如果您使用複本策略,您會看到已建立兩個 服務:
CloudWatchAgentService
是 CloudWatch 代理程式複本服務。APPLICATION_SERVICE
是您應用程式的服務。它包含下列兩個容器:init
– 初始化 Application Signals 所需的容器。
– 這是我們文件中的範例應用程式容器。在您的實際工作負載中,此特定容器可能不存在,或者可能會取代為您自己的服務容器。my-app