株式会社メドレーDeveloper Portal

2020-09-18

Fargate 上で動くコンテナアプリケーションに SessionManager で接続する

自己紹介

株式会社メドレーのエンジニア阪本です。

9 月に入っても暑い日が続く中、皆さんはいかがお過ごしでしょうか。

前回のブログでも書きましたが私は野球観戦(虎党)が趣味で、毎日の試合結果に一喜一憂しています。 このブログの執筆時点ではセ・リーグは首位巨人にマジックが点灯し、残試合 50 を切った状況でのゲーム差 10。優勝を目指す阪神にとっては厳しい状況となりましたが、残り直接対決をすべて勝てば可能性は見えてくるはず。ここは諦めずに応援しようと思います。

次の記事を書く頃には何らかの決着が着いていると思いますので、その時には喜びのメッセージが書ける事を願っています。

はじめに

突然ですが、皆さんはFargateを使いこなしていますか? 今まで ECS(EC2)での運用がメインでしたが、ジョブメドレーのシステムでも Fargate に触れる機会が増えてきました。 筆者自身は初めての Fargate でしたが、EC2 の存在が無くなることに不思議な感覚を覚えつつも、管理するものが減って運用が楽になったと実感しています。

しかし、EC2 が無くなった事によりサーバ内にターミナルで入る手段を失いました。 公式のガイドでは

質問2:コンテナの中に ssh や docker exec で入ることは出来ますか?

こちら現状サポートしておりませんが、コンテナワークロードでは「同一の環境でしっかりテストを行う」ことや「ログを外部に全て出す」ことがベストプラクティスとされていて、コンテナに入る必要性を出来る限り減らす方が将来的にも好ましいです。

と「事前にテストを十分に実施する」「ログは(S3 や CloudWatchLogs など)外部に出力する」 さえ出来ていれば入る必要が無いはずと記載されているものの・・・心配性な自分は不測の事態が発生した時の事を考えてサーバに入る手段を求めてしまいます。

そこで代替手段を模索していた所、SessionManagerを使えば可能との文献を見つけました。 すでに SessionManager 自体は EC2 に対して運用を行っていたため導入の敷居は低いと考え、この手段を採用することにしました。

Session Manager とは?

Session Manager とは AWS の Systems Manager サービスの 1 機能で、AWS 上で管理しているサーバ(マネージドインスタンス)に対してターミナルのアクセスを可能にするものです。

ターミナルへのアクセス手段は、よくある手段だと SSH がありますが この方法は SSH ポートを外部に開放する必要があるため攻撃の対象になりやすく、あまり好ましくありません。

それに比べて Session Manager は SSH ポートの開放は不要でサーバから見てアウトバウンド方向の HTTPS 通信の確保で済む為、外部からの攻撃も受けず安全にアクセス経路の確保が実現できます。 ※通信経路の確保以外にも IAM ロールの設定などが必要となります。詳しくはこちらを参考

「AWS 上で管理しているサーバ」と先に記載しましたが、このサーバは EC2 インスタンスに限らないのが本記事の重要なポイントになります。 オンプレミスなサーバも AWS 上で管理されているのであれば、SessionManager エージェントをインストールする事により管理対象に含めることが可能になるのです。

今回は EC2 で動いていた SessionManager エージェントを Fargate で動くコンテナにインストールする事によりコンテナ自体をサーバと見立ててマネージドインスタンスとし、SessionManager でアクセスする事を目指します。

20200918142724.png

対応

Systems Manager インスタンス枠をスタンダードからアドバンスドに変更する / AWS コンソールでの設定

オンプレミスなサーバに SessionManager にてアクセスする場合、Systems Manager のオンプレミスインスタンスティアをスタンダードからアドバンスドへと変更する必要があります。

20200918142745.png

この変更作業は AWS コンソールから行う事になりますが、アドバンスドへの変更に当たって既存のマネージドインスタンスに影響することはありません。 ただし、この逆の場合、スタンダードに戻す際には考慮が必要となるのでこちらを参照ください。

SSM Agent のインストール / コンテナに対する設定

ここからは実際に動くコンテナに対する設定になります。 AWS のドキュメント手動でインストール SSM エージェント EC2 で Linux のインスタンスを参考に、OS に合った方法で SessionManager エージェントのインストールを行います。

インストール作業には通信などの時間が必要となるので、事前にコンテナイメージにインストールする形としました。

コンテナをマネージドインスタンスとして登録する / コンテナに対する設定

コンテナをマネージドインスタンスとして登録するため、コンテナのスタートアップ(Entrypoint)にて下記スクリプトを実行します。

# 1. ハイブリッドアクティベーションの作成
SSM_ACTIVATE_INFO=`aws ssm create-activation --iam-role service-role/AmazonEC2RunCommandRoleForManagedInstances --registration-limit 1 --region ap-northeast-1 --default-instance-name medley-blog-fargate-container`

# 2. アウトプットからアクティベーションコード/ID の抽出
SSM_ACTIVATE_CODE=`echo $SSM_ACTIVATE_INFO | jq -r '.ActivationCode'`
SSM_ACTIVATE_ID=`echo $SSM_ACTIVATE_INFO | jq -r '.ActivationId'`

# 3. コンテナ自身をマネージドインスタンスへの登録
amazon-ssm-agent -register -code $SSM_ACTIVATE_CODE -id $SSM_ACTIVATE_ID -region "ap-northeast-1"

# 4. SessionManager エージェントの起動
amazon-ssm-agent &

これらのコマンドについては各行ごとに説明します

1.ハイブリッドアクティベーションの作成

マネージドインスタンス登録に必要なアクティベーションコード/ID 取得のため、ハイブリッドアクティベーションの登録を行います。 後々 AWS コンソールにてインスタンスの識別ができるように、--default-instance-nameオプションにてmedley-blog-fargate-containerという名前を付与しています。

このコマンドのアウトプットにて下記のような JSON が返される為、一旦変数に格納しています。

{ "ActivationId": "<<アクティベーション ID>>", "ActivationCode": "<<アクティベーションコード>>" }

また--iam-roleオプションでサービスロール AmazonEC2RunCommandRoleForManagedInstances を使っています。 このロールがまだ存在しない場合、AWS コンソールからハイブリッドアクティベーションから IAM ロール →「必要な権限を備えたシステムのデフォルトコマンド実行ロールを作成」により作成してください。

20200918142823.png

2. アウトプットからアクティベーションコード/ID の抽出

前項のアウトプットからアクティベーションコード/ID を個々の変数に分離しています。

3. コンテナ自身をマネージドインスタンスへの登録

取得したアクティベーションコード/ID を利用し、コンテナ自身をマネージドインスタンスとして登録します。 環境変数AWS_DEFAULT_REGIONのように AWS の Credential にてデフォルトの Region 設定があった場合でも、このコマンドではオプションで Region 指定が必須となるのでご注意ください。

4. SessionManager エージェントの起動

最後に SessionManager エージェントを起動します。 これにより AWS との通信が確立され、SessionManager が利用できるようになります。

この状態でマネージドインスタンス画面にて目的のインスタンスが「オンライン」であれば設定が完了です。

20200918142901.png

接続確認

設定が完了したので、実際に SessionManager にて接続してみます。 AWS コンソールのセッションマネージャからセッションの開始を選択し、名前が事前に登録したmedley-blog-fargate-containerであるものを選択します。 外見は他の EC2 と変わらない表示ですが、この手段で登録したものはインスタンス ID がmiから始まる ID になります(通常の EC2 はiから始まる ID)。

20200918142910.png

後は普段通りにセッションを開始するとコンテナ内へのアクセスが開始されます。 これで EC2 の無い Fargate 上のコンテナに対してもターミナルに入ることができました。

運用してみての感想

Fargate 上のコンテナに直接入ることにより、今まで出来なかった topコマンドによるプロセス状態の確認 dfコマンドによる Disk 容量の確認 などの環境調査が出来るようになりました。 利用頻度が多い訳ではありませんが、調査の選択肢を増やす事により有事の際の早期対応に繋げれられていると感じています。

注意点

ここからは運用に当たっての注意点について数点紹介します。

料金

EC2 での SessionManager と違い、この方法で登録したサーバへの SessionManager 通信は料金が発生します。 正確には 「SessionManager エージェントが起動し AWS と通信が確立している状態」 での時間課金で SessionManager での接続有無は問いません。 よって、常時必要ではない場合は SessionManager エージェントを止めて節約する方法を検討してください。

アクティベーションやマネージドインスタンスがリストに残る

コンテナ終了時でも AWS コンソールのハイブリッドアクティベーション一覧やマネージドインスタンス一覧に表示が残ってしまうようです。 一覧の上限の記載は見つからなかったものの、無限に増えるとも思えないので適時 Lambda を使って削除しています。

SessionManager での操作について

EC2 インスタンスに対しての SessionManager と同様ですが、セッション開始直後のユーザは ssm-user 固定になるようです。 特定ユーザでの操作が必要となる場合、suコマンドでのユーザ切り替えが必要になります。

さいごに

今回のようにメドレーでは新たな技術を取り入れつつ、サービスの安定を目的とした様々な施策を導入しています。 こういった働き方に興味を持たれた方、まずは下記リンクからお気軽にお話しませんか?

https://www.medley.jp/jobs/

株式会社メドレーDeveloper Portal

© Medley Developer Portal