オンプレ感覚! AWS EC2でNMI割り込みでdump取っちゃおう!!!

# はじめに
某ベンダで、クラウドの人材育成企画と研修トレーニングのデリバリを担当しています。
研修準備のためオンプレとクラウドの運用差分を整理していたのですが、「あれ、クラウドで仮想OSのdumpってオンプレみたいに取れるのかな？」が気になりちょっと調べてみました。
結論から言うと、オンプレみたいに取れちゃいます。

実は、10数年前までLinuxエンジニアやってました。オンプレでは当たり前のようにOSのdumpを取って障害分析してました。クラウド的にな使い方だと、リソースは使い捨い捨てが当たり前なのですが、エンタープライズ用途の需要がまだあるんじゃないかと思ってます。例えば、性能遅延時の原因調査とか、アプリケーション実行時のメモリ不足の原因調査とか。

# 前提環境
Amazon Linux 2で試してみます。
恐らくRedhat系のディストリビューションだと手順は同じと思います。
今回利用するAMIはx86を利用します。

>[AMI]
Amazon Linux 2 AMI (HVM),
SSD Volume Type ami-06202e06492f46177 (64-bit x86)

>[Instance Type]
c5.large

Amazon Linux 2のAMIは、オンプレの仮想環境でも動かすことはできます。ソースコードはGPLなので、どこにあるんだろう、、、と探してたら、yumレポジトリにsourceのリポジトリがありました。

インスタンスタイプはc5を利用しました。dump取得の検証にNMI(non-maskable interrupt)割り込みを使いたいのですが、仮想化機構（AWS Nitro）の制限で利用できるインスタンスタイプが制限されるみたいです。

>診断割り込みは、AWS Nitro システムで稼働している、A1 (ARM ベース) を除くすべての EC2 >インスタンスに送信できます。本記事の執筆時点では、C5、C5d、C5n、i3.metal、I3en、M5、>M5a、M5ad、M5d、p3dn.24xlarge、R5、R5a、R5ad、R5d、T3、T3a、Z1d が該当します。
https://aws.amazon.com/jp/blogs/news/new-trigger-a-kernel-panic-to-diagnose-unresponsive-ec2-instances/

では環境を構築します。以下の作業は`rootユーザ権限`で設定します。

## 1. パッケージのインストール
yumレポジトリを変更し、`amzn2-core-debuginfo`を有効化します。
`enabled=1`に設定します。

```
# vi /etc/yum.repos.d/amzn2-core.repo
〜省略〜
[amzn2-core-debuginfo]
name=Amazon Linux 2 core repository - debuginfo packages
mirrorlist=$awsproto://$amazonlinux.$awsregion.$awsdomain/$releasever/$product/$target/debuginfo/$basearch/mirror.list
priority=10
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-amazon-linux-2
enabled=1
metadata_expire=300
mirrorlist_expire=300
report_instanceid=yes
〜省略〜
```

`kexec-tools crash kernel-debuginfo`を追加します。

```
#  yum install kexec-tools crash kernel-debuginfo
```
## 2. kdumpの設定
`/etc/default/grub`を編集し、`crashkernel=256M`を追記します。

```
# vi /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="crashkernel=256M console=tty0 console=ttyS0,115200n8 net.ifnames=0 biosdevname=0 nvme_core.io_timeout=4294967295 rd.emergency=poweroff rd.shell=0"
GRUB_TIMEOUT=0
GRUB_DISABLE_RECOVERY="true"
```
編集後にgrubの設定を再構築します。
```
# grub2-mkconfig -o /boot/grub2/grub.cfg
```
NMI割り込みでdumpを取るため、カーネルパラメータを編集します。
`/etc/sysctl.conf`に`kernel.unknown_nmi_panic=1`を追記します。

```
# vi /etc/sysctl.conf
kernel.unknown_nmi_panic=1
```
カーネルパラメータを編集、EC2を再起動します。再起動後にkdumpサービスが稼働していることを確認します。
```
# systemctl status kdump.service
● kdump.service - Crash recovery kernel arming
   Loaded: loaded (/usr/lib/systemd/system/kdump.service; enabled; vendor preset: enabled)
   Active: active (exited) since Tue 2021-03-30 14:42:44 UTC; 4min 5s ago
  Process: 3027 ExecStart=/usr/bin/kdumpctl start (code=exited, status=0/SUCCESS)
 Main PID: 3027 (code=exited, status=0/SUCCESS)
```

## 3. NMI割り込みの実行
さて、ここからAWS CLI経由でAPIを叩いて、NMI割り込みを実行します。CLIオプションの`region`と`instance-id`は環境にあわせて設定してください。

```
# aws ec2 send-diagnostic-interrupt --region xxxxx --instance-id　xxxxxx
```

NMI割り込み十講義に数分間放置するとEC2が再起動します。kdumpが成功していると/var/crashの配下にdumpが取れています。
成功していれば、crashコマンドで確認してみましょう。`PANIC: "Kernel panic - not syncing: NMI: Not continuing"`と表示されるはずです。
```
# pwd 
/var/crash/127.0.0.1-2021-03-30-16:22:11
# crash /usr/lib/debug/lib/modules/4.14.225-169.362.amzn2.x86_64/vmlinux vmcore
〜省略〜
      KERNEL: /usr/lib/debug/lib/modules/4.14.225-169.362.amzn2.x86_64/vmlinux
    DUMPFILE: vmcore  [PARTIAL DUMP]
        CPUS: 2
        DATE: Tue Mar 30 16:22:08 UTC 2021
      UPTIME: 00:05:13
LOAD AVERAGE: 0.02, 0.01, 0.00
       TASKS: 127
    NODENAME: ip-172-31-25-107.ap-southeast-2.compute.internal
     RELEASE: 4.14.225-169.362.amzn2.x86_64
     VERSION: #1 SMP Mon Mar 22 20:14:50 UTC 2021
     MACHINE: x86_64  (3000 Mhz)
      MEMORY: 3.8 GB
       PANIC: "Kernel panic - not syncing: NMI: Not continuing"
         PID: 0
     COMMAND: "swapper/0"
        TASK: ffffffff82013480  (1 of 2)  [THREAD_INFO: ffffffff82013480]
         CPU: 0
       STATE: TASK_RUNNING (PANIC)
```

# おわりに
今回執筆にあたり何度か実機で動作検証したもの、dumpが取れない事象が発生して少々ハマりました。`kdumpのmemサイズを128Mにしてたのが原因ポイ`です。10年前の感覚でメモリサイズを小さくしてたのですが、サイズを大きくしておかないとdumpを取り切る前にリセットが入っているようにみえます。詳細はもうちょっと調べてみる必要がありそうです。

今後、エンタープライズ用途にクラウドの活用範囲が拡大するとオンプレ感覚でdumpを取るニーズも増えそうですね。その際にこの記事がお役に立てると幸いです。

いや〜、10年ぶりのcrashコマンド、、、、当時あれだけ 使いこなしてたのに何も覚えてないのがちょっぴりショック、まだまだ修行です。