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

Podの分散配置戦略とその運用事例

 Podの分散配置戦略とその運用事例

Kubernetes Novice Tokyo #22 2022/11/15 発表資料
https://k8s-novice-jp.connpass.com/event/262918/

Kiyoshi Muranaka

November 15, 2022
Tweet

More Decks by Kiyoshi Muranaka

Other Decks in Technology

Transcript

  1. • LINE株式会社 • AI カンパニー AI 開発⽀援チーム • Embedded SRE

    としてプロダクト開発チームと共に プロダクトの信頼性向上や開発/運⽤効率化等を推進 Who am I ? 村中 清史 Muranaka Kiyoshi (@kiyoshim55)
  2. Agenda • Pod を分散配置する⽬的と設定⽅法 • マニフェストの設定内容 (各種フィールド) については要点のみを紹介 • Pod

    を分散配置する上で直⾯した課題、運⽤⾯での⼯夫点 • まとめ !"#$%&'()*&+,-.*/01)23456789:;<='>?@
  3. • コンテナ化したアプリケーションを Kubernetes 上で実⾏するときに、 コンテナアプリケーションの可⽤性を⾼めたい • 複数台実⾏可能であれば、コンテナ (Pod) を複数作成して冗⻑化すれば OK?

    • 例えば Deployment としてデプロイすれば Pod を複製してくれるし、 設定次第で Pod のヘルスチェックやオートヒーリングも可能 !"#$%& !"#$%' !"#$%( !""#$ !""#$ )**%+%,-$*./0)12%'3 451 6"7/0$%8'' 9:%;<=>?@ AB ⽬的
  4. ⽬的 • Pod を複数台起動した場合、どこに配置されるかは状況次第・Scheduling の結果次第 • 特定の Node や Availability

    Zone に偏ってしまうことがある • レプリカ数を増やせばすべての Pod が偏って配置される可能性は低くなる (とはいえ想定しているよりも多くの Pod が停⽌する可能性はある) • Pod を分散配置して、障害や運⽤作業による影響をできるだけ⼩さくしたい! !"#$%& !"#$%' !"#$%( !""#$ !""#$ )**%+%,-$*./0)12%'3 AB )**%C%,-$*./0)12%'3 !""#% !""#% !"#$%(%DEFGHIJKLM )**%C%NOPN Q"#%DEFGH
  5. Pod 分散配置設定 • Pod を Topology Domain *1 の単位で分散配置するために使⽤できる機能・設定 •

    Inter-pod Anti-affinity • Pod Topology Spread Constraints *1. Topology Domain: ノード, ラック, Region, Availability Zone 等のことで、Node Label で区別される 本資料では、ノードを対象にして Pod を分散配置する例を挙げながら説明していく
  6. Inter-pod Anti-affinity ラベルセレクターで指定した ある特定の Pod が存在しない Topology Domain に配置する Anti-affinity

    ルール • Required (hard) • 条件を満たす場合のみノードに配置される • Preferred (soft) • ルールの重みをもとに Scoring して その結果が最も⾼いノードに配置 • 条件を満たさない場合でもいずれかの ノードに配置される apiVersion: apps/v1 kind: Deployment metadata: name: myapp spec: replicas: 5 ... template: metadata: labels: app.kubernetes.io/name: myapp spec: affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app.kubernetes.io/name operator: In values: - myapp topologyKey: kubernetes.io/hostname ... https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node
  7. Pod Topology Spread Constraints Topology Domain の間で Pod 数の差が maxSkew

    の値を超えないように 配置する Skew とは • Topology Domain 間での Pod 数の差のこと • Skew = 起動している Pod 数 ‒ Topology Domain 全体における最⼩起動 Pod 数 + 1 • Skew ≦ maxSkew であれば Pod を配置できる(Skew > maxSkew の場合配置できない) https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints !"#$%& !"#$%' !"#$%( RS)** ,-$*./0)12%TU%R)VWX$Y2%&3 WX$Y%%%%%%%%%%%%%%%&%Z &%[%&%\%&%%%%%%%&%Z &%[%&%\%&%%%%%%%'%Z &%[%&%\%' "-
  8. Pod Topology Spread Constraints Topology Domain の間で Pod 数の差が maxSkew

    の値を超えないように 配置する whenUnsatisfiable フィールド • DoNotSchedule (hard) • maxSkew の値を超える場合は配置しない • ScheduleAnyway (soft) • maxSkew の値を超える場合でも、 スケジューラーの Scoring の結果に 従っていずれかのノードに配置される https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints apiVersion: apps/v1 kind: Deployment metadata: name: myapp spec: replicas: 5 ... template: metadata: labels: app.kubernetes.io/name: myapp spec: topologySpreadConstraints: - maxSkew: 1 topologyKey: kubernetes.io/hostname whenUnsatisfiable: ScheduleAnyway labelSelector: matchLabels: app.kubernetes.io/name: myapp ...
  9. Pod 分散配置設定の⽐較 分散配置設定 確実な分散配置 1ノード上での 複数Pod起動 1ノードあたり 2台以上Podが起動する ときの分散配置 Inter-pod

    Anti-affinity Required ✓ ✗ (1ノードに1Podしか 起動できない) ✗ (そもそも1ノードに1Podしか 起動できない) Preferred ✗ (Scoring の結果によっては 分散しないことがある) ✓ ✗ (2台⽬以降は Scoring 結果次第) Pod Topology Spread Constraints DoNotSchedule ✓ ✓ (maxSkew を満たす限り) ✓ ScheduleAnyway ✗ (Scoring の結果によっては 分散しないことがある) ✓ ✓ ] ^_`abcdef • Inter-pod Anti-affinity は、その名の通り同⼀ Topology Domain で起動させたくない時に適する • 分散配置という⽬的に対しては、Pod Topology Spread Constraints が適している ] gfhNijkl
  10. 運⽤上の課題 • Pod Topology Spread Constraints (DoNotSchedule) を使⽤した場合、 Taints の影響で、ノードに

    Pod を配置できなくなる場合がある ※ デフォルトでは Taints が付与されたノードも配置先候補になることが原因 • Case 1. Control Plane ⽤に設定された Taints • Case 2. Upgrade 時に cordon / drain で設定された Taints !"#$%& !"#$%' RS)** ,-$*./0)12%(U%R)VWX$Y2%&3 WX$Y%%%%%%%%%%%%%%%m%Z m%[%&%\%&%%%%%%%&%Z m%[%&%\%'%%%%%%%&%Z m%[%&%\%' 6"#$Z-".$nXop$-6$q$1n/"r R)1q$-2%!"W0s$#o.$ ! Q$6#/6t 例: Case 1. u"6q-".%Q.)6$ v)1q$-%&
  11. 運⽤上の課題 • Node Upgrade 時のケースでは、PodDisruptionBudget の設定も考慮しないと Pod を配置できなくなる影響で drain の処理⾃体が停⽌してしまう可能性がある

    • 例: Deployment に maxSkew: 1、PodDisruptionBudget に maxUnavailable: 1 を設定 • 注意: drain の処理が停⽌しない場合も、Pod が⼀時的に起動できない状況は発⽣し得る !"#$%' !"#$%( RS)** ,-$*./0)12%wU%R)VWX$Y2%&3 WX$Y%%%%%%%%%%%%%%%&%Z &%[%&%\%&%%%%%%%'%Z &%[%&%\%'%%%%%%%'%Z &%[%&%\%' ! x7/0q$#U Q$6#/6t 6"#$nXop$-6$q$1n/"r o610s$#o.)p.$2!"W0s$#o.$ !"#$%& yz{M|}~P•€•I ‚*t-)#$Nƒ„DEFGH 例: Case 2.
  12. 運⽤上の課題 | 対策 1. nodeSelector や nodeAffinity を設定する • nodeSelector

    や nodeAffinity によって Filter されるノードはデフォルトで配置先候補から外れる • Node Upgrade 時にこの対策を実施するのは、各 Node ごとに設定変更する必要があり⼤変 2. topologySpreadConstraints.nodeTaintsPolicy を Honor に設定する • Taints によって Filter されるノードを配置先候補から外す設定 • K8s v1.25 で 追加された機能 [1] で alpha 段階のため当案件では採⽤困難、将来的には使⽤予定 3. 代わりに Pod Topology Spread Constraints (ScheduleAnyway) を使⽤する • Scoring の結果によっては分散しないことがあるが、k8s v1.19 以降は重みが調整されている [2] • ただし Pod が偏って配置される可能性はゼロではないため、最低限検知できるようにすべき [1] https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/#spread-constraint-definition [2] https://github.com/kubernetes/kubernetes/pull/91258 ! "#$%&'()*
  13. 運⽤上の課題 | 対策 • 対策案 3 で Pod Topology Spread

    Constraints (ScheduleAnyway) を使⽤した場合、 Pod が偏って配置される可能性があるため、その状況を検知できるようにする • Prometheus で収集しているメトリクス (kube-state-metrics が公開している kube_pod_info メトリクス) を使⽤して監視 • Alertmanager 等を使⽤すれば Slack やメール通知も可能 • Alert ルールの例 • created_by_name で対象の Pod を選択 (=~) or 対象外とする Pod を除外 (!=) • 何かしらの事情で replicas: 1 に設定されている場合は除外が必要 expr: count(count(kube_pod_info{created_by_kind="ReplicaSet", namespace="your-ns", created_ by_name=~"^target-app.*"}) by (created_by_name, node, namespace)) by (created_by_name) == 1
  14. 運⽤上の⼯夫点 CI パイプライン内でのマニフェストバリデーション • Pod Topology Spread Constraints の設定漏れや Label

    の設定ミスがあると分散配置されないため、 マニフェスト更新のプルリクエスト作成時に バリデーションを実⾏する • Rego ⾔語でルールを記述し、OPA/Conftest を 使⽤して Label の設定チェックを実⾏ package main deny[msg] { target_kind := ["Deployment", "StatefulSet", "Rollout"] input[i].contents.kind == target_kind[_] target := input[i].contents is_replicated(target) not match_topology_spread_constraints_selector(target) msg := sprintfPod is("Pods owned by %v ¥"%v¥" must be distributed to dif ferent nodes or availability zones with topologySpreadConstraints. Configure topologySpreadConstraints field to ensure that at least node-level failures do not impact availability. If a single Pod is enough, simply set replicas t o 1 so that this rule will be passed.", [target.kind, target.metadata.name]) } # Multiple is_replicated functions are processed as OR conditions. # ref. https://www.openpolicyagent.org/docs/latest/policy-language/#incremen tal-definitions is_replicated(target) { target.spec.replicas > 1 } # If replicas field is not present, it is assumed that the number of Pods # is replicated and controlled by HPA. is_replicated(target) { not target.spec.replicas } match_topology_spread_constraints_selector(target) { labels := target.spec.template.metadata.labels constraint := target.spec.template.spec.topologySpreadConstraints[i] object.subset(labels, constraint.labelSelector.matchLabels) } +,-./012 3435678 !
  15. Pod 分散配置設定をした結果 • Pod Topology Spread Constraints を設定した結果... • コンテナを冗⻑化

    & 分散配置することで可⽤性のレベルを向上できた • 障害や運⽤作業による影響をできるだけ⼩さくすることができた • 運⽤作業向けの設定に関しては、PodDisruptionBudget も適切に設定して ノードを drain した時に退避する Pod 数を制御するとよい [3] • ただし、これで完璧というわけではなく、まだ注意点があるため次スライドにて紹介 …†‡ˆ‰Šnn !"#$%& !"#$%' !"#$%( !""#$ !""#$ !""#% !""#& !""#& !""#% !""#& !""#& !""#& ‹Œ‡•B [3] https://kubernetes.io/docs/tasks/run-application/configure-pdb
  16. 注意点 • Pod Topology Spread Constraints は Pod のスケジューリング時に適⽤されるため、 すでに作成された

    Pod に関しては適⽤されず、多少 Pod が偏る可能性もある • 参考: https://github.com/kubernetes-sigs/descheduler • 複数台同時に Rolling Update を実施すると、新旧 Pod が混在して skew の計算結果が 適切なものにならず、更新完了後に Pod の数に偏りが発⽣する可能性がある • Pod の分散配置はコンテナアプリケーションを安定運⽤するための⼀つの要素に過ぎない ! "#$%&'()*+,- ./01234567*89:;<'6=>*?@<ABCDEFGH< IJGKLMNOPQR9STUVWQXYZ[\X
  17. まとめ • Pod を分散配置する⽬的と設定⽅法 • コンテナを冗⻑化 & 分散配置して可⽤性のレベルを向上 • Pod

    Topology Spread Constraints が便利 • Pod を分散配置する上で直⾯した課題、運⽤⾯での⼯夫点 • DoNotSchedule or ScheduleAnyway どちらを選択するかは検討が必要 (nodeTaintsPolicy に期待) • ScheduleAnyway の場合は念のため Pod の偏りを検知できるようにする • マニフェストに定義した分散設定は CI でバリデーションするとよい