AWS CDKからmackerel-container-agentをサイドカーにしたタスク定義を作成したいことがよくあるので,ライブラリを継承してmackerel-container-agentを必ず同梱するようなタスク定義クラスを作ってみた.
コードは以下.
import * as cdk from '@aws-cdk/cdk' import * as ecs from '@aws-cdk/aws-ecs' export interface Ec2TaskDefWithMackerelProps extends ecs.Ec2TaskDefinitionProps { mackerelRoles: string mackerelApiKey?: string } export class Ec2TaskDefWithMackerel extends ecs.Ec2TaskDefinition { constructor(scope: cdk.Construct, id: string, props: Ec2TaskDefWithMackerelProps) { super(scope, id, props) const platform = this.networkMode === ecs.NetworkMode.AwsVpc ? 'ecs_awsvpc' : 'ecs' const mackerelContainer = this.addContainer('mackerel-container-agent', { image: new ecs.DockerHubImage('mackerel/mackerel-container-agent:latest'), environment: { MACKEREL_CONTAINER_PLATFORM: platform, MACKEREL_ROLES: props.mackerelRoles, MACKEREL_APIKEY: props.mackerelApiKey || 'YOUR_API_KEY', }, memoryLimitMiB: 128, }) if (this.networkMode !== ecs.NetworkMode.AwsVpc) { this.addVolume({ name: 'cgroup', host: { sourcePath: '/cgroup', // or Amazon Linux 2 // sourcePath: '/sys/fs/cgroup', }, }) this.addVolume({ name: 'docker_sock', host: { sourcePath: '/var/run/docker.sock', }, }) mackerelContainer.addMountPoints( { containerPath: '/host/sys/fs/cgroup', sourceVolume: 'cgroup', readOnly: true, }, { containerPath: '/var/run/docker.sock', sourceVolume: 'docker_sock', readOnly: true, }, ) } this.defaultContainer = undefined } }
現状はEC2の場合のみ対応していて,どのネットワークモードでも動作する.(デフォルトはBridgeモード)
const apiTaskDef = new Ec2TaskDefWithMackerel(this, 'ApiTaskDef', { mackerelRoles: 'sample:api' })
mackerel-container-agentのドキュメントはこちら.
余談
this.defaultContainer = undefined
この部分は,mackerel-container-agentがdefault container
としてセットされるのを防いでいる.
default containerはALBがタスクにアクセスする際のコンテナ,つまり「Container to load balance(負荷分散用のコンテナ)」としてアクセスされるコンテナのこと.
これはAWS CDKの用語で,ドキュメントに説明がある.
The first essential container that is added to this task will become the default container.
と書いてあるとおり,最初にessential: true
なコンテナが選ばれるという動作になっており,mackerel-container-agentが選ばれてしまうので回避が必要.