Medley Developer Blog

株式会社メドレーのエンジニア・デザイナーによるブログです

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でアクセスする事を目指します。

f:id:medley_inc:20200918142724p:plain

対応

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

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

f:id:medley_inc:20200918142745p:plain

この変更作業は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ロール→「必要な権限を備えたシステムのデフォルトコマンド実行ロールを作成」により作成してください。

f:id:medley_inc:20200918142823p:plain

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

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

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

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

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

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

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

f:id:medley_inc:20200918142901p:plain

接続確認

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

f:id:medley_inc:20200918142910p:plain

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

運用してみての感想

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

注意点

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

料金

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

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

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

SessionManagerでの操作について

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

さいごに

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

www.medley.jp