質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
nginx

nginixは軽量で高性能なwebサーバーの1つです。BSD-likeライセンスのもとリリースされており、あわせてHTTPサーバ、リバースプロキシ、メールプロキシの機能も備えています。MacOSX、Windows、Linux、上で動作します。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

Q&A

解決済

2回答

4649閲覧

ALB(ロードバランサ)からECSに接続する際にエラー(502 Bad Gateway)が出る

退会済みユーザー

退会済みユーザー

総合スコア0

nginx

nginixは軽量で高性能なwebサーバーの1つです。BSD-likeライセンスのもとリリースされており、あわせてHTTPサーバ、リバースプロキシ、メールプロキシの機能も備えています。MacOSX、Windows、Linux、上で動作します。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

0グッド

1クリップ

投稿2021/04/10 05:05

やりたいこと

Amazon-ALBとECSを紐付け、HTTP通信ができるようにしたいです。
ECSのコンテナはNginxとPuma、Postgresqlで構成されています。

エラー内容

ロードバランシングのターゲットグループに上記のEC2インスタンスを登録したところ、
statusが「unhealthy」と表示されています。

確認したこと

・ECSにSSH接続し、さらにNginxコンテナの中でcurl localhost:80を入力したところ、
期待した内容が返ってきました。そのため、Nginx-Puma-Postgres間は問題ないと考えています。

・次に、ECSのインバウンドに不備があると考え、下記のように設定しました。
ただ、結果は「unhealthy」のままでした。

|タイプ|プロトコル|ポート範囲|ソース|
|:--|:--:|--:|
|HTTP|TCP|80|0.0.0.0/0|
|すべてのTCP|TCP|0 - 65535|sg-xxxxxx(ロードバランサのセキュリティーグループ)|
|SSH|TCP|22|0.0.0.0/0|

・また、ALBとNginx間のタイムアウトが原因で接続が切れているのかと思い、
ALBのアイドルタイムアウトを「60秒」、
Nginxのkeepalive_timeoutを「65秒」に設定したのですが、これもエラー解消には繋がりませんでした。

Nginxの設定はこちらになります
# プロキシ先の設定 upstream backend { server unix:///app/tmp/sockets/puma.sock; } server { listen 80; server_name ElasticIPアドレス; keepalive_timeout 65; error_log /var/log/nginx.error.log; access_log /var/log/nginx.access.log; root /app/public; try_files $uri/index.html $uri.html $uri @app; location @app { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://backend; } client_max_body_size 4G; error_page 500 502 503 504 /500.html; location = /500.html { root /app/public; } }

お聞きしたいこと

ロードバランサとNginx間に問題があるとは思うのですが、その詳細まではわかりませんでした。
次に何を確認すべきかアドバイスいただけないでしょうか。よろしくお願いします。

環境

Ruby: 2.7.1
Rails: 6.0.3.5

参考にさせていただいている記事

初心者でもできる! ECS × ECR × CircleCIでRailsアプリケーションをコンテナデプロイ

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

自己解決しました。
原因は、EC2がListenしているポートの設定が間違っていたことにありました。

ALB(ロードバランサ)はEC2の80ポートをヘルスチェックの識別に使うのですが、
私が立てたEC2は、0.0.0.0:32768ポートで受けたデータをNginxの80ポートに伝える設定になっていました。

そのため、外部(ALBやブラウザ)からのアクセスはEC2の80ポートにアクセスしようとするものの、
実際は32768でListenしているため、データのやりとりが正常にできなかったものと考えられます。

よって、タスクの新しいリビジョンを作り、Nginxの設定を
ホスト:80, コンテナ:80
にしたところ正常に動きました。

ただ、EC2のヘルスチェック自体は「unhealthy」のままなので、
正しい解決と言えるかはわかりません。原因がわかりしだい追記しようと思います。

ご協力いただいた TakashiAbe 様
この度はどうもありがとうございました。

投稿2021/04/11 05:53

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/target-group-health-checks.html

https://blog.serverworks.co.jp/tech/2017/02/08/alb-tagert-health-status/

ヘルスチェックの設定はお済みでしょうか? ロードバランサーの定期的なチェックに対して200を返さないといけません。ロードバランサー側、nginxの両方の設定が必要です。

投稿2021/04/10 05:48

編集2021/04/10 05:56
AbeTakashi

総合スコア4853

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/04/10 08:46 編集

TakashiAbe様 早速のご回答ありがとうございます。 知識不足で申し訳ないのですが、回答の意図としては ・ロードバランサ側は、ターゲットグループの詳細画面からヘルスチェックする対象を指定する ・nginx側は、ヘルスチェックされるためのファイル?か何かを用意する ということでよろしいのでしょうか。 [こちらの記事を見て、そのような考えにいたりました。] https://qiita.com/ameyamashiro/items/63793a02d66b6c48ec09#%E5%AF%BE%E5%87%A6 また、併せてお聞きしたいのですが、 EC2インスタンスに紐づいたパブリックIPアドレスをブラウザから入力した際に、 「ERROR_CONNECTION_TIMED_OUT」と表示されるのですが、 これは今回の問題を解決するうえでヒントになりますでしょうか。
AbeTakashi

2021/04/10 10:00 編集

・ロードバランサ側は、ターゲットグループの詳細画面からヘルスチェックする対象を指定する ・nginx側は、ヘルスチェックされるためのファイル?か何かを用意する ↑ これについては概ねその通りかと思います。ロードバランサー的には200が返ってくれば良いので、ロードバランサー側でサイトのトップページを指定して、nginx側では特に設定なしという方法もありといえばありです。とにかくロードバランサー側はヘルスチェックで200が返ってくればhealthyで問題なし、そうでなければunhealthyと判断した時点で、そのインスタンスは使えないと判断されて通信を遮断するはずです。なので、これを回避するのは絶対かと思います(ヘルスチェックを切るという方法もあったような気もしますが、それはやらないですよね)。 「ERROR_CONNECTION_TIMED_OUT」と表示されるのですが、 ↑ こちらもヒントになり得ると思います。今回の不具合がヘルスチェック以外も含めて複合的な要因の可能性もあります。ヘルスチェックをクリアしてもアクセスできない場合は、別の原因だと思うので、このへんの事象も含めて調べる必要があると思います。セキュリティーポリシーはロードバランサー、ECSともに適切に設定されている必要があるでしょうし、ECS側のNATゲートウェイの設定も必要かもしれません(ロードバランサー配下の構成方法によって色々変わるかと)。パブリックIPアドレスにアクセスして何か返ってきた際にそれがロードバランサーが返したものか、ECSが返したものか、何も返ってこずにタイムアウトになるのかなどで、その都度状況判断する必要があると思います。
退会済みユーザー

退会済みユーザー

2021/04/10 10:21 編集

ご回答ありがとうございます。 丁寧な説明のおかげでだいたいのイメージが掴めました。 「今回の不具合がヘルスチェック以外も含めて複合的な要因の可能性もあります。ヘルスチェックをクリアしてもアクセスできない場合は、別の原因だと思うので、このへんの事象も含めて調べる必要があると思います。」 とのことなので、問題をさらに切り分けて考えてみます。 何かわかったことがあればすぐに追記します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問