kubernetes でデプロイするときの5xxエラーを解決する
kubernetes でローリングデプロイを行う際、途中で502、503エラーが発生することがある。 <https://github.com/kubernetes/kubernetes/issues/96858 <https://github.com/kubernetes/kubernetes/issues/20473
kubernetes でローリングデプロイを行う際、途中で502、503エラーが発生することがある。 <https://github.com/kubernetes/kubernetes/issues/96858 <https://github.com/kubernetes/kubernetes/issues/20473
kubernetes でローリングデプロイを行う際、途中で502、503エラーが発生することがある。
https://github.com/kubernetes/kubernetes/issues/96858
https://github.com/kubernetes/kubernetes/issues/20473
https://github.com/foriequal0/pod-graceful-drain
この問題に関するIssueと、それを解決するために作られた pod-graceful-drain がある。
もちろん、私は sleep を使って対処している。
説明すると、Podが新しくデプロイされると、既存のPodは終了処理に入るが、 終了処理に入った後も、そのPodにはリクエストが引き続き届く。
このとき、終了処理中にリクエストが届いても、途中でPodが終了してはいけない。 そのため、nginx と php-fpm に sleep を設定する。
つまり、php-fpm が先に停止してしまうと、nginx は stream エラーを返すことになる。 そのため、php-fpm は必ず nginx より遅く終了しなければならない。
とはいえ、php-fpm と nginx がいつ終了しても、大きな問題はないのだが。
重要なのは、AWSネットワークでALB、LBから接続が切り離されるまでの最短時間分は、必ず sleep させることだ。
その時間は約15秒かかる。
つまり、終了処理中であっても、15秒間はリクエストが届く可能性があるということだ。
そのため、sleep は最低でも15秒以上にしなければならない(nginx、php-fpm)。
その後、さらに sleep を追加するかどうかは、サーバー環境によると思う。
たとえば、処理に10秒かかるリクエストがある場合は、
15(ネットワーク)+ 5(余裕)+ 10(最大リクエスト時間)= 30秒にすればよいだろう。
また、terminationGracePeriodSeconds の値は、必ず sleep より大きくする必要がある。
sleep が30なら、terminationGracePeriodSeconds は40程度にすればよい。
lifecycle:
preStop:
exec:
command:
- /bin/sh
- -c
- sleep 20
terminationGracePeriodSeconds: 30そのため、通常はこのように設定すればよい。