【小ネタ】ECS(EC2)を利用する時にクラスターへ参加出来ない時の対処

こんにちわ、札幌のヨシエです。

別記事で遭遇したECS対応でEC2インスタンスがECSクラスターへ参加出来ない事象に遭遇しましたので対応メモを共有させて頂きます。

runc脆弱性でEC2、ECS(EC2/Fargate)の対応をやってみる

当初の目的

上記で書いたようにDocker脆弱性対応でEC2インスタンスをコンテナホストとして利用している環境の検証を目的としておりました。
そこでなるべくダウンタイムを抑えたい気持ちから一時的に脆弱性対応済みAMIでコンテナホストを起動し、クラスターに参加させることでコンテナを別ホストで起動することを動きました。

遭遇事象

最新のECS Optimized-AMIを利用し、一時的に/etc/ecs/ecs.configへクラスター名を記載した後にEC2インスタンスを再起動したもののECSクラスターへホストインスタンスが追加されませんでした。

Step1:事象確認

ECSではホストインスタンスの/var/log/ecsディレクトリ以下にecs-agentの挙動ログが出力されます。
このログにはecs-agentの起動状態やコンテナイメージのPull、コンテナの起動状態等が細かくロギングされます。

[ec2-user@ip-xx-xx-xx-xx ~]# ls /var/log/ecs
ecs-agent.log.yyyy-mm-dd-hh  ecs-init.log

このログファイルはかなり有用で、初期処理から一貫してログが見えるのですが以下のようなログが出力され続けました。

yyyy-mm-ddThh:mm:ssZ [WARN] Unable to fetch user data: NotFoundError: user-data not found
caused by: EC2MetadataError: failed to make EC2Metadata request
caused by: <?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>404 - Not Found</title>
 </head>
 <body>
  <h1>404 - Not Found</h1>
 </body>
</html>

yyyy-mm-ddThh:mm:ssZ [INFO] Amazon ECS agent Version: 1.25.2, Commit: 0821fbc7
yyyy-mm-ddThh:mm:ssZ [INFO] Creating root ecs cgroup: /ecs
yyyy-mm-ddThh:mm:ssZ [INFO] Creating cgroup /ecs
yyyy-mm-ddThh:mm:ssZ [INFO] Loading state! module="statemanager"
yyyy-mm-ddThh:mm:ssZ [INFO] Event stream ContainerChange start listening...
yyyy-mm-ddThh:mm:ssZ [CRITICAL] Data mismatch; saved cluster 'default' does not match configured cluster 'Test-container-Cluster'. Perhaps you want to delete the configured checkpoint file?

Step2:事象発生原因を確認

今回は[CRITICAL] Data mismatch; saved cluster 'default' does not match configured clusterから読み取れるように何らかの状態保持目的としてファイルが存在しており、ECSの設定ファイル内容と一致してないことから発生した事象と読み取れました。

結果としてecs.configの指定を確認しましたが特に問題と思われる箇所は見当たりませんでした。

Step3:動作ソフトウェアのコミュニティを確認

今回はecs-agentの挙動として、GitHubを確認しました。
aws/amazon-ecs-agent

この中のIssuesから以下のような内容がありました。
How do register existing agent to a different cluster? #139

https://github.com/aws/amazon-ecs-agent/issues/139#issuecomment-123061463

Once it has joined a cluster, you can cause it to join a new cluster by stopping it, deleting its checkpoint file (located at /var/lib/ecs/data/* by default), and launching it again with the new configuration. It's important to note that all tasks currently managed by it should be stopped prior to doing this as the Agent will be unable to track past tasks.

ここで/var/lib/ecs/data配下にStep2であたりとしてついていた状態保持ファイルがありそうな推測が立てられました。
そこで対象ディレクトリを参照するとECSを利用する上で必要と考えられるecs_agent_data.jsonなるファイルがありました。

Step4:事象改善対応

上記のコメントで記載があるように対象JSONファイルはECSAgentが初回起動時に作成されるものと考えましたので対象のJSONを削除しました。
ここからインスタンスを再起動することでJSONファイルが再作成され、ECSクラスターへ参加出来たことを確認できました。

最後に

とても基礎的なことを記載して恐縮ですが、ECSでEC2インスタンスを使用する時に行ったトラブルシュートの一例を書きました。
ステップ分けしましたが、何が問題なのか?何が起きてるのか?同事象はあるのか?というところを守ることですぐに対応が出来ました。

最後に書くべきではないかもしれませんが、EC2インスタンスでコンテナを動かす際には様々なログが出力されることが予想されますので
各ログファイルはCloudwatchLogs等のログ出力基盤に吐き出してからログローテート設定はきちんと対応しましょう。