Gracefull EC2 shutdown within EKS

AWS 謹製のツール

以下2つのモードが用意されている
- IMDS Processor Mode
- Queue Processor Mode
モードによって検知できるイベントの種類が異なり Queue Processor Mode のほうが多い(というより上位互換)

IMDS Processor Mode は制限されたモードで、名前の通り metadata endpoint を監視する。なので metadata endpoint から検知できないイベントに対しては有意なハンドリングができない。
終了検知として主に利用しているのは以下エンドポイントで、概ねカバーできているように見える。しかし実際には ASG 起因のインスタンス終了に適切に対応できないと思われる。
- スポットインスタンス中断通知: /latest/meta-data/spot/instance-action
- メンテナンス通知: /latest/meta-data/events/maintenance/scheduled
- インスタンスリバランス推奨: /latest/meta-data/events/recommendations/rebalance
- ASG のターゲットライフサイクル状態: latest/meta-data/autoscaling/target-lifecycle-state
latest/meta-data/autoscaling/target-lifecycle-state はノードが終了する前に ASG がインスタンスメタデータを Terminated に書き換える。このため、NTH(aws-node-termination-handler)は ASG ライフサイクルフックのハートビート・タイムアウトを変更する等して、終了までの充分な猶予時間を確保できない可能性がある。
ASG will update instance metadata to be Terminated before it terminates the node
ライフサイクルフックの概要図

NTH がイベントを検知する実装を見ていく

IMDS Mode の場合はここで Monitor を設定してる

わかりやすそうな ScheduledEventMonitor を見てみる
/latest/meta-data/events/maintenance/scheduled
にリクエストを送って(IMDS Mode の場合は Daemonset なので localhost に送れば良い)。
こんな感じのデータが取れるらしい
[
{
"NotBefore" : "21 Jan 2019 09:00:43 GMT",
"Code" : "system-reboot",
"Description" : "scheduled reboot",
"EventId" : "instance-event-0d59937288b749b32",
"NotAfter" : "21 Jan 2019 09:17:23 GMT",
"State" : "active"
}
]

取得したデータを検査して必要に応じて InterruptionEvent に追加する
例えば再起動が必要な Event かを検査してる

以上がイベント検知の一例。ここからは検知した時にどうハンドリングしてるかを見ていく

検知したイベントのハンドリングはここでやってる

handler は2種類設定されている

Queue Processor Mode のイベント検知はここに集約されてるっぽい

IMDS Processor Mode との顕著な違いは Monitor() で ASG レベルのハンドリングまで実行してる。例えば ASG のライフサイクルが autoscaling:EC2_INSTANCE_TERMINATING
に遷移したのを以下で検知し
一定時間ハードビートが送信し続け、送信が終わるまでインスタンス終了を遅延させる(デフォルトだと 172800s = 48h)

karpenter はどうやっているのか?