CloudWatchでSSM Agentプロセスを監視してみた
CloudWatchでプロセス監視の設定を行う機会があったのでブログに残します。
やること
- Systems Manager パラメータストアにCloudWatch Agentの設定を登録
- EC2へCloudWatch Agentのインストール
- CloudWatchメトリクスに値が登録されていることを確認する
設定
1. Systems Manager パラメータストアにCloudWatch Agentの設定を登録
まずはSSM Agentプロセスを監視するためのCloudWatch Agentの設定を作成します。
プロセスの監視はこちらのドキュメントに記載されているprocstat プラグインを使用します。
プロセスを指定する方法は以下の3つの方法があります。
指定方法 | 説明 |
---|---|
pid_file | 作成するプロセス識別番号 (PID) ファイルの名前でプロセスを選択します。 /var/run に配置されているような.pidファイルを指定することができます。 |
exe | 正規表現の照合ルールを使用して、指定した文字列と一致するプロセス名のプロセスを選択します。 一致は「含む」一致です。つまり、一致する用語として agent を指定した場合、cloudwatchagent のような名前を持つプロセスは、その用語に一致します。 grep Name /proc/プロセスID/status でプロセスの名前を確認することが可能です。 |
pattern | プロセスの起動に使用するコマンドラインでプロセスを選択します。 正規表現の照合ルールを使用して指定した文字列と一致するコマンドラインを持つすべてのプロセスが選択されます。 コマンドで使用されるパラメータやオプションを含むコマンドライン全体が確認されます。 ps aux で出力されたCOMMAND列が該当するものになります。 |
また取得できるメトリクスはcpu_usageやpid_countなどが取得できます。
詳しくは公式ドキュメントをご確認ください。
今回はpid_count (プロセス数)を取得してみました。
CloudWatch Agentの設定は以下になります。
{ "metrics": { "metrics_collected": { "procstat": [ { "exe": "amazon-ssm-agent", "measurement": [ "pid_count" ] } ] }, "append_dimensions": { "InstanceId": "${aws:InstanceId}" } } }
上記の設定ではexeでプロセス名を指定しています。
また、append_dimensionsでディメンションにインスタンスIDを設定しました。
この設定内容でSystems Manager パラメータストアに登録していきます。
上記の設定をjsonファイルに保存してください。
パラメータストアへの登録は以下のコマンドで行います。
パラメータ名は「AmazonCloudWatch-」から始まる名前にしてください。
今回EC2が使用するIAMポリシー「CloudWatchAgentAdminPolicy」は「AmazonCloudWatch-」から始まるパラメータ名でないと使用できなくなっています。
独自の名前にしたい場合はカスタムポリシーを作成してください。
aws ssm put-parameter --name AmazonCloudWatch-process-monitoring --type String --value file://jsonファイル名
登録に成功すると以下のようにバージョンが返ってきます。
{ "Version": 1, "Tier": "Standard" }
2. EC2へCloudWatch Agentのインストール
パラメータストアにパラメータの登録が完了したらEC2へCloudWatch Agentのインストールを行っていきます。
監視対象のEC2は以下のCloudFormationテンプレートで作成しました。
CloudFormationテンプレート (ここをクリックしてください)
AWSTemplateFormatVersion: "2010-09-09" Description: Session Test Stack Metadata: # ------------------------------------------------------------# # Metadata # ------------------------------------------------------------# AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Parameters for VPC Parameters: - VPCCIDR - Label: default: Parameters for Subnet Parameters: - PublicSubnet01CIDR - Label: default: Parameters for EC2 Parameters: - EC2VolumeSize - EC2VolumeIOPS - EC2AMI - EC2InstanceType Parameters: # ------------------------------------------------------------# # Parameters # ------------------------------------------------------------# VPCCIDR: Default: 172.30.0.0/16 Type: String PublicSubnet01CIDR: Default: 172.30.0.0/24 Type: String EC2VolumeSize: Default: 30 Type: Number EC2VolumeIOPS: Default: 3000 Type: Number EC2AMI: Default: ami-079a2a9ac6ed876fc Type: AWS::EC2::Image::Id EC2InstanceType: Default: t3.micro Type: String Resources: # ------------------------------------------------------------# # VPC # ------------------------------------------------------------# VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VPCCIDR EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: test-vpc # ------------------------------------------------------------# # InternetGateway # ------------------------------------------------------------# InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: test-igw InternetGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref InternetGateway VpcId: !Ref VPC # ------------------------------------------------------------# # Subnet # ------------------------------------------------------------# PublicSubnet01: Type: AWS::EC2::Subnet Properties: AvailabilityZone: ap-northeast-1c CidrBlock: !Ref PublicSubnet01CIDR MapPublicIpOnLaunch: true Tags: - Key: Name Value: test-pub-01 VpcId: !Ref VPC # ------------------------------------------------------------# # RouteTable # ------------------------------------------------------------# PublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: test-pub-rtb PublicRouteTableRoute1: Type: AWS::EC2::Route Properties: DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway RouteTableId: !Ref PublicRouteTable PublicRtAssociation1: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PublicRouteTable SubnetId: !Ref PublicSubnet01 # ------------------------------------------------------------# # Security Group # ------------------------------------------------------------# EC2SG: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: for ec2 GroupName: test-sg-ec2 SecurityGroupEgress: - CidrIp: 0.0.0.0/0 FromPort: -1 IpProtocol: -1 ToPort: -1 Tags: - Key: Name Value: test-sg-ec2 VpcId: !Ref VPC # ------------------------------------------------------------# # IAM # ------------------------------------------------------------# EC2IAMRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - 'sts:AssumeRole' ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore - arn:aws:iam::aws:policy/CloudWatchAgentAdminPolicy RoleName: test-iam-role-ec2 Tags: - Key: Name Value: test-iam-role-ec2 EC2IAMInstanceProfile: Type: AWS::IAM::InstanceProfile Properties: InstanceProfileName: test-iam-instanceprofile-ec2 Roles: - !Ref EC2IAMRole # ------------------------------------------------------------# # KeyPair # ------------------------------------------------------------# KeyPair: Type: AWS::EC2::KeyPair Properties: KeyName: test-ec2-key KeyType: rsa Tags: - Key: Name Value: test-ec2-key # ------------------------------------------------------------# # EC2 # ------------------------------------------------------------# EC2: Type: AWS::EC2::Instance Properties: BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: DeleteOnTermination: true Encrypted: true Iops: !Ref EC2VolumeIOPS VolumeSize: !Ref EC2VolumeSize VolumeType: gp3 DisableApiTermination: false EbsOptimized: true IamInstanceProfile: !Ref EC2IAMInstanceProfile ImageId: !Ref EC2AMI InstanceType: !Ref EC2InstanceType KeyName: !Ref KeyPair NetworkInterfaces: - AssociatePublicIpAddress: true DeleteOnTermination: true DeviceIndex: 0 GroupSet: - !Ref EC2SG SubnetId: !Ref PublicSubnet01 Tags: - Key: Name Value: test-ec2
上記のCloudFormationテンプレートではパブリックサブネットに1台EC2が起動します。
デプロイは以下のコマンドで行います。
aws cloudformation create-stack --stack-name CloudFormationスタック名 --template-body file://CloudFormationテンプレートファイル名 --capabilities CAPABILITY_NAMED_IAM
EC2の作成が完了したら以下のコマンドでCloudWatch Agentのインストールを行います。
aws ssm send-command --instance-ids インスタンスID --document-name "AWS-ConfigureAWSPackage" --parameters '{"action":["Install"],"name":["AmazonCloudWatchAgent"]}' aws ssm send-command --instance-ids i-0a031789d94c080f6 --document-name "AmazonCloudWatch-ManageAgent" --parameters '{"action":["configure"],"optionalConfigurationLocation":["AmazonCloudWatch-process-monitoring"]}'
上記2つのコマンドはSystems Manager Run Commandを実行しています。
1つ目のコマンドでCloudWatch Agentのインストールを行っています。
2つ目のコマンドでCloudWatch Agentの設定をパラメータストアから読み込ませています。
3. CloudWatchメトリクスに値が登録されていることを確認する
ここからはマネジメントコンソールで確認していきます。
マネジメントコンソールからCloudWatchダッシュボードへ移動します。
画面遷移後、左の項目から「すべてのメトリクス」をクリックします。
「カスタム名前空間」の「CWAgent」をクリックします。
画面遷移後、「InstanceId,exe,pid_finder」をクリックするとインスタンス名が「test-ec2」でInstanceIdが該当のものが作成されています。
グラフを見ると値が1で登録されていることが確認できます。
さいごに
設定自体はとても簡単でした。
上手く設定できていない可能性があるのでブログには記載していませんが、カーネルモードのプロセス (psコマンドで[]がついてるもの、[kthreadd]や[rcu_gp]など)はexeやpatternで指定してもメトリクス値が0のままでした。
原因は不明ですがこちらについてはもう少し検証を行ってみたいと思います。