長生村本郷Engineers'Blog

千葉県長生村本郷育ちのエンジニアが書いているブログ

ECS EC2 上で起動する Datadog Agent コンテナが unhealthy になる時の処方箋

f:id:kenzo0107:20190110112818p:plain

概要

$ docker ps

CONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS                    PORTS                NAMES
8baa0e2cff47        datadog/docker-dd-agent:latest   "/entrypoint.sh supe…"   31 hours ago        Up 31 hours (unhealthy)   8125/udp, 8126/tcp   ecs-dd-agent-task-1-dd-agent-f6d3d5eb9febcab9c601

ある日、ECS で起動させている Datadog Agent コンテナが unhealthy になってしまう事象が発生しました。 その原因と対応法をまとめました。

結論

Datadog Agent イメージを現時点の最新バージョン 6 系にすることで解決できました。

Datadog サポートに問い合わせた所、 今回のケースでは Datadog Agent イメージのバージョンが 5 系だったことに起因していました。

datadog/docker-dd-agent:latest は 5系の最新だった!

バージョン5が最新だった時には設定手続きは以下に沿って実施していました。 https://docs.datadoghq.com/integrations/faq/agent-5-amazon-ecs/

上記手順にて登場する datadog agent の ECS での起動用タスクが以下になります。 ここで指定しているイメージ (datadog/docker-dd-agent:latest) が 5系でした。 https://docs.datadoghq.com/json/dd-agent-ecs.json

datadog/docker-dd-agent:latest は 5系の最新だった!

datadog/agent:latest が 2019.01.10 時点最新の 6系 !

現最新バージョン 6系を扱うには以下設定手続きを参照します。 https://docs.datadoghq.com/integrations/amazon_ecs

手続きで変更点はタスク定義の変更くらいです。 https://docs.datadoghq.com/json/datadog-agent-ecs.json

今の所、datadog/agent:latest が6系の最新になっています。 7系になった際には是非とも互換維持してほしいです。

おまけ

サポートへの問い合わせ

サポートに問い合わせると、 caseID という問い合わせの ID をいただけます。 その後、caseID を設定し、起動時のログファイル (tar.gz) を取得し、サポート宛に添付しました。

ECS の管理下にある EC2 に ssh ログインし以下実行します。

$ docker run --rm -v /tmp:/tmp -e API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx datadog/docker-dd-agent:latest /etc/init.d/datadog-agent flare <caseID>

2019-01-03 12:27:44,472 | ERROR | dd.collector | utils.dockerutil(dockerutil.py:148) | Failed to initialize the docker client. Docker-related features will fail. Will retry 0 time(s). Error: Error while fetching server API version: ('Connection aborted.', error(2, 'No such file or directory'))
...
2019-01-03 12:27:45,807 | INFO | dd.collector | utils.flare(flare.py:161) | Saving all files to /tmp/datadog-agent-2019-01-03-12-27-44.tar.bz2
/tmp/datadog-agent-2019-01-03-12-27-44.tar.bz2 is going to be uploaded to Datadog.
...

EC2 ホスト上に /tmp/datadog-agent-2019-01-03-12-27-44.tar.bz2 ファイルが取得できるので、それをサポート宛にメール添付しました。

上記でログも含めサポートに連絡した所、API バージョンにより接続中止されている、という指摘を受け、バージョン上げて!という話になりました。

2019-01-03 12:27:44,472 | ERROR | dd.collector | utils.dockerutil(dockerutil.py:148) | Failed to initialize the docker client. Docker-related features will fail. Will retry 0 time(s). Error: Error while fetching server API version: ('Connection aborted.', error(2, 'No such file or directory'))

サポートさんありがとう♪ f:id:kenzo0107:20190110112453p:plain

以上です。 参考になれば幸いです。

ECS EC2 上で起動する Datadog Agent コンテナが unhealthy になる時の処方箋

f:id:kenzo0107:20190110112818p:plain

概要

$ docker ps

CONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS                    PORTS                NAMES
8baa0e2cff47        datadog/docker-dd-agent:latest   "/entrypoint.sh supe…"   31 hours ago        Up 31 hours (unhealthy)   8125/udp, 8126/tcp   ecs-dd-agent-task-1-dd-agent-f6d3d5eb9febcab9c601

ある日、ECS で起動させている Datadog Agent コンテナが unhealthy になってしまう事象が発生しました。 その原因と対応法をまとめました。

結論

Datadog Agent イメージを現時点の最新バージョン 6 系にすることで解決できました。

Datadog サポートに問い合わせた所、 今回のケースでは Datadog Agent イメージのバージョンが 5 系だったことに起因していました。

datadog/docker-dd-agent:latest は 5系の最新だった!

バージョン5が最新だった時には設定手続きは以下に沿って実施していました。 https://docs.datadoghq.com/integrations/faq/agent-5-amazon-ecs/

上記手順にて登場する datadog agent の ECS での起動用タスクが以下になります。 ここで指定しているイメージ (datadog/docker-dd-agent:latest) が 5系でした。 https://docs.datadoghq.com/json/dd-agent-ecs.json

datadog/docker-dd-agent:latest は 5系の最新だった!

datadog/agent:latest が 2019.01.10 時点最新の 6系 !

現最新バージョン 6系を扱うには以下設定手続きを参照します。 https://docs.datadoghq.com/integrations/amazon_ecs

手続きで変更点はタスク定義の変更くらいです。 https://docs.datadoghq.com/json/datadog-agent-ecs.json

今の所、datadog/agent:latest が6系の最新になっています。 7系になった際には是非とも互換維持してほしいです。

おまけ

サポートへの問い合わせ

サポートに問い合わせると、 caseID という問い合わせの ID をいただけます。 その後、caseID を設定し、起動時のログファイル (tar.gz) を取得し、サポート宛に添付しました。

ECS の管理下にある EC2 に ssh ログインし以下実行します。

$ docker run --rm -v /tmp:/tmp -e API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx datadog/docker-dd-agent:latest /etc/init.d/datadog-agent flare <caseID>

2019-01-03 12:27:44,472 | ERROR | dd.collector | utils.dockerutil(dockerutil.py:148) | Failed to initialize the docker client. Docker-related features will fail. Will retry 0 time(s). Error: Error while fetching server API version: ('Connection aborted.', error(2, 'No such file or directory'))
...
2019-01-03 12:27:45,807 | INFO | dd.collector | utils.flare(flare.py:161) | Saving all files to /tmp/datadog-agent-2019-01-03-12-27-44.tar.bz2
/tmp/datadog-agent-2019-01-03-12-27-44.tar.bz2 is going to be uploaded to Datadog.
...

EC2 ホスト上に /tmp/datadog-agent-2019-01-03-12-27-44.tar.bz2 ファイルが取得できるので、それをサポート宛にメール添付しました。

上記でログも含めサポートに連絡した所、API バージョンにより接続中止されている、という指摘を受け、バージョン上げて!という話になりました。

2019-01-03 12:27:44,472 | ERROR | dd.collector | utils.dockerutil(dockerutil.py:148) | Failed to initialize the docker client. Docker-related features will fail. Will retry 0 time(s). Error: Error while fetching server API version: ('Connection aborted.', error(2, 'No such file or directory'))

サポートさんありがとう♪ f:id:kenzo0107:20190110112453p:plain

以上です。 参考になれば幸いです。

boto3 の AssumeRole をしたアカウントスイッチ credentials 利用時の MFA 突破対応

f:id:kenzo0107:20181206121637p:plain

概要

備忘録です。

AssumeRole でのアカウントスイッチで credentials 情報を持っている場合に対応した boto3.Session での認証の仕方です。

MFA 設定してる場合も付けときました。

実装

# MFA 入力待ち
mfa_TOTP = raw_input("Enter the MFA code: ")

# sts クライアント
client=boto3.client( 'sts' )

# 認証
response = client.assume_role(
    RoleArn='arn:aws:iam::123456789:role/admin_full',
    RoleSessionName='mysession',
    DurationSeconds=3600,
    SerialNumber='arn:aws:iam::987654321:mfa/myaccount',
    TokenCode=mfa_TOTP,
)

# 認証情報
credentials = response['Credentials']

# session に 認証情報付加
session = boto3.Session(profile_name=session_name, 
    aws_access_key_id = credentials['AccessKeyId'],
    aws_secret_access_key = credentials['SecretAccessKey'],
    aws_session_token = credentials['SessionToken'],
)

ec2Client = session.client('ec2', region_name='ap-north-east1')
resources = ec2.describe_instances()

boto3.Session に sts で AssumeRole で得た credentials 情報を渡してます。

以上です。

No space left on device が発生して i-node 枯渇してた時の原因調査法

f:id:kenzo0107:20181015001102j:plain

Linux Server で No space left on device が発生した時の対処まとめです。

とりあえず df -h してみる

df -h しても 最大で 77% no space left on device が発生することでもなさそう

$ df -h 

Filesystem      Size  Used Avail Use% Mounted on
udev            1.9G     0  1.9G   0% /dev
tmpfs           385M   40M  346M  11% /run
/dev/nvme0n1p1   15G   11G  3.3G  77% /
tmpfs           1.9G     0  1.9G   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           1.9G     0  1.9G   0% /sys/fs/cgroup
tmpfs           385M     0  385M   0% /run/user/1022
tmpfs           385M     0  385M   0% /run/user/1128
tmpfs           385M     0  385M   0% /run/user/1098
tmpfs           385M     0  385M   0% /run/user/6096

-h = --human-readable 読みやすいサイズ表示をしてます。

df -i してみる

df -i で i-node 情報表示。最大 95%
これでした。

$ df -i

Filesystem     Inodes  IUsed  IFree IUse% Mounted on
udev           490419    351 490068    1% /dev
tmpfs          492742    521 492221    1% /run
/dev/nvme0n1p1 983040 927212  55828   95% /
tmpfs          492742      1 492741    1% /dev/shm
tmpfs          492742      3 492739    1% /run/lock
tmpfs          492742     16 492726    1% /sys/fs/cgroup
tmpfs          492742      4 492738    1% /run/user/1022
tmpfs          492742      4 492738    1% /run/user/1128
tmpfs          492742      4 492738    1% /run/user/1098
tmpfs          492742      4 492738    1% /run/user/1142

i-node とは?と思ったら、 「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典 i-node編 辺りを見てみてください。

簡単に言うと、ファイルの属性情報を管理しているデータです。

要は、ファイル数が増えると、ファイルを管理するデータが増え、 i-node はどんどん増えていきます。

その調査法をまとめました。

どのディレクトリのファイル数が多いか調査

以下は「現ディレクトリでのファイル数多い順ランキング」です。

sudo find . -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -r

※ find の -xdev オプションはマウント先のファイルシステムを検索しない様にしてます。-type f はファイルのみ検索。

このワンライナーで原因となるファイル数の多いディレクトリを探索します。

当たりが付いている場合はそのディレクトリで実行

例えば、ユーザ毎にディレクトリが用意されている場合等に、個々人が home directory で git clone してるとか、
個々人が bundle install してて vendor ディレクトリ以下がファイル数が激増してたとか。

そういった事象があり得そうなら、 /home/ ディレクトリ以下でワンライナー実行して原因調査をするのが良いです。

各ユーザ毎が原因なら相談して消して良いかも確認できるし!

一番手っ取り早いのは、root path 「/」 で実行

どのディレクトリのファイル数が多いのかを探るのなら、一番上位階層の「/」(root) から実行した方が特定しやすいです。

但し、root から全てのディレクトリ内のファイルを検索するとなると非常に cpu を食います。
実行してしばらくレスポンスが返ってこなくてドキドキします。

top コマンド等で cpu 状況を監視しつつ、実行することをオススメします。

本番環境の web サーバで直ちにユーザ影響が出そうな場合は、LBから一旦外して、とか、ユーザアクセスの少ない時間に実行する様に影響範囲を最小限にしたい所。

状況見た上で進めましょう。

実際にあった i-node 枯渇原因

/usr ディレクトリ以下に linux-headers-*** ファイルが溜まっており、30% 近く食ってました。

以下記事に救われました。ありがとうございます。 古いカーネルの削除方法メモ

AWS EC2 t2 から t3 へ移行する為の step by step

f:id:kenzo0107:20180914130511j:plain

概要

AWS EC2 に t3 系インタスタンスが登場した為、サクッとできるかと思いきや、つまづいた箇所をまとめました。

今回対象のインスタンスは HVM で ubuntu 16.04.5 LTS を使用しました。

t2 と比べて t3 は何がいいの?

t2 から t3 へ移行する大まかな流れ

要は、ena モジュールをインストールし、EC2 ENA サポートを有効化する必要がありました。

  1. t2 インスタンス停止
  2. AMI 作成
  3. t2 インスタンス起動
  4. t2 インスタンスカーネルモジュール(ena) のインストール
  5. ena モジュールインストール確認
  6. t2 インスタンス停止
  7. インスタンスタイプを t3 へ変更 (credit: unlimited もしたい場合はここで)
  8. t3 インスタンス起動

ENA って?

Elastic Network Adapter – Amazon EC2 向けの高性能パフォーマンスネットワークインターフェイス

プロセッサのワークロードを軽くし、ネットワークパケットと生成または処理を行う vCPU 間で短く効率的なパスを作成するために構築されています。

Linux インスタンスにおける Elastic Network Adapter (ENA) を使用した拡張ネットワーキングの有効化 には以下のように記載があります。

Amazon EC2 は、Elastic Network Adapter (ENA) を介して C5, C5d, F1, G3, H1, I3, m4.16xlarge, M5, M5d, P2, P3, R4, R5, R5d, X1, X1e, and z1d インスタンスに拡張されたネットワーキング機能を提供します。

拡張ネットワーキングは、Amazon EC2 コンソールから管理することはできません。

HVM インスタンスでのみサポート

まとめると、

  • Amazon EC2 向けの高性能パフォーマンスネットワークインターフェイス
  • HVM (Hardware-assited VM:完全仮想化) 環境でサポートされている。
  • PV (ParaVirtual:準仮想化) 環境ではサポートされない。
  • ENA というカーネルモジュールを介す事で、インスタンスに拡張されたネットワーキング機能が利用できる。

pv/hvm は AWS コンソール>EC2 説明の「仮想化」の項目で確認できます。
pv の場合は、 hvm の移行を検討する必要があります。

f:id:kenzo0107:20180914130817p:plain

以下から設定に進みます。

ENA 有効化設定手順

以下前提とします。

  • AMI を取る等のバックアップが済んでいる。
  • t2.small から t3.small に移行する。

Ubuntu での拡張ネットワーキングの有効化

ubuntu:~$ sudo apt-get update && sudo apt-get upgrade -y linux-aws

他OSの対応法も先ほどの Linux インスタンスにおける Elastic Network Adapter (ENA) を使用した拡張ネットワーキングの有効化 に記載されています。

W: mdadm: /etc/mdadm/mdadm.conf defines no arrays. エラーが発生した場合

/etc/mdadm/mdadm.conf ファイルに以下一文を追記します。

ARRAY <ignore> devices=<ルートデバイス>

自分の場合は以下の一文を一番下に追記して、もう一度 コマンド実行したら通りました。

ARRAY <ignore> devices=/dev/sda1

ena カーネルモジュールに関する情報表示

modinfo ena を実行し以下のように表示されれば OK です。

ubuntu:~$ modinfo ena

filename:       /lib/modules/4.4.0-81-generic/kernel/drivers/net/ethernet/amazon/ena/ena.ko
version:        1.1.2
license:        GPL
description:    Elastic Network Adapter (ENA)
author:         Amazon.com, Inc. or its affiliates
...

EC2 ENA サポート有効化

// インスタンス停止
macOS%$ aws ec2 stop-instances --instance-ids <instance id>

// ENA サポート設定
macOS%$ aws ec2 modify-instance-attribute --instance-id <instance id> --ena-support true

// EBS 最適化 (任意)
macOS%$ aws ec2 modify-instance-attribute --instance-id <instance id> --ebs-optimized

// credit unlimited 設定 (任意)
macOS%$ aws ec2 modify-instance-credit-specification --instance-credit-specification "InstanceId=i-<instance id>,CpuCredits=unlimited"

// インスタンスタイプ変更
macOS%$ aws ec2 modify-instance-attribute --instance-id <instance id> --instance-type t3.small

// インスタンス起動
macOS%$ aws ec2 start-instances --instance-ids <instance id>

これで t3 デビューを飾ることができました♪

参照

Amazon Web Servicesではじめる新米プログラマのためのクラウド超入門 (CodeZine BOOKS)

Amazon Web Servicesではじめる新米プログラマのためのクラウド超入門 (CodeZine BOOKS)

*1:本稿執筆時 2018-09-14

S3 に5分毎に出力される AWS LB ログファイルを時間帯を指定してまとめてダウンロード

概要

AWS で LB のログを S3 に保存設定をしている場合に、 インシデントがあった時間帯のログがまとめて欲しいという時に awscli でまとめてログ取得しています。

その時の手順を備忘録としてまとめました。

事前準備

  • awscli インストール

本件の実行環境は以下になります。

macOS%$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.12.6
BuildVersion:   16G1036

macOS%$ aws --version
aws-cli/1.15.50 Python/3.7.0 Darwin/16.7.0 botocore/1.10.49

ログファイルダウンロード

例) 2018年9月12日 14時台の ALB ログファイルをダウンロード

// 2018年9月12日 14時台のログファイルをダウンロード
macOS%$ aws s3 --profile <profile> cp s3://<log bucket name>/<lb name>/AWSLogs/123456789012/elasticloadbalancing/ap-northeast-1/2018/09/12/ . --recursive --exclude "*" --include "*20180912T05*

// ログファイル解凍
gunzip *.gz

// log を1ファイルにまとめ
cat *.log > all.log

// HTTP コードが 50x のものを 50x.log にまとめる
awk '{if($9 ~ 50) print $13,$14,$15}' all.log > 50x.log

--profile <profile>aws configure --profile <profile> で設定した場合の設定です。
default を利用する場合は --profile <profile> の指定は不要です。

以上です。

プロセスの起動経過時間・CPU使用時間

備忘録です。

プロセスがいつ頃から起動しているものか、全然再起動してないと再起動するのもやや不安になるので
一旦確認しておこう、という気持ちから以下コマンドを使っています。

$ ps -eo pid,comm,etime,time  | grep node
  591 node            51-20:47:21 00:01:54
 2255 node            23-18:07:58 00:01:18
OPTION Explain
pid プロセス ID
comm コマンド
etime プロセス開始からの経過時間
time CPU使用時間

もちろん CPU の使用頻度等も把握できるので何かと便利♪

PS(ホスファチジルセリン) 30日分

PS(ホスファチジルセリン) 30日分