Slide 1

Slide 1 text

KubernetesでCephクラスタ用のストレージをどう管理するか 分割と配置の最適化への取り組み サイボウズ株式会社 森本健司 1

Slide 2

Slide 2 text

自己紹介 ▌森本健司 ⚫github.com: morimoto-cybozu ▌cybozu.comのインフラ開発・運用を8年間担当 ▌インフラ刷新プロジェクトでKubernetesと出会う ⚫手作業のない世界を目指す 2

Slide 3

Slide 3 text

今日紹介する内容 ▌LVMで動的にボリュームを作成するTopoLVM ⚫サイボウズ製のOSS ▌ボリュームを最適に分散配置する各種の工夫 ⚫PodTopologySpreadConstraints ⚫kube-schedulerのチューニング 3

Slide 4

Slide 4 text

Cephの紹介 ▌OSSの分散ストレージシステム ⚫スケーラブルで耐障害性をほぼ自動で確保 ▌意識して分散させるべき構成要素 ⚫Monitor (Paxosで分散合意) ⚫Object Storage Device (OSD) 4

Slide 5

Slide 5 text

5 ラック1 サーバ ラック2 ラック3 Mon Mon Mon Monitorの配置は anti-affinityでOK!

Slide 6

Slide 6 text

Rookの紹介 ▌Kubernetes上でCephを自動運用 ▌機能例 ⚫Cephクラスタを宣言どおりに構築 ⚫CephクラスタからS3互換のバケットを作成 6

Slide 7

Slide 7 text

解決したい課題 ▌LVMで柔軟にボリュームを作成したい ⚫Ceph以外に、MySQL等でも使いたいため ▌OSDボリュームを分散配置したい ⚫攪乱要因がいろいろあるが、負けずに! ⚫例:HDD数台の故障、LVM VGの容量差、ラック間 の機材台数の差、... 7

Slide 8

Slide 8 text

8 SSD LV SSD LV SSD LV LV MySQLに利用 LVMで柔軟にボリュームを作成したい

Slide 9

Slide 9 text

デバイスをLVMで切り出す ▌k8sのストレージドライバTopoLVMを開発 ⚫PersistentVolumeClaimに対して、各ノードの空き 容量を考慮しつつLVを切り出してPVとして渡す ▌Rookの「OSD on PVC」方式でストレージを指定 ⚫OSD Pod作成時にPVCでOSDを要求 ▌この組み合わせで、宣言的にSSDを分割・統合 9

Slide 10

Slide 10 text

10 CephCluster YAML SSD

Slide 11

Slide 11 text

OSD 11 CephCluster YAML SSD 「このノードのこのデバイス」 ではなく 「このStorageClassで デバイスを確保」 という指定

Slide 12

Slide 12 text

OSD 12 CephCluster YAML TopoLVM SSD LV 宣言に基づき LVを動的に確保

Slide 13

Slide 13 text

OSD 13 CephCluster YAML TopoLVM SSD LV 宣言に基づき LVを動的に確保

Slide 14

Slide 14 text

14 ラック1 zone: rack1 host: r1-s1 ラック2 ラック3 OSD zone: rack1 host: r1-s2 zone: rack2 host: r2-s1 zone: rack2 host: r2-s2 zone: rack3 host: r3-s1 zone: rack3 host: r3-s2 OSD OSD OSD OSD OSD OSD OSD OSDボリュームを分散配置したい

Slide 15

Slide 15 text

PVの配置問題をPodの配置問題に置換 ▌k8sはPVの配置を直接は管理しない ▌PVの配置をPodのスケジューリングに置き換える ⚫Podが使うPVCのStorageClassで volumeBindingMode: WaitForFirstConsumer ⚫まずPodのスケジューリング ⚫Pod/Nodeが決まったらそれに適したPVをbind 15

Slide 16

Slide 16 text

16 CephCluster YAML SSD

Slide 17

Slide 17 text

OSD 17 CephCluster YAML SSD Podがスケジュールされるまでは PVを割り当てなくていいよ

Slide 18

Slide 18 text

OSD 18 CephCluster YAML SSD affinity, anti-affinityや リソースキャパシティの観点から Podをスケジューリング

Slide 19

Slide 19 text

OSD 19 CephCluster YAML TopoLVM SSD LV 「どのノードのストレージを使うか」問題を 「どのノードにPodを置くか」問題で解決

Slide 20

Slide 20 text

OSD 20 CephCluster YAML TopoLVM SSD LV 「どのノードのストレージを使うか」問題を 「どのノードにPodを置くか」問題で解決

Slide 21

Slide 21 text

OSD Podを分散配置したい ▌anti-affinityでは表現できない ⚫1ホストに複数のOSDを配置するので ▌pod topology spread constraintsを使う ⚫k8s 1.18でbetaとなった新しめの機能 ⚫ホスト単位/ラック単位/...でpod数の差を maxSkew以下に抑える 21

Slide 22

Slide 22 text

topologySpreadConstraints ▌whenUnsatisfiable: DoNotSchedule (デフォ) ⚫まったく均等な機材構成が必須になる ⚫例えばあるノードでMySQLのためにVGを使い果たし ていて、maxSkewを満たせない → Pod作成エラー ▌whenUnsatisfiable: ScheduleAnyway ⚫skewを最小に抑えつつ配置続行……のはずだが? 22

Slide 23

Slide 23 text

whenUnsatisfiable: ScheduleAnyway ▌想定: まずskew条件を満たすよう配置を試みる、駄 目なら優先度を下げる ▌→ 実際に配置してみた 23

Slide 24

Slide 24 text

24 ラック1 zone: rack1 host: r1-s1 ラック2 ラック3 zone: rack1 host: r1-s2 zone: rack2 host: r2-s1 zone: rack2 host: r2-s2 zone: rack3 host: r3-s1 zone: rack3 host: r3-s2 skewは満たせるはずなのに…… Pod Pod Pod Pod Pod Pod Pod Pod Pod やや重いPodだが resourceには余裕あり

Slide 25

Slide 25 text

25 ラック1 zone: rack1 host: r1-s1 ラック2 ラック3 zone: rack1 host: r1-s2 zone: rack2 host: r2-s1 zone: rack2 host: r2-s2 zone: rack3 host: r3-s1 zone: rack3 host: r3-s2 OSD OSD OSD OSD OSD OSD OSD skewは満たせるはずなのに…… Pod OSD まるでspreadしていない! Pod Pod Pod Pod Pod Pod Pod Pod

Slide 26

Slide 26 text

whenUnsatisfiable: ScheduleAnyway ▌想定: まずskew条件を満たすよう配置を試みる、駄 目なら優先度を下げる ▌実際: 満たすかどうか試みず、単にskew条件をスコアリ ングの数ある条件の一つにしてしまう ▌メンテナに確認、「実際の動作が仕様」 ⚫whenUnsatisfiableを文字どおりに受け取ってはい けない! 26

Slide 27

Slide 27 text

kube-schedulerをチューニング ▌skew条件のweightを大きくしてやればいい ⚫1.17: scheduling policy (全体で1つ)を調整 ⚫EvenPodsSpreadPriorityのweightを500に ⚫1.18+: scheduling profile (複数可)を調整 ⚫1.18: PodTopologySpreadのweightを500に ⚫1.19: NodeResourcesBalancedAllocation無効化 27

Slide 28

Slide 28 text

kube-schedulerをチューニング 1.18設定 28 apiVersion: kubescheduler.config.k8s.io/v1alpha2 kind: KubeSchedulerConfiguration leaderElection: leaderElect: true clientConnection: kubeconfig: /etc/kubernetes/scheduler.conf profiles: - schedulerName: default-scheduler plugins: score: disabled: - name: PodTopologySpread enabled: - name: PodTopologySpread weight: 500

Slide 29

Slide 29 text

サイボウズが追加したRookの機能 ▌元々はPodの配置の指示が貧弱だった ▌Monitor PodのpodAntiAffinity対応の修正 ▌OSD PodのtopologySpreadConstraints対応 ▌OSD podのschedulerName指定対応 29

Slide 30

Slide 30 text

まとめ ▌TopoLVMで動的にストレージを分割した ▌OSDボリュームを最適に分散配置した ⚫Topology spread constraintsを活用 ⚫攪乱要因に対しkube-schedulerをチューニング ⚫→ Cephに限らずPodの分散配置に有効な知見 30