以下イベントの発表資料です。 https://rook.connpass.com/event/202147/
プロダクション向けRook/Cephクラスタ構築への道Japan Rook Meetup #5Cybozu, Inc. Neco ProjectSatoru TakeuchiTwitter: satoru_takeuchi1
View Slide
目次1. CephとRookの基礎2. サイボウズのインフラ基盤とストレージ基盤3. プロダクション向けRook/Cephクラスタの構成4. 現状と今後2
Rook/Cephの基礎3
Cephとは▌オープンソースの分散ストレージ▌提供するストレージ⚫RBD: ブロックデバイス⚫RGW: S3互換オブジェクトストレージ⚫CephFS: ファイルシステム▌ユーザ⚫大きなところだとNASA, CERNなど4
アーキテクチャ5アプリRADOS(Ceph独自のオブジェクトストレージ)Cephnode node node…RBD RGWブロックデバイス オブジェクトブロックデバイスブロックデバイス オブジェクトS3互換オブジェクトアプリアプリpool pool
Cephを構成するデーモン▌Monitor(MON)⚫Cephクラスタに対する全処理の整合性を保つ⚫通常システムに奇数個、通常3つ以上存在▌Manager(MGR)⚫機能拡張のためのモジュールの管理⚫通常システムに1つ存在▌Object Storage Daemon(OSD)⚫データストアを管理⚫OSDへのI/O、OSDの相互生存監視を担当6
Object Storage Daemon(OSD)▌Cephがストレージデバイスを管理する単位⚫ OSDをあらわすデータ構造もOSDを管理するデーモン(後述)も両方OSDと呼ぶ▌1つのデバイスに1つ以上のOSDを作れる⚫ HDDは通常1つ、NVMe SSDは通常2以上7RADOSnodeHDDnodeNVMe SSDOSD OSD OSD
データの均等分散配置(例えばラック間分散)8rack1rack0rack1rack0node0 node1 node2 node3OSDOSDOSDOSDOSDOSDOSDOSDCephクライアント(RBD, RGW)データ CRUSHによるデータの均等分散配置Ceph管理者によるOSDの均等分散配置
用語説明▌CRUSHアルゴリズム⚫データのOSDへの分散配置方法を決める⚫各オブジェクトのレプリカを全OSDになるべくランダムに配置▌CRUSH map⚫クラスタを構成するハードウェアの物理的な構成を記述⚫ラックやノード、OSDの関係を示すツリー構造⚫Failure domainを設定可能9
CRUSH mapの例▌2rack,2node per 1rack,2osd per 1nodeの例10nodeOSD OSDracknodeOSD OSDnodeOSD OSDracknodeOSD OSDroot
Rookとは▌K8sで動くCephのオーケストレータ⚫CassandraやNFSなども管理できる▌CephClusterというCRでクラスタを管理▌MON,MGR,OSDごとにPodが1つ存在(以下はOSD pod)11ブロックデバイスOSD PodOSD
• Host-basedクラスタ• ハード構成を直接CRに書く• 大規模になると管理が困難• PVC-basedクラスタ(サイボウズはこちら)• CRに書くのはOSDを作るPVのVolumeClaimTemplates• ボリュームの作成/配置はK8sとCSIドライバの責任• countフィールドを増やすとOSD(Pod)が増える• 規模にかかわらず構築後の拡張は楽storage:nodes:- name: foodevices:- sdb- sdc- name: bar…122種類のRook/Cephクラスタstorage:…count: 3volumeClaimTemplates:- spec:resources:requests:storage: 10GistorageClassName: my-class
RBDの使い方(1/2)13apiVersion: ceph.rook.io/v1kind: CephBlockPoolmetadata:name: ceph-block-poolnamespace: rook-cephspec:replicated: size: 3apiVersion: storage.k8s.io/v1kind: StorageClassmetadata:name: ceph-blockprovisioner: ceph-ssd.rbd.csi.ceph.comparameters:clusterID: ceph-ssdpool: ceph-ssd-block-pool2. 管理者がストレージクラスを定義1. 管理者がPoolを定義
RBDの使い方(2/2)143. ユーザがPVCを作るapiVersion: v1kind: PersistentVolumemetadata:name: myclaimspec:storageClassName: ceph-block4. PodからPVCを使うapiVersion: v1kind: Podmetadata:name: mypodspec:containers:- name: fooimage: foovolumeMounts:- mountPath: "/mnt"name: myvolumevolumes:- name: myvolumepersistentVolumeClaim:claimName: myclaim
RGWの使い方(1/2)151. 管理者がオブジェクトストレージを作るapiVersion: ceph.rook.io/v1kind: CephObjectStoremetadata:name: ceph-object-storenamespace: rook-cephspec:dataPool:replicated:size: 3apiVersion: storage.k8s.io/v1kind: StorageClassmetadata:name: ceph-bucketprovisioner: ceph-hdd.ceph.rook.io/bucketparameters:objectStoreName: ceph-object-storeobjectStoreNamespace: rook-ceph2. 管理者がストレージクラスを作る
RGWの使い方(2/2)163. ユーザがbucketを作るkind: ObjectBucketClaimmetadata:name: test-object-bucketnamespace: defaultspec:generateBucketName: test-object-bucketstorageClassName: ceph-bucketkind: Podmetadata:name: app-podspec:containers:- name: fooimage: barenvFrom:- configMapRef:name: test-object-bucket- secretRef:name: test-object-bucket4. ユーザが使うbucketへのアクセス方法が下記ConfigMapとSecretsに入っている
サイボウズのインフラ基盤とストレージ基盤17
インフラ基盤のハードウェア構成▌2種のサーバを詰めたラックを並べる18rackCSSSSSSSrackCSCSCSSSrackCSCSSSSS…CSSS• Computing Server• 全サービスが使う• ストレージはNVMe SSD• Storage Server• Ceph専用• ストレージはHDD
特徴▌ソフトウェアマルチテナンシー⚫Cephもアプリも同じK8sクラスタ上で動く▌ラック障害耐性⚫運用継続⚫データロスト無し19
必要なストレージ▌高速ローカルブロックストレージ⚫ 顧客データを扱うMySQLなど▌中速&スケーラブルなブロックストレージ⚫ ファイルシステムを前提としたアプリのデータなど▌大容量&スケーラブルなブロックストレージ⚫ メトリクスやログ▌大容量&スケーラブルなオブジェクトストレージ⚫ 添付ファイルなど20
ストレージ基盤の構成21K8sクラスタRook/CephクラスタA Rook/CephクラスタBRGW RBD RBDHDDSS CSSSDHDDHDDSSDSSDLogicalVolume LogicalVolumeLogicalVolumeLogicalVolume LogicalVolumeLogicalVolume TopoLVMが管理ローカルストレージ
全体構成のイメージ22K8sクラスタ リモートK8sクラスタ* 左図と同様の構成レプリケーションVictoriaMetrics& LokiRook/CephクラスタA Rook/CephクラスタBPod Pod PodRGW RBD RBDメトリクス& ログHDDSSCSSSDHDDHDD SSDSSDLogicalVolume LogicalVolumeLogicalVolumeLogicalVolume LogicalVolumeLogicalVolumePod
プロダクション向けRook/Cephクラスタの構成23
NVMe SSD Cephクラスタの設定▌OSD用のブロックデバイスは自社製CSIドライバTopoLVMから切り出す⚫ TopoLVMはDynamic provisioningをサポート⚫ OSDの数を増やすときに対応するPVが自動的に作られる24storage:…count: 20volumeClaimTemplates:- spec:resources:requests:storage: 1TistorageClassName: topolvm-provisionerCephCluster CRより抜粋
HDD Cephクラスタの設定▌OSD用のブロックデバイスは自社製ツールで自動生成⚫ KubernetesクラスタにSSを組み込むと自動的にHDD用のPVを作成▌管理者はPVのprovisioningを気にしなくてよい25storage:…count: 20volumeClaimTemplates:- spec:resources:requests:storage: 1TistorageClassName: local-storageCephCluster CRより抜粋
Cephコマンド実行ツールのdeploy▌Rookが提供するtoolbox Pod⚫ソースのcluster/example/Kubernetes/ceph/toolbox.yamlにある⚫両方のクラスタにdeploy▌使い方⚫kubectl apply –f toolbox.yaml⚫kubectl –n rook-ceph exec rook-ceph-tool-XXX –- ceph status▌使いどころ⚫CRの記述では実現できない一部オペレーション⚫デバッグ26
ラック間のデータの均等分散配置27rack1rack0rack1rack0node0 node1 node2 node3OSDOSDOSDOSDOSDOSDOSDOSDCephクライアント(RBD, RGW)データCRUSHによるデータの均等分散配置RookRookによるOSD Podの均等分散配置
CRUSHによるデータの均等分散配置▌プールのfailureDomainフィールドを設定⚫CRUSH ruleはRookが自動生成28apiVersion: ceph.rook.io/v1kind: CephBlockPoolmetadata:name: ceph-ssd-block-poolnamespace: ceph-ssdspec:failureDomain: zonereplicated: size: 3apiVersion: ceph.rook.io/v1kind: CephObjectStoremetadata:name: ceph-hdd-object-storenamespace: ceph-hddspec:dataPool:failureDomain: zonereplicated:size: 3apiVersion: ceph.rook.io/v1kind: CephBlockPoolmetadata:name: ceph-hdd-block-poolnamespace: ceph-hddspec:failureDomain: zonereplicated: size: 3SSD CephのRBDのpool HDD CephのRBDのpoolHDD Cephのオブジェクトストア
OSDの均等分散配置▌課題⚫KubernetesのPodはどのノードにスケジュールされるかわからない⚫ OSD Podも例外ではない⚫特定ノードにOSDの配置が偏ると困る▌解決方法⚫K8sのTopologySpreadConstraints(TSC)機能⚫K8sのScheduling profile機能29
OSD Podのスケジューリング with TSC30rack0node0OSDOSDnode1OSDOSDrack1node2OSDOSDnode3OSD新規OSD Pod 1. rack0のOSD数 > rack1のOSD数→rack1上のノードにスケジュール2. node2のOSD数 > node3のOSD数→node3にスケジュール
TSCの設定例31apiVersion: v1kind: Podmetadata:name: mypodspec:topologySpreadConstraints:- maxSkew: 1topologyKey: topology.Kubernetes.io/zonelabelSelector:…ドメイン間で許容されるPod数の差Pod数の均衡をすべきドメイン対象となるPodを選択
課題: TSCとStatefulアプリの相性が悪い▌システムの運用中にハード構成は大きく変わりうる⚫ ラック/ノード/デバイスの追加/削除/故障▌ローカルストレージを使うPodは別ノードに移動できない▌デフォルトではmaxSkewより大きな差があるとOSD Podが増やせない32
問題になるケースの例33node0 node1disk0disk1disk2disk0disk1disk2node0 node1disk0disk1disk2disk0disk1disk2OSDOSDOSDOSDOSDOSDOSD時間経過node0 node1disk0disk1disk2disk0disk1disk2node2disk0disk1disk2OSDNode2を追加node0 node1disk0disk1disk2disk0disk1disk2node2disk0disk1disk2OSDこのディスク用のOSDはデフォルトではTSCの制約により作れない追加ディスク用OSDの作成OSDOSD
対策: TSCの制約の緩和▌TSCのwhenUnsatisfiableフィールドの変更⚫dontSchedule(デフォルト): 制約を満たせる時のみスケジュール⚫scheduleAnyway: 制約を満たせなくてもスケジュール⚫ Podの分散具合についてはスケジューラのスコアに影響▌参考: maxSkewの値を2以上にする対策は困難⚫小さすぎる: 場合によっては結局OSD Podが作れない⚫大きすぎる: 設定する意味がない34
さらなる課題▌TSCのwhenUnsatisfiableフィールドの変更⚫dontSchedule(デフォルト): 制約を満たせる時のみスケジュール⚫scheduleAnyway: 制約を満たせなくてもスケジュール⚫ Podの分散具合についてはスケジューラのスコアに影響35ノードのスコアリングにおけるPodの分散具合のweightがほとんどゼロなので、事実上無視される
解決方法: スケジューラの設定変更▌scheduling profile機能を使用(k8s v1.18~)⚫アプリごとにスケジューラの設定をprofileとして作れる▌Profileごとにpodの分散具合のweightを高められる▌サイボウズではデフォルトスケジューラの設定を変更⚫他のアプリでもTSCは有用36
Default scheduling profileの変更37profiles:- schedulerName: default-schedulerplugins:score:…enabled:- name: PodTopologySpreadweight: 500pluginConfig:- name: PodTopologySpreadargs:defaultConstraints:- maxSkew: 1topologyKey: topology.kubernetes.io/zonewhenUnsatisfiable: ScheduleAnywayweightを大きくするデフォルトTSCラック間でPod分散配置* サイボウズのK8sクラスタではzoneがrackに対応
CephClusterのCRにOSD Pod用TSC設定▌rack間でOSDを均等分散+host間でも均等分散38storage:…placement:topologySpreadConstraints:- maxSkew: 1topologyKey: topology.kubernetes.io/zonewhenUnsatisfiable: ScheduleAnywaylabelSelector:matchExpressions:- key: appoperator: Invalues:- rook-ceph-osd- rook-ceph-osd-prepare……- maxSkew: 1topologyKey: kubernetes.io/hostnamewhenUnsatisfiable: ScheduleAnywaylabelSelector:matchExpressions:- key: appoperator: Invalues:- rook-ceph-osd- rook-ceph-osd-prepare
現状と今後39
最終的な全体構成のイメージ(再載)40K8sクラスタ リモートK8sクラスタ* 左図と同様の構成レプリケーションVictoriaMetrics& LokiRook/CephクラスタA Rook/CephクラスタBPod Pod PodRGW RBD RBDメトリクス& ログHDDSSCSSSDHDDHDD SSDSSDLogicalVolume LogicalVolumeLogicalVolumeLogicalVolume LogicalVolumeLogicalVolumePod
進捗▌基本的な機能検証は完了⚫既に説明した諸機能⚫OSD破壊からの復旧⚫MON quorumの回復▌インフラ基盤の監視、ログのストレージとして使用中▌ユーザデータは性能を気にしないものなら置いていい41
現状の構成42K8sクラスタリモートレプリケーションVictoriaMetrics& LokiRook/CephクラスタA Rook/CephクラスタBPod Pod PodRGW RBD RBDメトリクス& ログHDDSS CSSSDLogicalVolume LogicalVolumeLogicalVolumeLogicalVolume LogicalVolumeLogicalVolumePod現行インフラ リモートK8sクラスタ* 左図と同様の構成
基本的な運用はとにかく楽▌クラスタの作成: CephCluster CRをapplyするだけ▌クラスタの拡張: 前述のcountフィールドの値を増やすだけ1. countフィールド値の変化をRookが検知、OSD用のPVCを作る2. 上記ボリューム上にOSDを作成してクラスタに組み込む▌故障したOSDの退役: ほぼ自動化するジョブあり▌ユーザはインフラがCephかどうかは気にしなくていい⚫ 単に通常通りストレージクラスを指定してPVCを作るだけ43
今後1. 性能検証&可用性を高める2. 追加構成⚫リモートレプリケーション⚫スナップショット、バックアップ/リストア⚫RGWの使用方法をKubernetes公式のCOSIに移行⚫ 現在は事実上Rook独自のインタフェース3. 全データを(徐々に)移行44
参考▌サイボウズのRook関連のマニフェスト⚫ https://github.com/cybozu-go/neco-apps/tree/main/rook▌Production-grade Deployment of PVC-based Rook/Ceph Cluster⚫ https://blog.kintone.io/entry/2020/09/18/175030▌賢く「散らす」ためのTopology Spread Constraints⚫ https://speakerdeck.com/ytaka23/kubernetes-meetup-tokyo-25th▌Scheduling Profileが実現するPod配置戦略の最前線⚫ https://speakerdeck.com/ytaka23/infra-study-meetup-2nd▌Capacity-aware Dynamic Volume Provisioning For LVM Local Storage⚫ https://static.sched.com/hosted_files/kccnceu20/a4/kubecon-eu2020_topolvm.pdf45
46Thank you! Any question?