3
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AWS FargateでEFSを使う - EC2起動タイプからの移行 (bridge → awsvpc)

Last updated at Posted at 2020-04-10

2020/4/8, ついにFargateでEFSが使えるようになりました!

この記事では、Fargateサポートを待ちつつも無念の『ECS on EC2 + EFS』構成を取っていた環境を移行するまでにハマった落とし穴を紹介していきます。

Fargateに移行してしまえば、こんな悩みは解消されるはず。

  • コンテナインスタンスのパッチ当てどうしよう...
  • 定期的にインスタンス入れ替える?
  • EFS以外のディスクは揮発性でいいのに、EBSの料金とか空き領域監視とかついてくる…
  • デプロイするときにコンテナインスタンスを一時的に増やすの面倒
  • スケールインとかインスタンス入れ替え時に乗ってるタスクが巻き添えにならない?

参考記事

新規でFargateを作成する場合や、全体像を知って動かしてみたい方は以下の記事が参考になります。

ネットワークモードがbridgeだった

ECSのEFSサポートがプレビュー版として使用可能になった2020/1/17から今日までの間、ECSタスク定義のefsVolumeConfigurationを使用したEFSマウントはネットワークモードがawsvpcの場合使用できませんでした。このため、移行前はネットワークモードをbridgeで構成していました。

EFS ファイルシステムのための Amazon ECS プレビューサポートが利用可能に

なお、efsVolumeConfiguration以外にもEFSのマウント方法はいくつかあります。下記の方法の場合はawsvpcモードでも使用可能です。ただ、ECSコンテナインスタンスへの依存ができてしまうためあまりやりたくありませんでした。

起動タイプをFargateに、ネットワークモードをawsvpcに変更

起動タイプをEC2からFargateに変えると、Fargateはネットワークモードawsvpcのみをサポートしているため、必然的にbridgeから変更する必要があります。今回のECSでのEFSサポートの発表の中で、明確にawsvpcをサポートするようになったとの記載はありませんでしたが、問題ないようです。

タスクのコンテナで使用する Docker ネットワーキングモード。Fargate 起動タイプを使用している場合、awsvpc ネットワークモードが必要です。

タスク定義パラメータ - Amazon ECS

セキュリティグループの設定先変更

ECSコンテナインスタンス(EC2)に設定していたセキュリティグループを、ECSサービスのセキュリティグループに変更します。設定内容は環境によりますが、今回は変更なしでそのまま付け替えました。

ECSサービス定義にnetworkConfigurationを追加

networkConfiguration:
  awsvpcConfiguration:
    subnets:
      - subnetid-1
    securityGroups:
      - sg-1

FireLensの環境変数FLUENT_HOST, FLUENT_PORTが挿入されなくなる

これはハマりました。ドキュメントには何も書いていませんが、awsvpcモードの場合これらの環境変数は挿入されないようです。

AWSさん、これはどこかに書いておいてください…。

awsvpcの場合、同一タスク内の通信はlocalhostで可能なため、FireLensのようにサイドカー構成の場合は確かに環境変数で明示する必要はありません。でも、これに思い当たるまで時間がかかりました。bridgeのときはあったんだもの…。

同じタスクに属するコンテナが、localhost インターフェイス経由で通信できるようになります。

タスクネットワーキングと awsvpc ネットワークモード - Amazon ECS

なお、普通にfluentdなどをサイドカーでなく立ち上げていた場合は、サービスディスカバリを考える必要があります。

というわけで、タスク定義にfirelensを動かすコンテナにポートを定義しておきます。

    portMappings:
      - containerPort: 24224
        protocol: tcp

元々、環境変数FLUENT_HOST, FLUENT_PORTを読んでアプリの設定を生成していたので、環境変数を自分で定義しておきます。

     environment:
     - name: FLUENT_HOST
       value: localhost
     - name: FLUENT_PORT
       value: "24224"

ALBターゲットグループのターゲットタイプ変更は再作成が必要

ALBターゲットグループのターゲットタイプはbridgeネットワークモードの場合はinstanceを指定します。awsvpcモードの場合はipに変える必要があります。これに伴い、ALBターゲットグループの再作成が必要になり、さらに、CloudFormationでターゲットグループのNameを指定している場合はリプレースに失敗するので名称を変える必要があります。RDS同様、Nameは未指定でもいいかもしれません。

ECSサービス削除後、ステータスがINACTIVEになるまで待つ必要がある

ECSサービスを作成済みの場合、後からALBターゲットグループを変更できないので、ECSサービスも再作成が必要になります。awscliでdelete-serviceしただけではすぐに消えないので、ステータスがINACTIVEになるまで待ってから再作成する必要があります。

echo "delete service"
aws ecs delete-service --cluster hoge-ECSCluster --service hoge-ECSService

echo "wait until status is INACTIVE"
aws ecs wait services-inactive --cluster hoge-ECSCluster --service hoge-ECSService

ALBからの通信ポートが変わる

ネットワークモードbridgeの場合、ECSコンテナインスタンスがALBからの通信を受けるポートはエフェメラルポート(32768-65535)ですが、awsvpcの場合はコンテナポートそのものになります。

-  ECSContainerInstanceSecurityGroup:
+  ECSTaskSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: hoge-ECSContainerInstanceSecurityGroup
      GroupDescription: ECS Allowed Ports
      SecurityGroupIngress:
        # ALBからの通信許可 (ephemeral port)
        - IpProtocol: tcp
-          FromPort: 32768
+          FromPort: 8080
-          ToPort: 65535
+          ToPort: 8080
          SourceSecurityGroupId: !ImportValue hoge-ALBSecurityGroup
      VpcId: !ImportValue hoge-VPC:Id

SecretsManagerのJSONキーが指定できない

これも気付かずハマりました。シークレットをJSONで登録し、そのキーをタスク定義のsecretsに指定して環境変数を挿入していた場合、シークレットをそれぞれバラして登録し直すか、コンテナ内でjq等で読み出す必要があります。今回はそんなに数も多くなかったのでバラしました。

現時点(2020年2月26日)では、Fargateはこの機能未サポートです。

For tasks that use the Fargate launch type, the following should be considered:

It is only supported to inject the full contents of a secret as an environment variable. Specifying a specific JSON key or version is not supported at this time.
引用:Specifying Sensitive Data Using Secrets Manager - Amazon Elastic Container Service

ECSがSecrets ManagerのバージョンやJSONキーに対応。機密情報管理がめっちゃ便利になりました! | Developers.IO

ECSサービス定義で platformVersion を指定する必要がある

FargateでEFSを使うためには1.4.0以上が必要です。未指定のデフォルト値LATEST1.3.0を向いています。これはこちらで紹介されていました。

ECSタスク定義の無効なパラメータを消す

タスク定義、サービス定義のドキュメントを見直しておきましょう。

次のタスク定義パラメータは Fargate 起動タイプでは無効です。

...

タスク定義の考慮事項 - Amazon ECS

上限値が違うパラメータもあります。

-    stopTimeout: 300
+    stopTimeout: 120 # less than 120

まとめ

ネットワークモードを理解していればそれほど難しくないようです。同じECSとはいえ、起動タイプがEC2とFargateではサポートされている機能にそれなりに違いがあるため、注意が必要です。この機会にパラメータの見直しをしておくのもいいと思います。

3
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?