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

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

nezumisannn
November 18, 2021

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

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 株式会社ビヨンド 寺岡 佑樹

    View Slide

  2. 自己紹介
    resource “my_profile” “nezumisannn” {
    name = “Yuki.Teraoka”
    nickname = “ねずみさん家。”
    company = “beyond Co., Ltd.”
    job = “Infra Engineer”
    twitter = “@yktr_sre”
    skills = [“Terraform”,”Packer”]
    }

    View Slide

  3. 前提
    ● 疑似的なリクエストを生成する
    ● 最初は最小スペック/設定で構築する
    ● 負荷が上昇する度に原因を調査
    ○ Clusterの状態の確認と改善に向けた対応案を検討する
    ● Apache Benchを利用する
    ○ ab -n -c

    View Slide

  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)

    View Slide

  5. マニフェスト
    ● Namespace
    ○ 本番環境を想定
    ● Deployment
    ○ コンテナ
    ■ Nginx
    ■ PHP
    ○ アプリケーションフレームワーク
    ■ Laravel
    ● Service
    ○ NodePortでNginxの80番ポートを公開
    ● Ingress
    ○ CloudLBを利用してserviceを外部公開

    View Slide

  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
    ```

    View Slide

  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
    ```

    View Slide

  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の数を手動で増やしてみる

    View Slide

  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
    ```

    View Slide

  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
    ```

    View Slide

  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
    ```

    View Slide

  12. ここまでの整理
    ● 単一PodでもWorker Nodeのリソースが枯渇しない限りは応答遅延が出なかった
    ● Worker Nodeのリソースが枯渇すると当然ながら
    Podが起動していても障害状態になる
    ● この状態でPodの数を増やすとRunningにはなるが状況は改善しない
    ● Worker Nodeを増やしてPodを再配置すると、利用できるリソース量が増えて改善した

    View Slide

  13. 課題感
    ● 単一PodがNodeのリソースのほとんどを無条件に占有してしまっている
    ○ 他のPodが起動できなくなる
    ○ 同一のクラスタ内に名前空間が複数ある場合はそちらにも影響が出る
    ○ kube-systemも例外ではない、Worker Node自体が機能しなくなる可能性
    ● メモリが枯渇するとやばい、OOM Killerの可能性

    View Slide

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

    View Slide

  15. 対応案2
    ● Pod及びWorker Nodeの数の調整
    ○ リソース状況に基づいて極力で自動で調整したい
    ● HorizontalPodAutoscaler(HPA)
    ○ Podの水平スケーリング
    ○ Kubernetes自体の機能なのでGKE以外でも利用可
    ● MultidimPodAutoscaler(MPA)
    ○ GKEの独自機能
    ○ CPU使用率による水平スケーリングとメモリ使用率による垂直スケーリング
    ○ HPA / VPAの併用
    ● ClusterAutoscaler(CA)
    ○ Worker Nodeの増減ができる

    View Slide

  16. まとめ
    ● 運用していると様々なトラブルシューティングをすることになる
    ● 今回のその中の一部分を疑似的に再現してみた
    ● 以下のサイトが非常に参考になる
    ○ https://learnk8s.io/troubleshooting-deployments

    View Slide

  17. 終わり

    View Slide