Monitによるkusanagi restartの連鎖で全サイト停止する

TOP Forums バグ報告と提案(Requests and Feedback) Monitによるkusanagi restartの連鎖で全サイト停止する

Monitによるkusanagi restartの連鎖で全サイト停止する

Viewing 6 reply threads
  • Author
    Posts
    • #1704
      hirasawa3
      Participant

        AlmaLinux 9 / KUSANAGI 9.11.2 / httpd-behind-nginx 構成です。

        稼働中の全profileへ突然アクセスできなくなり、確認したところ nginx129@with_httpd.service が停止していました。
        手動で

        systemctl start nginx129@with_httpd

        を実行すると正常に起動し、全サイトが復旧しました。

        調査したところ、Monitによる kusanagi restart が短時間に繰り返され、最終的にsystemdのstart-limit-hitに到達していたことが分かりました。

        最初の契機として、あるprofileのnginx SSLアクセスログでHTTP 499が検出され、

        trying to restart
        restart: '/opt/kusanagi/bin/kusanagi restart'

        となっていました。

        該当profileのMonit設定は以下です。

        restart program = "/opt/kusanagi/bin/kusanagi restart"
        if match '"(GET|POST) /.* HTTP/.*" (499|5[0-9][0-9]) [0-9]+ ' for 5 cycles then restart
        if 5 restarts within 5 cycles then alert
        if 5 restarts within 5 cycles then unmonitor

        その後、kusanagi restartによるnginx/httpdの再起動中に、別profileで502/503が記録され、それを各profileのMonitが検出してさらに kusanagi restart を実行する、という連鎖が発生していました。

        実際に短時間でnginx/httpdのstop/startが繰り返され、まずhttpdが

        10:25:24
        httpd@with_nginx.service: Start request repeated too quickly.
        httpd@with_nginx.service: Failed with result 'start-limit-hit'.

        となりました。

        その後もrestartが続き、nginxも

        10:26:02
        nginx129@with_httpd.service: Start request repeated too quickly.
        nginx129@with_httpd.service: Failed with result 'start-limit-hit'.

        となっています。

        systemdの設定を確認すると、nginx/httpdともに

        StartLimitIntervalUSec=10s
        StartLimitBurst=5

        でした。

        KUSANAGIのbackend.logでも、

        10:25:24
        'systemctl restart httpd@with_nginx.service' returned 1

        10:26:02
        'systemctl restart nginx129@with_httpd.service' returned 1

        10:26:03
        'systemctl restart nginx129@with_httpd.service' returned 1

        10:26:04
        'systemctl restart nginx129@with_httpd.service' returned 1

        などが記録されています。

        nginxの設定テスト自体は正常で、後からsystemctl startを実行すると正常起動するため、nginx設定エラーではなく、短時間のrestart回数がsystemdのStartLimitBurstを超えたことが直接の停止原因と考えています。

        気になっているのは、Monitのrestart回数制限は各profileのcheck単位ですが、実際に実行されるのがprofile単位の復旧ではなく

        /opt/kusanagi/bin/kusanagi restart

        である点です。

        例えば複数profileがそれぞれ1回ずつrestartを要求した場合、各profileでは「5 restarts within 5 cycles」に到達していなくても、共有しているnginx/httpdには短時間に5回を超えるrestartが発生し得ます。

        また、一度の kusanagi restart による瞬断で他profileに502/503が発生し、その502/503が次の kusanagi restart の契機になるため、restart処理自身が次のrestart条件を作る状態になっているように見えます。

        なお、保存していたKUSANAGI 9.9.0のRPMと現在の9.11.2を比較したところ、Monitのnginx監視条件は9.9.0時点ですでに

        (499|5[0-9][0-9])

        となっており、9.11.2で新たに499監視が追加されたものではありませんでした。
        changelog上では9.8.9で

        Add 499 to monit restart condition.

        とされています。

        9.9.0と9.11.2のMonitテンプレートの主な差は、

        if match

        から

        if content =

        への変更でした。

        そのため今回の現象は9.11.2固有とは限らず、以前のバージョンでも発生し得る構造ではないかと考えています。
        過去にも原因不明で一部サイトへアクセスできなくなり、kusanagi restartで復旧したことがあった可能性がありますが、今回ほど詳細には調査していませんでした。

        なお9.10.4以降では、同一のstate-changing commandをbackend側で順番待ちさせる処理も追加されているようですが、今回その待機処理が実際に発動したかどうかまではログから確認できていません。

        現在は再発防止のため、暫定的に

        kusanagi monit off

        として運用しています。

        Monitの各profileによる5xx/499検出から共有サービス全体の kusanagi restart を実行する現在の構成では、このようなprofile間のrestart連鎖が発生する可能性があるように思います。

        仕様上想定された動作なのか、またMonitのrestart処理について修正等が必要な状態なのか、ご確認いただけますでしょうか。

      • #1706
        hideishi
        Participant

          hirasawa3さん

          monitの設定は標準的な設定として用意しているもので、
          環境によっては負荷が集中するとmonitが多重検知することはあるかもしれません。
          必要に応じてカスタマイズしてみてください。

          例えば、頻発するようであれば for 5 cycles then restart を 10 や 20 のように増やしてみてください。
          また if 5 restarts within 5 cycles then unmonitor は5回連続してrestartをかけるとmonit監視をやめるようにしています。
          これは逆に 3 restarts のように数を減らすとmonit監視を早く止める (=restartが早く止まる) ことができます。
          変更した後は kusanagi monit reload で読み込み直してください。

          設定ファイルに加えた変更は kusanagi monit config を実行するとデフォルトに戻ります。

          それでも解決できない場合は kusanagi monit off でmonitを無効にしてみてください。

        • #1707
          hirasawa3
          Participant

            ご回答ありがとうございます。

            Monitの設定について、環境に応じて調整する想定であること、承知しました。

            for 5 cycles then restart を10や20へ増やすことや、if 5 restarts within 5 cycles then unmonitor のrestart回数を減らすことも検討してみます。

            一点、今回の現象について確認させてください。

            今回のログを見る限り、1つのprofileが短時間に何度もrestartを繰り返したというより、

            1. あるprofileで499/5xxを検出
            2. Monitから kusanagi restart
            3. nginx/httpdの再起動中に別profileで502/503が発生
            4. そのprofileのMonitから再度 kusanagi restart
            5. さらに別profileで502/503が発生

            という形で、複数profileからrestartが連鎖しているように見えました。

            各profileのMonit設定では、

            restart program = "/opt/kusanagi/bin/kusanagi restart"

            となっているため、各profileの監視に対するrestartであっても、実際には共有しているnginx/httpd等が再起動されます。

            また、この環境ではnginx/httpdともに、

            StartLimitIntervalUSec=10s
            StartLimitBurst=5

            となっており、実際に短時間のrestart後、

            Start request repeated too quickly.
            Failed with result 'start-limit-hit'.

            となっていました。

            このため、例えば複数のprofileがそれぞれ1回ずつrestartを要求した場合、各profileでは

            if 3 restarts within 5 cycles then unmonitor

            のような条件にまだ達していなくても、共有nginx/httpd側では合計5回を超えてrestartされ、systemdのStartLimitに到達する可能性があるように思います。

            for 5 cycles を10や20に増やせば最初のrestart自体は発生しにくくなると思いますが、一度restartが発生した際のprofile間の502/503によるrestart連鎖についても、この調整で防止できるという理解でよいでしょうか。

            あるいは、複数profileを収容している環境では、各profileのMonitから共有サービス全体の kusanagi restart を実行しないようにするなど、推奨される設定方法がありますでしょうか。

            現在は再発を避けるため、引き続き kusanagi monit off としています。

            よろしくお願いいたします。

          • #1708
            hideishi
            Participant

              hirasawa3さん

              フィードバックありがとうございます。
              複数のプロファイルを同一サーバで運用している環境で同じような問題に直面していますので、ご意見もっともだと思います。

              再起動がprofileで共通になっていることには理由があります。
              「別のprofile」が原因でアクセス不能になっていることもあるからです。
              例えば、「別のprofile」がphp-fpmがリソース食い潰す、MariaDBのセッションをロックしている、httpd/nginxのコネクションを使い切ったことで「今のprofile」がアクセス不能になっている場合には、全体をrestartする以外に解消する手段がないためです。

              提案のように、kusanagi restartに制限を設けることも検討しました。しかし、lockによる不具合の危険性を完全に回避できないことから見送りになっています。(9.10.4で対応した問題です)
              細かくmonitをカスタマイズすれば実現できるかもしれませんが、正直monitの運用の限界だと感じています。

              申し訳ないのですが、設定を調整するか、offにしてみてください。
              また、そもそも最初に499/5xxが発生した原因をつぶすことが根本的な解決になります。
              error.logから何が原因で最初の5xxが起きたのかを確認することはいかがでしょうか。

              なお、Security Editionではmonitに依存しないように、KUSANAGI自身でログを監視する仕組みを入れています。

            • #1709
              hirasawa3
              Participant

                hideishiさん

                ご回答ありがとうございます。

                複数profile環境で同様の問題をご認識されていること、また共有サービス全体をrestartする設計上の理由と、Monitでの運用上の限界について理解しました。

                今回の調査では、499を契機としたrestart後に他profileの502/503からrestartが連鎖し、最終的にsystemdのstart-limit-hitに到達していたことまで確認できましたので、当面はMonitをoffにした状態で運用し、必要に応じて監視方法を検討したいと思います。

                また、最初の499/5xxについても、引き続きログを確認してみます。

                詳しくご説明いただき、ありがとうございました。

              • #1711
                hideishi
                Participant

                  hirasawa3さん

                  9.11.4-1 でmonitのrestartの問題の改善を入れました。
                  monitのテンプレートを再生成する必要があるのが、プロファイルごとに以下のコマンドを実行してください。

                  kusanagi monit config プロファイル

                  完全にrestart連鎖を止められるものではありませんが、monit経由のrestartの実行を制限するようにしています。
                  こちらの設定で改善されるかどうか確認いただけますか。

                  • This reply was modified 2 weeks, 2 days ago by hideishi.
                • #1713
                  hirasawa3
                  Participant

                    hideishiさん

                    ご提示いただいた手順で、9.11.4-1を導入しました。
                    しばらく様子を見ます。

                    ご対応いただき誠にありがとうございました。

                Viewing 6 reply threads
                • You must be logged in to reply to this topic.

                Next article

                フォーラムについて