GKE Kubernetes クラスターとデプロイメントがあります。
デプロイメントのリソーススタンザを次のように設定しました。
resources.requests.memory: 4G
resources.requests.cpu: 2
resources.limits.memory: 4G
CPU制限が設定されていません
ポッド(Djangoウェブアプリ)をデプロイし、負荷テストで叩きます。飽和状態になると、ポッドのCPU使用率は1CPUまで上がりますが、基本的には1CPUを超えることはありません。
ここで何をトラブルシューティングすればよいか、何かアイデアはありますか?
答え1
この投稿は開いたままにしていたので、閉じておきましょう。
私の場合、ボトルネックは実際には K8S Pod の上流、データベースにあることが判明しました。postgres インスタンスは単純に大きさが足りず、CPU 使用率が 100% に達し、下流のタイムアウトを引き起こしていました。
確信はありませんが、ポッドの CPU が平準化したのは、ポッドがアップストリームからの応答を待機していて、他に何もすることがなかったために 1 CPU 使用率を維持できなかったためだと思われます。
さらに、Django インスタンスは Django チャネルと ASGI 非同期モデルを使用しています。これはシングル スレッドであり、UWSGI と同じ「子スレッド」モデルを持っていません。これが、Pod の CPU 使用率が 1CPU で最大になるもう 1 つの理由 (または実際の理由) です。
だから、これを拡大する正しい方法は、
- Postgresを垂直にスケールする
- ポッドのベースライン数を増やす
- オートスケーラー(HPA)のしきい値を下げてスケールアップし、新しいポッドを追加します。
編集: 追加情報
この問題は、アプリ自体の設計方法にも関係しています。私たちは、Django Channelsの非同期Pythonを使用し、Daphne ASGIコンテナでhtatを実行しようとしています。しかし、アプリのすべてが非同期というわけではなく、どうやらそれは悪いことです。私はこの非同期対同期アプリケーションの問題とその結果生じるデッドロックについて多くの調査を行い、開発チームにアプリを再設計させている間に、デプロイも再設計しました。
- デプロイメントにuWSGIサーバーを追加する
- コードベースを2つのデプロイメント/ポッドにデプロイする
- 1つはASGIポッド
- 1つはuWSGIポッド
- すべてのASGIエンドポイント(1つだけ)をIngress PathルールのASGIポッドにルーティングします。
- Ingress PathルールですべてのuWSGIエンドポイントを同期ポッドにルーティングする
これは機能しますが、まだ完全な負荷テストは完了していません。