Upgrade to Pro — share decks privately, control downloads, hide ads and more …

20211118_GKEにおける高負荷時のPodとWorker_Nodeの挙動について.pdf

2e2c49f6f3fa33b8f5aad5841774c211?s=47 nezumisannn
November 18, 2021

 20211118_GKEにおける高負荷時のPodとWorker_Nodeの挙動について.pdf

2e2c49f6f3fa33b8f5aad5841774c211?s=128

nezumisannn

November 18, 2021
Tweet

More Decks by nezumisannn

Other Decks in Technology

Transcript

  1. GKEにおける高負荷時の PodとWorker Nodeの挙動について MixLeap Study #68 - 各社事例に学ぶKubernetes運用 2021/11/18 株式会社ビヨンド

    寺岡 佑樹
  2. 自己紹介 resource “my_profile” “nezumisannn” { name = “Yuki.Teraoka” nickname =

    “ねずみさん家。” company = “beyond Co., Ltd.” job = “Infra Engineer” twitter = “@yktr_sre” skills = [“Terraform”,”Packer”] }
  3. 前提 • 疑似的なリクエストを生成する • 最初は最小スペック/設定で構築する • 負荷が上昇する度に原因を調査 ◦ Clusterの状態の確認と改善に向けた対応案を検討する •

    Apache Benchを利用する ◦ ab -n <総リクエスト数> -c <同時接続数> <リクエスト先URL>
  4. ホストマシンスペック • Master Node ◦ GKEのため利用者からは見えないようになっている • Worker Node ◦

    初期1台 ◦ v1.20.10-gke.1600 ◦ Container-Optimized OS from Google ◦ containerd://1.4.4 ◦ e2-standard-2(vCPU:2 / Mem:8GB)
  5. マニフェスト • Namespace ◦ 本番環境を想定 • Deployment ◦ コンテナ ▪

    Nginx ▪ PHP ◦ アプリケーションフレームワーク ▪ Laravel • Service ◦ NodePortでNginxの80番ポートを公開 • Ingress ◦ CloudLBを利用してserviceを外部公開
  6. 平常時 Worker Node ``` $ kubectl top node NAME CPU(cores)

    CPU% MEMORY(bytes) MEMORY% gke-gke-cluster-default-pool-a063d899-58t9 149m 15% 799Mi 28% ``` Pod(Production) ``` $ kubectl top pod -n production NAME CPU(cores) MEMORY(bytes) laravel-6dbd68b4f9-7pnln 16m 64Mi ```
  7. 1. 単一Podに対して小規模なリクエストを生成する ``` $ ab -n 500 -c 1 http://{IP

    アドレス}/ ``` watchコマンドとkubectl top を併用 名前空間のkube-system に対してmetrics-server が必要になるが GKEは初期状態でセットアップされている 単一のWorker Node が有するvCPUが2のため、CPUを使い切ることなくまだ余裕がある状態 応答遅延を感じることもない ``` Every 2.0s: kubectl top node && kubectl top pod -n production NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% gke-gke-cluster-default-pool-a063d899-58t9 784m 83% 823Mi 29% NAME CPU(cores) MEMORY(bytes) laravel-6dbd68b4f9-7pnln 580m 119Mi ```
  8. 2. 単一Podに対して生成するリクエスト量を増やす ``` $ ab -n 10000 -c 50 http://{IPアドレス}/

    ``` PodによってリクエストされたCPUリソースが増えてWorker Nodeが有するvCPUを使い果たしている 応答遅延が発生してタイムアウトする(Nginxが499エラーで応答する)、本番環境だと普通に障害 Pod * 1 / Worker Node * 1の現状ではここが性能限界 ``` Every 2.0s: kubectl top node && kubectl top pod -n production NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% gke-gke-cluster-default-pool-a063d899-58t9 1998m 212% 855Mi 30% NAME CPU(cores) MEMORY(bytes) laravel-6dbd68b4f9-7pnln 1824m 146Mi ``` 現時点で複数の問題を抱えているが、まずは素直にPodの数を手動で増やしてみる
  9. 3. リクエスト量はそのままでPodの数を増やす deploymentのspec.replicasを1から5に変更する ``` spec: replicas: 1 spec: replicas: 5

    ``` Podの数が増えて全てRunningになる ``` $ kubectl get po -n production NAME READY STATUS RESTARTS AGE laravel-6dbd68b4f9-4w8qr 2/2 Running 0 74s laravel-6dbd68b4f9-75p9n 2/2 Running 0 74s laravel-6dbd68b4f9-7pnln 2/2 Running 0 19h laravel-6dbd68b4f9-9jkwc 2/2 Running 0 74s laravel-6dbd68b4f9-j4qq8 2/2 Running 0 73s ```
  10. 3. リクエスト量はそのままでPodの数を増やす ``` $ ab -n 10000 -c 50 http://{IPアドレス}/

    ``` 単一Podごとのリソース使用量は減少した Worker NodeのCPUリソースが枯渇しているのでPodを増やしても応答遅延は解消しない ``` Every 2.0s: kubectl top node && kubectl top pod -n production NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% gke-gke-cluster-default-pool-a063d899-58t9 1999m 212% 1167Mi 41% NAME CPU(cores) MEMORY(bytes) laravel-6dbd68b4f9-4w8qr 376m 82Mi laravel-6dbd68b4f9-75p9n 348m 82Mi laravel-6dbd68b4f9-7pnln 345m 131Mi laravel-6dbd68b4f9-9jkwc 351m 83Mi laravel-6dbd68b4f9-j4qq8 388m 83Mi ```
  11. 4. Worker Nodeの数を増やす gcloudコマンドでWorker Node(Node Pool) の数を増やす ``` $ gcloud

    container clusters resize gke-cluster --node-pool default-pool --num-nodes 5 ``` 若干の偏りはあるがリソース状況が大きく改善 応答遅延もなくなった ``` Every 2.0s: kubectl top node && kubectl top pod -n production NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% gke-gke-cluster-default-pool-a063d899-43dr 631m 67% 533Mi 18% gke-gke-cluster-default-pool-a063d899-58t9 640m 68% 550Mi 19% gke-gke-cluster-default-pool-a063d899-h02m 388m 41% 569Mi 20% gke-gke-cluster-default-pool-a063d899-jmh8 634m 67% 577Mi 20% gke-gke-cluster-default-pool-a063d899-r83r 660m 70% 564Mi 20% NAME CPU(cores) MEMORY(bytes) laravel-6dbd68b4f9-7pnln 590m 60Mi laravel-6dbd68b4f9-gl2vs 588m 60Mi laravel-6dbd68b4f9-jg8dr 375m 61Mi laravel-6dbd68b4f9-wh7sx 579m 61Mi laravel-6dbd68b4f9-z6fs5 628m 61Mi ```
  12. ここまでの整理 • 単一PodでもWorker Nodeのリソースが枯渇しない限りは応答遅延が出なかった • Worker Nodeのリソースが枯渇すると当然ながら Podが起動していても障害状態になる • この状態でPodの数を増やすとRunningにはなるが状況は改善しない

    • Worker Nodeを増やしてPodを再配置すると、利用できるリソース量が増えて改善した
  13. 課題感 • 単一PodがNodeのリソースのほとんどを無条件に占有してしまっている ◦ 他のPodが起動できなくなる ◦ 同一のクラスタ内に名前空間が複数ある場合はそちらにも影響が出る ◦ kube-systemも例外ではない、Worker Node自体が機能しなくなる可能性

    • メモリが枯渇するとやばい、OOM Killerの可能性
  14. 対応案 • Pod(及びコンテナ)が利用するリソース量を指定及び制限を設ける ◦ Resource Requests ▪ Podが必要とするリソース量を指定できる ◦ Resource

    Limits ▪ Podが利用するリソースに制限を設けることができる ◦ Limits Range ▪ 名前空間単位で利用するリソースの最小 /最大値を指定できる • 設定するとPodのスケジューリング時にPendingになる場合がある ◦ PodはWorker Nodeの使用量は考慮せず Resource Requestsの値を見て起動される ◦ Node自体が落ちるよりまし、安全弁と考える ◦ 「Pending状態になっているPodの数」という指標で監視の基準とできる • 最適値はアプリケーションの特性によって異なる ◦ 負荷テストによる検証を ◦ 指定及び制限を設けながら単一 Podが性能要件を満たせるか否か
  15. 対応案2 • Pod及びWorker Nodeの数の調整 ◦ リソース状況に基づいて極力で自動で調整したい • HorizontalPodAutoscaler(HPA) ◦ Podの水平スケーリング

    ◦ Kubernetes自体の機能なのでGKE以外でも利用可 • MultidimPodAutoscaler(MPA) ◦ GKEの独自機能 ◦ CPU使用率による水平スケーリングとメモリ使用率による垂直スケーリング ◦ HPA / VPAの併用 • ClusterAutoscaler(CA) ◦ Worker Nodeの増減ができる
  16. まとめ • 運用していると様々なトラブルシューティングをすることになる • 今回のその中の一部分を疑似的に再現してみた • 以下のサイトが非常に参考になる ◦ https://learnk8s.io/troubleshooting-deployments

  17. 終わり