【AWS/ECS】デプロイ後、アクセス出来ない

タスクやEC2インスタンスなど、どこを見ても正常なはずなのにいざパブリックIPにアクセスするとアクセス不可の表示が。

結論から言うと、タスク定義の際に設定する「ネットワークモード」をawsvpcにしているのが原因です。bridgeにすれば正常に作動しました。

それもそのはず、既に定義したVPCの中でEC2インスタンスを動かし、それに伴うセキュリティグループなどを設定した上で、その中でタスクを動かすわけですからアクセス出来なくなってしまいます。

【AWS/ECS】タスクを実行するとRESOURCES"PORT"となる場合

サービスを作ったのにも関わらず、タスクが起動しない。

自動起動が行われないので、手動で起動してみるとRESOURCES"PORT"となりました。

結論から言うと、EC2インスタンスを利用したECSの場合はそれを再起動もしくは削除し新規作成すれば解決します。

原因としましては、古いコンテナ側で利用しているポートがあるので、新しいコンテナ側では重複してしまいエラーが発生するという流れらしいです。

参考

https://toris.io/2015/12/a-few-things-i-wanted-to-know-before-playing-with-amazon-ecs/

【AWS・ECS】Nginx 502 Bad Gatewayが表示されたとき

何度か表示されたので、解決方法をメモ。

1.volumeの設定を確認する

volumeが正しく設定されていないときに発生しました。

ECSのvolumeはタスク定義から設定しますが、この設定に不備があったのが原因でした。

webコンテナとnginxコンテナがあって、web側と共有したいディレクトリがnginxにあった場合の設定方法をまとめると

  • タスク定義画面下のボリュームから該当するボリュームを作成する
  • 作成画面ではボリュームドライバーを選択し、localに
  • スコープはtaskにしておく
  • 他の項目は空白で良いのでそのまま追加
  • 画面上に移動し、webコンテナをいじる
  • 「ストレージとログ」からマウントポイントを設定する ソースボリュームに先程追加したボリュームを選び、コンテナパスにボリュームとして設定したいディレクトリを入力する。
  • 同じく、nginx側のボリューム設定に移動し「ストレージとログ」の「ボリュームソース」をいじる
  • 今回、nginxコンテナはwebコンテナでマウントしたボリュームを共有したいので ソースコンテナ欄にwebコンテナのコンテナ名を入力すれば完了

みたいな風に一つひとつの入力を確認しながらやると不備が発見できたので、うまくいけました。

2.コンテナのログを確認してみる

大体起動するはずのコンテナがexitedしているケースが多いのでログを確認してみる

確認の仕方は https://qiita.com/mom0tomo/items/35dfacb628df1bd3651e ここを参考にした。

僕の場合はtmp以下が自動で作成されないみたいなエラーだったので、手動で作成することでどうにかなった。

【AWS・ECS】ECSの各流れを軽くまとめる

ECSは色んな単語があったり、役割を覚えるのがややこしいので、忘れたとき用にまとめてみる。

今回はEC2テンプレート(Linux)を用いた例

1番大きい単位のものから順にまとめてみる

  • クラスター ここで、起動するEC2インスタンスの設定などを調整する。 EC2のVPCやSGもここで設定する。
  • EC2インスタンス クラスターを元に作成されたインスタンス この中でタスクを動かす
  • タスク定義 起動するコンテナの設定をまとめるもの
  • サービス タスク定義を元にタスクを生成したり、タスクのネットワークの設定などを調整する。
  • タスク タスク定義を元にタスクは作成される

【AWS】ECSにALBを設定したら接続に時間がかかる問題

タイトルにある通り、ECSにALBを設定すると最初の接続にかなり時間がかかります。

一度アクセスすればその後は快適なのですが、少し時間を置くとまたかなり時間がかかります。

具体的な時間を言うと20秒~30秒程度でしょうか。ちょっと致命的です。

思い当たったのが、ALBを作成する際に設定したサブネット。

デフォルトで2つ必要ということなので、何も考えずにパブリックとプライベート1つずつ選択したのですが、それがちょっとまずかったみたいです。

要はALBがサブネットを振り分ける際にプライベートサブネットが含まれているとこのような現象が起きるらしい。

とりあえずこのためにEC2インスタンスを新しいサブネットに増やすのもどうなのかなと思ったので、空でigwを設定した既存のものとはAZが別のサブネットを作成。

それをALBに登録して、プライベートのサブネットを解除したらひとまず収まったっぽいです。

そもそも実用するならインスタンス2個以上あって当然でしょみたいなことなんですかね。よくわからないですが。

RailsのRSpecテストにおける用語整理

  • RSpecRubyにおけるBDDのためのテスティングフレームワーク
  • BDD…Behavior(振舞)をまず作り、その後にプロダクトコードを書く開発手法
  • CapybaraRSpecと組み合わせて使うE2Eテスト用フレームワーク。ブラウザ操作などをシュミレーションできる。
  • E2E…End to End。E2Eテストはアプリの開始から終了までがちゃんと動くかテストすること。
  • FactoryBot…テスト用データ作成をサポートするGem。
  • SystemSpecRSpecにおけるE2Eテストに相当する。ブラウザを通して挙動を確認できる。
  • ファクトリ…前提となるデータを作成するためのテンプレート
  • Example…単位。期待することと、実際の値を書いたひとまとめの単位。itからendまで。
  • エクスペクテーション…Exampleの期待することろの部分。

【AWS】ECS+Fargateで環境構築

Dockerの基本的な座学は大体終えたので、AWSのECSをFargateで実践してみる。

用語整理

  • タスク…アプリケーション単位のコンテナのまとまりのこと。コンテナの集合体。 AコンテナとBコンテナという2つのコンテナでWebサーバーを構築する場合、Webサーバーのタスクということになる。次の「タスク定義」を元に作成される。
  • タスク定義…どのようなタスクを生成するかを定義しているもの。どんなイメージ、CPUやメモリの割り当て、などなどを設定する。
  • サービス…タスクのステータスを監視しながら、タスクの台数だったりを調整してくれるもの。
  • クラスタ…アプリケーション毎にタスクとサービスをまとめるもの。
  • ECRAWSが提供するDockerイメージのレジストリサービス
  • ALBロードバランサー(サーバーにかかる負荷を分散させるもの)
  • TargetGroup…ALBとサーバーの間にあるもので、ヘルスチェックなどを担う。

ECRへのプッシュ

ECRへイメージのプッシュは別の記事にまとめたので、既に使用するイメージのプッシュは済んでいるものとする。

クラスターの作成

ECS上でアプリケーションを動かすとき、クラスター、タスク、サービスの3つを主に作成することになるが、その中で一番大きい単位のものがクラスター。

今回は1つのタスクしか作らないが、複数のタスクをまとめる役割を持つ。

タスクが1つだとしても必要不可欠である。

ECSのダッシュボードからクラスターを作成する。

ネットワーキングのみと書かれ、AWS Fargateを使用と書かれたテンプレートを選択。

適当なクラスター名を入力し、VPCは既に作成してあるのであればVPCの作成にチェックは入れない。

今回はWebサーバーのタスクのみを入れるので、それ専用のパブリックVPCは予め作成しておく。

これで作成を押す。

タスク定義を作成

タスクのあれこれを記述するタスク定義を作成する。

同じくダッシュボードからタスク定義を作成。

FARGATEを選択、

タスクロール:ecsTaskExecutionRole

ネットワークモード:vpc

タスクメモリ&タスクCPU:とりあえず一番小さいもの

コンテナの定義:

コンテナ名はわかりやすいものを入力し、イメージに事前にECRへプッシュしておいたものを入力する。ECRのダッシュボードのURIに:tagとして:latestを付けておく。

メモリ制限はとりあえず128、ポートマッピングはdocker-composeでいうportsの部分を入力。

下のストレージとログの部分にボリュームの設定がある。

もし今定義しているコンテナが他のコンテナのボリュームを参照したい場合は、ボリュームソースのソースコンテナの部分に参照したいコンテナ名を入れる。多分docker-composeでいう(Ver3からはないが)volumes_forみたいなやつだと思う。

あとは基本そのままで作成。

サービスの作成

先程作ったタスク定義からどうやってタスクを作成するかと言うと、このサービスを作成し、実行することで作成することができる。

サービスはタスクやクラスターを設定した通りに管理してくれる優秀な装置みたいなもの。

前に作成したクラスターの画面からサービスを作成する。

起動タイプは勿論FARGATE、タスク定義は先程のを選択、リビジョンはlatest

サービス名はわかりやすいものを。

サービスタイプはとりあえずレプリカ。

タスク数は1。

最小ヘルス100、最大率200。

VPCやらセキュリティグループは予め設定したものを選ぶ。

サービス検出の結合の有効化はとりあえずなしで。

以上で作成。

作成が終わると、タスクを実行し、クラスターのタスクタブからステータスを確認することができる。

この時点で、タスクのパブリックIPへアクセスすると、対象のアプリケーションが表示されるはず。

コマンド入力が必要なときについて

rails db:createなどコマンド打ちたいからSSHでFargateに入りたいのですが、残念ながらFargateはSSHに対応していません。

ただ、AWSのSystemManagerを利用すれば出来るっぽいです。(動かすコンテナにssm-agentを入れたりとだいぶ面倒そうですが…)

https://qiita.com/pocari/items/3f3d77c80893f9f1e132

僕の場合はとりあえずrails db:createしたいだけだったので、既にテストとして作っていたEC2インスタンスを起動し、それにSSH接続しコマンド入力でcreateしました。