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

賢く「散らす」ための Topology Spread Constraints #k8sjp / Kubernetes Meetup Tokyo 25th

y_taka_23
November 13, 2019

賢く「散らす」ための Topology Spread Constraints #k8sjp / Kubernetes Meetup Tokyo 25th

Kubernetes Meetup Tokyo #25 で使用したスライドです。

Kubernetes において、Pod を分散させる基本単位は Node です。しかし現実には複数の Node に Pod が分散している状況であっても、それらの Node が同じ Availability Zone やラックにホスティングされていた場合には、障害が原因で Pod が全滅しサービス停止に陥る可能性があります。

この問題を解決するため、Kubernetes v1.16 ではアルファ機能として Topology Spread が導入されました。この機能を有効にすると、Node に Label を付与することで故障ドメインを表現した論理的なグループを作成し、そのグループ単位での Pod の分散方法を指定することができます。

イベント概要:https://k8sjp.connpass.com/event/150873/
動画:https://www.youtube.com/watch?v=m4SpEzKN-RM&t=8138s

y_taka_23

November 13, 2019
Tweet

More Decks by y_taka_23

Other Decks in Technology

Transcript

  1. 賢く「散らす」ための
    Topology Spread Constraints
    チェシャ猫 (@y_taka_23)
    Kubernetes Meetup Tokyo #25 (2019/11/13)
    #k8sjp

    View Slide

  2. Scheduling = Pod の配置戦略
    #k8sjp

    View Slide

  3. 複数 Node への Pod の配置
    Node
    Pod Pod
    Node
    Pod Pod
    Node Node
    #k8sjp

    View Slide

  4. 複数 Node への Pod の配置
    Availability Zone A
    Node
    Pod Pod
    Node
    Pod Pod
    Availability Zone B
    Node Node
    #k8sjp

    View Slide

  5. Kubernetes の Topology
    ● Node を論理的にグルーピング
    ○ Label を付与することで表現
    ○ 運用上は「まとめて故障する単位」に対応
    ● Well-Known Labels も利用可能
    ○ Cloud Provider が自動で付与
    ○ failure-domain.beta.kubernetes.io/region
    ○ failure-domain.beta.kubernetes.io/zone
    #k8sjp

    View Slide

  6. Zone 間の Pod 分散
    Availability Zone A
    Node [zone=zoneA, node=node1]
    Pod Pod
    Node [zone=zoneA, node=node2]
    Availability Zone B
    Node [zone=zoneB, node=node3]
    Pod Pod
    Node [zone=zoneB, node=node4]
    #k8sjp

    View Slide

  7. Node 間の Pod 分散
    Availability Zone A
    Node [zone=zoneA, node=node1]
    Pod
    Node [zone=zoneA, node=node2]
    Availability Zone B
    Node [zone=zoneB, node=node3]
    Pod
    Node [zone=zoneB, node=node4]
    Pod
    Pod
    #k8sjp

    View Slide

  8. 既存の「散らす」機能
    ● DaemonSet
    ○ 全 Node に 1 Pod ずつ配置されてしまう
    ○ 大きなクラスタでは無駄が多すぎる
    ● Pod Anti Affinity
    ○ 自分自身と反発するような設定を記述
    ○ 各 Topology にちょうど 1 Pod しか配置できない
    ○ ローリングアップデートできない
    #k8sjp

    View Slide

  9. Topology Spread Constraints
    #k8sjp

    View Slide

  10. Topology Spread Constraints
    ● v1.16 で α 版機能として導入
    ○ 従来よりも「柔軟な単位」で分散が可能に
    ○ Feature Gate: EvenPodsSpread=true
    ● Topology 間で Pod を分散させる
    ○ 許容できる Pod 個数の差を指定
    ○ カウント対象となる Pod は Label で指定
    ○ 強制か、あくまでも優先に留めるかは選択可能
    #k8sjp

    View Slide

  11. Topology Spread Constraints
    kind: Pod
    apiVersion: v1
    metadata:
    name: mypod
    labels:
    foo: bar
    spec:
    constiners: ...
    topologySpreadConstraints:
    - topologyKey: zone
    maxSkew: 1
    labelSelector:
    matchLabels:
    foo: bar
    whenUnsatisfiable: DoNotSchedule
    #k8sjp

    View Slide

  12. Topology Spread Constraints
    kind: Pod
    apiVersion: v1
    metadata:
    name: mypod
    labels:
    foo: bar
    spec:
    constiners: ...
    topologySpreadConstraints:
    - topologyKey: zone
    maxSkew: 1
    labelSelector:
    matchLabels:
    foo: bar
    whenUnsatisfiable: DoNotSchedule
    Pod をカウントする単位
    #k8sjp

    View Slide

  13. Topology Spread Constraints
    kind: Pod
    apiVersion: v1
    metadata:
    name: mypod
    labels:
    foo: bar
    spec:
    constiners: ...
    topologySpreadConstraints:
    - topologyKey: zone
    maxSkew: 1
    labelSelector:
    matchLabels:
    foo: bar
    whenUnsatisfiable: DoNotSchedule
    許容する個数の差
    #k8sjp

    View Slide

  14. Topology Spread Constraints
    kind: Pod
    apiVersion: v1
    metadata:
    name: mypod
    labels:
    foo: bar
    spec:
    constiners: ...
    topologySpreadConstraints:
    - topologyKey: zone
    maxSkew: 1
    labelSelector:
    matchLabels:
    foo: bar
    whenUnsatisfiable: DoNotSchedule
    カウントする Pod の条件
    #k8sjp

    View Slide

  15. Topology Spread Constraints
    kind: Pod
    apiVersion: v1
    metadata:
    name: mypod
    labels:
    foo: bar
    spec:
    constiners: ...
    topologySpreadConstraints:
    - topologyKey: zone
    maxSkew: 1
    labelSelector:
    matchLabels:
    foo: bar
    whenUnsatisfiable: DoNotSchedule 合致しない場合は配置禁止
    #k8sjp

    View Slide

  16. Zone に対して maxSkew: 1
    Availability Zone A (2 Pods)
    Node [zone=zoneA, node=node1]
    Pod [foo=bar]
    Node [zone=zoneA, node=node2]
    Pod [foo=bar]
    Availability Zone B (1 Pods)
    Node [zone=zoneB, node=node3]
    Pod [foo=bar]
    Node [zone=zoneB, node=node4]
    #k8sjp

    View Slide

  17. Zone に対して maxSkew: 1
    Availability Zone A (2 Pods)
    Node [zone=zoneA, node=node1]
    Pod [foo=bar]
    Node [zone=zoneA, node=node2]
    Pod [foo=bar]
    Availability Zone B (2 Pods)
    Node [zone=zoneB, node=node3]
    Pod [foo=bar]
    Node [zone=zoneB, node=node4]
    Pod [foo=bar]
    #k8sjp

    View Slide

  18. Zone に対して maxSkew: 1
    Availability Zone A (2 Pods)
    Node [zone=zoneA, node=node1]
    Pod [foo=bar]
    Node [zone=zoneA, node=node2]
    Pod [foo=bar]
    Availability Zone B (2 Pods)
    Node [zone=zoneB, node=node3]
    Pod [foo=bar]
    Node [zone=zoneB, node=node4]
    Pod [foo=bar]
    #k8sjp

    View Slide

  19. 複数の Constraints を指定
    spec:
    topologySpreadConstraints:
    - topologyKey: zone
    maxSkew: 1
    labelSelector:
    matchLabels:
    foo: bar
    whenUnsatisfiable: DoNotSchedule
    - topologyKey: node
    maxSkew: 1
    labelSelector:
    matchLabels:
    foo: bar
    whenUnsatisfiable: DoNotSchedule
    #k8sjp

    View Slide

  20. 複数の Constraints を指定
    spec:
    topologySpreadConstraints:
    - topologyKey: zone
    maxSkew: 1
    labelSelector:
    matchLabels:
    foo: bar
    whenUnsatisfiable: DoNotSchedule
    - topologyKey: node
    maxSkew: 1
    labelSelector:
    matchLabels:
    foo: bar
    whenUnsatisfiable: DoNotSchedule
    Zone に対する分散
    #k8sjp

    View Slide

  21. 複数の Constraints を指定
    spec:
    topologySpreadConstraints:
    - topologyKey: zone
    maxSkew: 1
    labelSelector:
    matchLabels:
    foo: bar
    whenUnsatisfiable: DoNotSchedule
    - topologyKey: node
    maxSkew: 1
    labelSelector:
    matchLabels:
    foo: bar
    whenUnsatisfiable: DoNotSchedule
    Node に対する分散
    #k8sjp

    View Slide

  22. Zone & Node で maxSkew: 1
    Availability Zone A (3 Pods)
    Node [zone=zoneA, node=node1]
    Pod [foo=bar] Pod [foo=bar]
    Node [zone=zoneA, node=node2]
    Pod [foo=bar]
    Availability Zone B (2 Pods)
    Node [zone=zoneB, node=node3]
    Pod [foo=bar] Pod [foo=bar]
    #k8sjp

    View Slide

  23. Zone & Node で maxSkew: 1
    Availability Zone A (4 Pods)
    Node [zone=zoneA, node=node1]
    Pod [foo=bar] Pod [foo=bar]
    Node [zone=zoneA, node=node2]
    Pod [foo=bar]
    Availability Zone B (2 Pods)
    Node [zone=zoneB, node=node3]
    Pod [foo=bar] Pod [foo=bar]
    Pod [foo=bar]
    #k8sjp

    View Slide

  24. Zone & Node で maxSkew: 1
    Availability Zone A (3 Pods)
    Node [zone=zoneA, node=node1]
    Pod [foo=bar] Pod [foo=bar]
    Node [zone=zoneA, node=node2]
    Pod [foo=bar]
    Availability Zone B (3 Pods)
    Node [zone=zoneB, node=node3]
    Pod [foo=bar] Pod [foo=bar]
    Pod [foo=bar]
    #k8sjp

    View Slide

  25. 配置できる Node がない!
    #k8sjp

    View Slide

  26. 矛盾する Constraints の解消
    spec:
    topologySpreadConstraints:
    - topologyKey: zone
    maxSkew: 1
    labelSelector:
    matchLabels:
    foo: bar
    whenUnsatisfiable: ScheduleAnyway
    - topologyKey: node
    maxSkew: 1
    labelSelector:
    matchLabels:
    foo: bar
    whenUnsatisfiable: DoNotSchedule
    #k8sjp

    View Slide

  27. 矛盾する Constraints の解消
    spec:
    topologySpreadConstraints:
    - topologyKey: zone
    maxSkew: 1
    labelSelector:
    matchLabels:
    foo: bar
    whenUnsatisfiable: ScheduleAnyway
    - topologyKey: node
    maxSkew: 1
    labelSelector:
    matchLabels:
    foo: bar
    whenUnsatisfiable: DoNotSchedule
    合致しない場合は順位を下げる
    #k8sjp

    View Slide

  28. 矛盾する Constraints の解消
    spec:
    topologySpreadConstraints:
    - topologyKey: zone
    maxSkew: 2
    labelSelector:
    matchLabels:
    foo: bar
    whenUnsatisfiable: DoNotSchedule
    - topologyKey: node
    maxSkew: 1
    labelSelector:
    matchLabels:
    foo: bar
    whenUnsatisfiable: DoNotSchedule
    許容できる差の範囲を緩める
    #k8sjp

    View Slide

  29. Zone & Node で maxSkew: 2
    Availability Zone A (4 Pods)
    Node [zone=zoneA, node=node1]
    Pod [foo=bar] Pod [foo=bar]
    Node [zone=zoneA, node=node2]
    Pod [foo=bar]
    Availability Zone B (2 Pods)
    Node [zone=zoneB, node=node3]
    Pod [foo=bar] Pod [foo=bar]
    Pod [foo=bar]
    #k8sjp

    View Slide

  30. Zone & Node で maxSkew: 2
    Availability Zone A (4 Pods)
    Node [zone=zoneA, node=node1]
    Pod [foo=bar] Pod [foo=bar]
    Node [zone=zoneA, node=node2]
    Pod [foo=bar]
    Availability Zone B (3 Pods)
    Node [zone=zoneB, node=node3]
    Pod [foo=bar] Pod [foo=bar]
    Pod [foo=bar]
    Pod [foo=bar]
    #k8sjp

    View Slide

  31. まとめ
    ● Kubernetes の Topology
    ○ Node を論理的にグルーピング
    ● Topology Spread Constraint
    ○ Topology に対して「散らす」設定が可能に
    ○ Topology ごと障害が起きた際の可用性が向上
    ● 運用上の注意点
    ○ DoNotScheduler はうっかりデッドロックを招く
    #k8sjp

    View Slide

  32. 【PR】Scheduling 徹底解説
    https://speakerdeck.com/ytaka23/cloudnative-days-tokyo-2019
    #k8sjp

    View Slide

  33. More Spreading, More Reliable!
    Presented by チェシャ猫 (@y_taka_23)
    #k8sjp

    View Slide