実現したいこと
RailsアプリケーションをAWS ECSにて運用したいのですが、
サービスを実行すると、実行したタスクが数分で停止してしまいます。
サービスがタスク数を維持しようとしてまた新しくタスクが実行されますが、そのタスクも数分で停止します。
この繰り返しになってしまいます。
以前は問題なくサービスを実行できていたのですが、アプリの開発を行い、タスク定義をアップデートしたところ、
上記のような問題が発生しました。
*5/19追記
以前は問題なくサービスを実行できたと書きましたが、確認してみると、以前のコードでも上手く動きませんでした。
コード以外になんらかの変更を加えてしまい、それが原因となっている可能性が高そうです。
構成・前提
ロードバランサー:ALB データベース:RDS デプロイ:ECS => 起動方法: EC2 => 実行: クラスター1つ、サービス1つ、タスク1つ => タスク定義: Nginxコンテナ, Railsコンテナ (Unicorn) ALB-EC2間の通信: HTTPS Rails関連: => rails db:create, rails db:migrate 済み => RAILS_MASTER_KEY 設定済み
発生している問題・エラーメッセージ
ECSのサービスにて実行したタスクが3分程で停止してしまいます。
具体的には、Nginxコンテナ, Railsコンテナが両方立ち上がるのですが、3分程でコンテナが停止し、どちらもSTATUS
がExited (137)
になってしまいます。
また、同じタスクを、サービスを通さずに単発で実行すると、停止しません。
(ECSコンソール
=>クラスター
=>タスク
=>新しいタスクの実行
)
タスクは停止せず、コンテナは問題なく起動し、コンテナのSTATUS
はUP
を維持します。
この違いは何なのでしょうか?
単発のタスク実行は成功することから、タスク定義は問題ないと考えます。
どちらのパターンも同じタスク定義を使用し、タスクの実行に使用しているEC2インスタンスも同じです。
どこに差分が生まれているのでしょうか?
試したこと
考えられる差分として、ALBのヘルスチェックが何らかの悪さをしているのではと考え、ヘルスチェックのプロトコルをHTTPS
からHTTP
に変更しましたが、結果は変わりませんでした。
(Nginxコンテナは、443ポートで動的ポートマッピングしているため、HTTP
にすることによりNginxコンテナへのヘルスチェックの通信を切る形になります)
ログ
Dockerの標準出力、NginxとRailsAppのログファイルにも、ログは一切出力されませんでした。
該当のソースコード
servise
起動タイプ: EC2 新しいデプロイの強制: なし サービスタイプ: REPLICA タスクの数: 1 最小ヘルス数: 0 最大ヘルス数: 200 ヘルスチェックの猶予期間: 0 ロードバランシング: => ロードバランサー名: ALB => コンテナ名: Nginx => コンテナポート: 443 => ターゲットグループ: ALB-TargetGroup Service Auto Scaling: サービスの必要数を直接調整しない
RailsApp
# Dockerfile FROM ruby:2.5.1 ENV JAVA_HOME /usr/lib/jvm/java-1.8.0-openjdk-amd64 RUN apt-get update \ && apt-get install -y \ build-essential \ nodejs \ openjdk-8-jdk ADD . /rails-app-root WORKDIR /rails-app-root RUN mkdir tmp tmp/sockets log \ && bundle install CMD unicorn_rails -c /rails-app-root/config/unicorn.rb -E production
nginx
# Dockerfile FROM nginx:1.15.8 RUN rm -f /etc/nginx/conf.d/* ADD docker/nginx/nginx.pro.conf /etc/nginx/conf.d/rails_app.conf RUN apt-get update \ && apt-get install -y \ openssl \ && mkdir /etc/ssl/ca \ && cd /etc/ssl/ca \ && openssl req -new -newkey rsa:2048 -keyout server.key -nodes -out server.csr -subj "/C=JP/ST=Prefecture/O=Hoge/CN=www.hoge.com" \ && openssl x509 -req -days 3650 -signkey server.key -in server.csr -out server.crt CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf # docker/nginx/nginx.pro.conf upstream unicorn { server unix:///rils-app-root/tmp/sockets/unicorn.sock; } server { listen 443 default ssl; server_name www.hoge.com; access_log /var/log/nginx/access.log main; error_log /var/log/nginx/error.log warn; root /rails-app-root/public; client_max_body_size 100m; error_page 404 /404.html; error_page 505 502 503 504 /500.html; try_files $uri/index.html $uri @rails_app; keepalive_timeout 5; ssl_certificate /etc/ssl/ca/server.crt; ssl_certificate_key /etc/ssl/ca/server.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; location @rails_app { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host; proxy_pass http://unicorn; } }
まとめ
なぜ、タスクは数分ですぐに停止してしまうのでしょうか?
サービスを通さずに単発でタスクを実行した状態と、サービスを通してタスクを実行した状態の差分に原因があると考えていますが、その原因をつかめておりません。
ALBが絡むくらいしか差分はないように思うのですが、ALBが原因であるとは考えづらいです、、。
このような問題の想定原因をご教授頂けますと幸いです。
宜しくお願い致します。
追記
5/19
調べると以下の公式資料が該当し、停止したタスクには停止理由が表示されるとのことでした。
コンソールから確認すると、以下のようになっていました。
停止理由: Scaling activity initiated by deployment ecs-svc/123456789001122
タスクの実行数を1にしてデプロイしているのですが、今回の問題だと永遠に新しいタスクが実行されてしまうため、確認したいことが終わるとタスク数を0にすることにより対応しています。
上記は、そのタスク数0の変更に対してサービスが対応した結果だと思われます.
停止理由: Task failed ELB health checks in (target-group arn:aws:elasticloadbalancing:ap-northeast-1:...)
3分置きに終了してしまうタスクには、この様な停止理由が書かれていました。
タスクは、ターゲーットグループのヘルスチェックが何回か失敗すると、自動的に停止する仕様になっているのでしょうか?
ヘルスチェックがなぜ失敗するのか、原因を調査してみます。
取り急ぎ、共有させて頂きます。
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/stopped-task-errors.html
もう一つ追記です。
タスク数を2にしてデプロイしてみましたが、状況は変わりませんでした。
むしろ、実行されているタスク数は1から変わらず、少々おかしいような気がします。
こちらは、当方のECSやオートスケーリング、タスク配置についての理解不足が原因で、タスク数1が正常なのかなとも思っております。
こちらも共有させて頂きます。
まだ回答がついていません
会員登録して回答してみよう