はじめに
Rookは「Cloud Native Storage for Kubernetes」を実現するために開発されているストレージオーケストレーターです。先日最新バージョンであるver 1.1が公開されましたが、その中でも特に注目された機能である「PVC-Based Cluster」について紹介したいと思います。
Cloud Native Storageとは
KubernetesはVolume Pluginを利用してストレージを抽象的に扱い、Kubernetes上のアプリケーションに対してストレージを提供します。しかしKubernetesでストレージを利用する際の課題も存在し、それはKubernetesが云々というよりもストレージ自体の抱える課題です。
例えばオンプレミスのストレージを利用する場合、可搬性や拡張性に制限のある場合があります。またストレージを管理者が管理・維持する必要もあり、デプロイする際の手間も発生します。
クラウドを利用すれば、上記課題をある程度は解決することができますが、ベンダーロックイン(他ベンダーへの切り替え時に発生する金額的・技術的コスト)の問題が発生します。
またオンプレミス・クラウド双方で問題となるのが運用です。監視・メンテナンス・トラブルシューティングなどを日々行い、必要に応じてパッチのリリースも行います。このような運用の課題は、その過程が単純であれ複雑であれ、シンプルに管理するべきものです。
※KubeCon+CloudNativeCon NA 2019 スライドより(動画リンク)
Cloud Native Storageとは、Cloud Nativeな世界を実現するために、ストレージとしてどのような姿であるべきか、を定義したようなものです。StorageOSの公開する記事では、以下のようなポイントを挙げています。
- アプリケーション中心:ホストOSとストレージは疎結合であるべきであり、ストレージがアプリケーションを追従する。
- プラットフォームに依存しない:特定のプラットフォームなどに依存せず、アプリケーションの要求に応じてスケーリングする。
- 宣言的構成:ストレージは宣言的リソースとして管理され、アプリケーションと合わせてデプロイされる。
- APIドリブン・自己管理:API経由で管理・操作され、オーケストレーターと統合して利用される
- アジャイル:ストレージは環境の変化に応じて動的に変化し、アプリケーソンの移動・要求するストレージサイズの変化に対応する。
- 初期段階からセキュアに利用できる:暗号化・RBACを利用し、別製品を利用せずにセキュアな環境を構築する。
- 効率的:分散環境において期待される性能要求を満たし、最小限のリソースで効率的にスケールする。
- 常に利用可能:高可用性・耐久性・データの一貫性を保証し、アプリケーションと独立してデータ損失から回復する。
Rookとは
Rookとは、上に挙げたCloud Native Storageな世界を実現するために開発されたソフトウェアの一つと言って良いと思います。RookはCloud Native Storage for Kubernetesと打ち出しており、Kubernetesの機能を利用し、多様なストレージサービスをCloud Nativeな環境に統合する、ストレージオーケストレーションツールになります。CNCFではIncubating Projectとして登録されています。
開発当初はCephをベースにCloud Native向けにデザインされた分散ストレージシステムと紹介されていたり、Rookの開発者の多くはCephのコントリビューターも含まれていたりと、Cephとの関連性が強いソフトウェアですが、ver 0.8あたりからCeph以外のストレージプラットフォームも追加され、ver 1.1ではEdgeFSがstable版として利用可能になりました。
Rookの機能としては以下のようなものが挙げられます。
- ストレージプラットフォームのデプロイと管理の自動化
- ストレージプラットフォームのデプロイ簡便化
- ストレージの構成管理(yamlによる管理)
- アップグレード簡便化
- 監視(Prometheus向けメトリクス)
- 複数のストレージプロバイダーのサポート
- 複数のストレージプロバイダーをCloud-Native環境に統合するフレームワーク
- 安定版: Ceph, EdgeFS
- α版: Cassandra, CockroachDB, NFS, YugabyteDB, Apache Ozone(ver 1.2から)
- Kubernetes機能を利用した各機能
- コンポーネントの自動復旧
- スケール
またRookの構成は以下の通りです。RookはストレージプロバイダーごとにOperatorを作成し、デプロイや運用自動化をもたらします。またRook Discoverはノード上のストレージデバイスを監視し、デバイスが追加された際は自動的にCephクラスターに追加します。
ちなみにver 1.1からはCeph CSI Driverがデフォルトで利用され、Rook Agentは利用されません。ver 1.0まではRook Agentがデフォルトで設定されており、FlexVolume Driverを構成しています。将来的にはCSI Driverの機能拡張に従い、Rook Agentはdeprecateされる予定のようです。
PVC-Based Clusterとは
Rookは2019年9月中旬にver 1.1が公開され、Cephに関連する複数の新機能が発表されました。その中で、PVC-Based Clusterというものがあります。
これまでRook-Cephを利用する場合、Ceph Monitor DaemonやOSDをPodとしてデプロイする際、host pathを指定する必要がありました (Host-Based Cluster)。これによりCephクラスターに利用できるのはKubernetesノードにアタッチされたストレージのみとなり、Podとノードとの結びつきが強くなってしまいます。その結果として柔軟性に欠けたストレージクラスターとなり、アプリケーションの動向に応じてストレージが追従する、というCloud Native Storageのコンセプトを実現するのが難しくなってしまいます。
一方、PVC-Based Clusterは、文字どおりPersistentVolumeClaimsを利用してCeph Monitor Daemon、OSDをデプロイできます。これによりKubernetesノードから独立したストレージデバイスも利用できるため、Podとノードとの結びつきが弱まります。またこの機能はKubernetesのRaw Block Volume機能を利用しており、利用するストレージデバイスがこれに対応している必要があります。
PVC-Based ClusterはRookの新機能の中でも注目されている機能であり、先日開催されたKubeCon+CloudNativeCon NA 2019 (動画リンク)では、PVC-Based Clusterがもたらすメリットについて紹介しています。PVC-Based Clusterを利用してCephクラスターをクラウド上に配置することで、クラウドプロバイダーの欠点を補い、以下のようなことが実現できます。
- AZをまたいだストレージの利用:異なるAZに配置されたストレージは同一のVMにアタッチすることができませんが、PVC-Baseの場合は各ストレージにアクセスできれば利用可能となります。
- フェイルオーバー時間の短縮:VMにストレージをアタッチした場合と比べ、VMがダウンしてからの復旧時間がより短縮されます。
- ノードあたりのPV数の制限を超える:AWS EC2などでは、VMあたりにアタッチできるデバイスの数は制限されています。PVC-Baseの場合はそのような制限はなく、結果的により巨大なサイズのストレージクラスターを構築できます。
※KubeCon+CloudNativeCon NA 2019 スライドより(動画リンク)
PVC-Based Clusterを試す
ここからPVC-Based Clusterを試してみます。基本的な構築方法はRookの公式ドキュメントに紹介されているので、そちらを見ながら進めます。
検証環境
今回はAzure Kubernetes Service (AKS)を利用して検証します。マネージドなKubernetesを利用することで、初期状態からCloud Providerが有効であったり、Azure DiskをprovisionerとするStorage Classが利用できたりと、検証するには都合のいい状態が作れます。なお、今回の操作はすべてAzure Cloud Shellで行っています。
- Kubernetes version: 1.14.8
- Node数: 3
- Node size: Standard_DS2_v2
- Network Configuration: Basic (Kubenetを利用)
- region: 西日本
Rookのデプロイ
はじめにRookを利用するためのリソースをデプロイします。この辺りはHost-Basedの場合とも共通ですが、まずはCRD、RBACなどが定義されたcommon.yaml
をデプロイします。
$ git clone https://github.com/rook/rook.git
$ cd rook/cluster/examples/kubernetes/ceph/
$ kubectl apply -f common.yaml
namespace/rook-ceph created
customresourcedefinition.apiextensions.k8s.io/cephclusters.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephfilesystems.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephnfses.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephobjectstores.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephobjectstoreusers.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephblockpools.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/volumes.rook.io created
customresourcedefinition.apiextensions.k8s.io/objectbuckets.objectbucket.io created
customresourcedefinition.apiextensions.k8s.io/objectbucketclaims.objectbucket.io created
clusterrolebinding.rbac.authorization.k8s.io/rook-ceph-object-bucket created
clusterrole.rbac.authorization.k8s.io/rook-ceph-cluster-mgmt created
clusterrole.rbac.authorization.k8s.io/rook-ceph-cluster-mgmt-rules created
role.rbac.authorization.k8s.io/rook-ceph-system created
clusterrole.rbac.authorization.k8s.io/rook-ceph-global created
clusterrole.rbac.authorization.k8s.io/rook-ceph-global-rules created
clusterrole.rbac.authorization.k8s.io/rook-ceph-mgr-cluster created
clusterrole.rbac.authorization.k8s.io/rook-ceph-mgr-cluster-rules created
clusterrole.rbac.authorization.k8s.io/rook-ceph-object-bucket created
serviceaccount/rook-ceph-system created
rolebinding.rbac.authorization.k8s.io/rook-ceph-system created
clusterrolebinding.rbac.authorization.k8s.io/rook-ceph-global created
serviceaccount/rook-ceph-osd created
serviceaccount/rook-ceph-mgr created
serviceaccount/rook-ceph-cmd-reporter created
role.rbac.authorization.k8s.io/rook-ceph-osd created
clusterrole.rbac.authorization.k8s.io/rook-ceph-osd created
clusterrole.rbac.authorization.k8s.io/rook-ceph-mgr-system created
clusterrole.rbac.authorization.k8s.io/rook-ceph-mgr-system-rules created
role.rbac.authorization.k8s.io/rook-ceph-mgr created
role.rbac.authorization.k8s.io/rook-ceph-cmd-reporter created
rolebinding.rbac.authorization.k8s.io/rook-ceph-cluster-mgmt created
rolebinding.rbac.authorization.k8s.io/rook-ceph-osd created
rolebinding.rbac.authorization.k8s.io/rook-ceph-mgr created
rolebinding.rbac.authorization.k8s.io/rook-ceph-mgr-system created
clusterrolebinding.rbac.authorization.k8s.io/rook-ceph-mgr-cluster created
clusterrolebinding.rbac.authorization.k8s.io/rook-ceph-osd created
rolebinding.rbac.authorization.k8s.io/rook-ceph-cmd-reporter created
podsecuritypolicy.policy/rook-privileged created
clusterrole.rbac.authorization.k8s.io/psp:rook created
clusterrolebinding.rbac.authorization.k8s.io/rook-ceph-system-psp created
rolebinding.rbac.authorization.k8s.io/rook-ceph-default-psp created
rolebinding.rbac.authorization.k8s.io/rook-ceph-osd-psp created
rolebinding.rbac.authorization.k8s.io/rook-ceph-mgr-psp created
rolebinding.rbac.authorization.k8s.io/rook-ceph-cmd-reporter-psp created
serviceaccount/rook-csi-cephfs-plugin-sa created
serviceaccount/rook-csi-cephfs-provisioner-sa created
role.rbac.authorization.k8s.io/cephfs-external-provisioner-cfg created
rolebinding.rbac.authorization.k8s.io/cephfs-csi-provisioner-role-cfg created
clusterrole.rbac.authorization.k8s.io/cephfs-csi-nodeplugin created
clusterrole.rbac.authorization.k8s.io/cephfs-csi-nodeplugin-rules created
clusterrole.rbac.authorization.k8s.io/cephfs-external-provisioner-runner created
clusterrole.rbac.authorization.k8s.io/cephfs-external-provisioner-runner-rules created
clusterrolebinding.rbac.authorization.k8s.io/rook-csi-cephfs-plugin-sa-psp created
clusterrolebinding.rbac.authorization.k8s.io/rook-csi-cephfs-provisioner-sa-psp created
clusterrolebinding.rbac.authorization.k8s.io/cephfs-csi-nodeplugin created
clusterrolebinding.rbac.authorization.k8s.io/cephfs-csi-provisioner-role created
serviceaccount/rook-csi-rbd-plugin-sa created
serviceaccount/rook-csi-rbd-provisioner-sa created
role.rbac.authorization.k8s.io/rbd-external-provisioner-cfg created
rolebinding.rbac.authorization.k8s.io/rbd-csi-provisioner-role-cfg created
clusterrole.rbac.authorization.k8s.io/rbd-csi-nodeplugin created
clusterrole.rbac.authorization.k8s.io/rbd-csi-nodeplugin-rules created
clusterrole.rbac.authorization.k8s.io/rbd-external-provisioner-runner created
clusterrole.rbac.authorization.k8s.io/rbd-external-provisioner-runner-rules created
clusterrolebinding.rbac.authorization.k8s.io/rook-csi-rbd-plugin-sa-psp created
clusterrolebinding.rbac.authorization.k8s.io/rook-csi-rbd-provisioner-sa-psp created
clusterrolebinding.rbac.authorization.k8s.io/rbd-csi-nodeplugin created
clusterrolebinding.rbac.authorization.k8s.io/rbd-csi-provisioner-role created
次にRook Operatorを定義するoperator.yaml
をデプロイします。
# Operatorデプロイ
$ kubectl apply -f operator.yaml
deployment.apps/rook-ceph-operator created
# デプロイ後の確認
$ kubectl get pods -n rook-ceph
NAME READY STATUS RESTARTS AGE
rook-ceph-operator-65d489f456-zr5gq 1/1 Running 0 106s
rook-discover-2t2s6 1/1 Running 0 63s
rook-discover-v2vhd 1/1 Running 0 63s
rook-discover-xfjwm 1/1 Running 0 63s
Ceph Clusterのデプロイ
続いてCephのクラスターをデプロイします。まずはクラスターを構築する際に利用するcluster-on-pvc.yaml
を眺めてみます。
#################################################################################################################
# Define the settings for the rook-ceph cluster with common settings for a production cluster.
# All nodes with available raw devices will be used for the Ceph cluster. At least three nodes are required
# in this example. See the documentation for more details on storage settings available.
# For example, to create the cluster:
# kubectl create -f common.yaml
# kubectl create -f operator.yaml
# kubectl create -f cluster-on-pvc.yaml
#################################################################################################################
apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
name: rook-ceph
namespace: rook-ceph
spec:
dataDirHostPath: /var/lib/rook
mon:
count: 3
allowMultiplePerNode: false
# A volume claim template can be specified in which case new monitors (and
# monitors created during fail over) will construct a PVC based on the
# template for the monitor's primary storage. Changes to the template do not
# affect existing monitors. Log data is stored on the HostPath under
# dataDirHostPath. If no storage requirement is specified, a default storage
# size appropriate for monitor data will be used.
volumeClaimTemplate:
spec:
storageClassName: gp2
resources:
requests:
storage: 10Gi
cephVersion:
image: ceph/ceph:v14.2.4-20190917
allowUnsupported: false
dashboard:
enabled: true
ssl: true
network:
hostNetwork: false
storage:
storageClassDeviceSets:
- name: set1
# The number of OSDs to create from this device set
count: 3
# IMPORTANT: If volumes specified by the storageClassName are not portable across nodes
# this needs to be set to false. For example, if using the local storage provisioner
# this should be false.
portable: true
# Since the OSDs could end up on any node, an effort needs to be made to spread the OSDs
# across nodes as much as possible. Unfortunately the pod anti-affinity breaks down
# as soon as you have more than one OSD per node. If you have more OSDs than nodes, K8s may
# choose to schedule many of them on the same node. What we need is the Pod Topology
# Spread Constraints, which is alpha in K8s 1.16. This means that a feature gate must be
# enabled for this feature, and Rook also still needs to add support for this feature.
# Another approach for a small number of OSDs is to create a separate device set for each
# zone (or other set of nodes with a common label) so that the OSDs will end up on different
# nodes. This would require adding nodeAffinity to the placement here.
placement:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- rook-ceph-osd
- key: app
operator: In
values:
- rook-ceph-osd-prepare
topologyKey: kubernetes.io/hostname
resources:
# limits:
# cpu: "500m"
# memory: "4Gi"
# requests:
# cpu: "500m"
# memory: "4Gi"
volumeClaimTemplates:
- metadata:
name: data
spec:
resources:
requests:
storage: 10Gi
# IMPORTANT: Change the storage class depending on your environment (e.g. local-storage, gp2)
storageClassName: gp2
volumeMode: Block
accessModes:
- ReadWriteOnce
disruptionManagement:
managePodBudgets: false
osdMaintenanceTimeout: 30
manageMachineDisruptionBudgets: false
machineDisruptionBudgetNamespace: openshift-machine-api
上記ファイルのうち、spec.mon
あたりはCeph Monitor Daemonの設定、spec.storage. storageClassDeviceSets
あたりはCeph OSDの設定になります。デフォルトの設定ではMonitor、OSDともに3つずつデプロイされ、利用されるStorage Classはgp2
になります。また、Monitorはspec.mon.allowMultiplePerNode
、OSDはspec.storage.storageClassDeviceSets.placement
でデプロイするノードの条件を指定できるようです。
今回は以下のように修正したtest-cluster-on-pvc.yaml
を作成し、これを利用します。
# StorageClassとストレージサイズを変更
$ diff cluster-on-pvc.yaml test-cluster-on-pvc.yaml
30c30
< storageClassName: gp2
---
> storageClassName: default
33c33
< storage: 10Gi
---
> storage: 20Gi
90c90
< storage: 10Gi
---
> storage: 20Gi
92c92
< storageClassName: gp2
---
> storageClassName: default
それではtest-cluster-on-pvc.yaml
をデプロイします。
# Clusterデプロイ
$ kubectl apply -f test-cluster-on-pvc.yaml
cephcluster.ceph.rook.io/rook-ceph created
# デプロイ後の確認
$ kubectl get pods -n rook-ceph
NAME READY STATUS RESTARTS AGE
csi-cephfsplugin-2bc5p 3/3 Running 0 37m
csi-cephfsplugin-2c4sm 3/3 Running 0 37m
csi-cephfsplugin-c2jt4 3/3 Running 0 37m
csi-cephfsplugin-provisioner-5dfb8fcdd5-dp9mb 4/4 Running 0 37m
csi-cephfsplugin-provisioner-5dfb8fcdd5-xlsll 4/4 Running 0 37m
csi-rbdplugin-hpvvm 3/3 Running 0 37m
csi-rbdplugin-jn7v5 3/3 Running 0 37m
csi-rbdplugin-mjwj5 3/3 Running 0 37m
csi-rbdplugin-provisioner-57dfcf95c5-2jtnh 5/5 Running 0 37m
csi-rbdplugin-provisioner-57dfcf95c5-hb98k 5/5 Running 0 37m
rook-ceph-crashcollector-aks-agentpool-25377305-vmss0000002vwjd 1/1 Running 0 32m
rook-ceph-crashcollector-aks-agentpool-25377305-vmss000001rvqj6 1/1 Running 0 35m
rook-ceph-crashcollector-aks-agentpool-25377305-vmss00000264cjn 1/1 Running 0 34m
rook-ceph-mgr-a-6f78c8c74d-5l7g8 1/1 Running 0 31m
rook-ceph-mon-a-6d58c8fff7-p9xrm 1/1 Running 0 35m
rook-ceph-mon-b-7d4cfbc59d-ndxxb 1/1 Running 0 34m
rook-ceph-mon-c-7c687b7bbc-bmh8p 1/1 Running 0 32m
rook-ceph-operator-65d489f456-nzr2b 1/1 Running 0 40m
rook-ceph-osd-0-5b8c65dbb-9r6l4 1/1 Running 0 23m
rook-ceph-osd-1-587c8f4b95-cmx2j 1/1 Running 0 21m
rook-ceph-osd-2-6db9fb7947-sgbh6 1/1 Running 0 21m
rook-ceph-osd-prepare-set1-0-data-f2hbj-4l6sx 0/1 Completed 0 31m
rook-ceph-osd-prepare-set1-1-data-n6hq5-w6qd6 0/1 Completed 0 31m
rook-ceph-osd-prepare-set1-2-data-5c57b-f9dbk 0/1 Completed 0 31m
rook-discover-7fg8l 1/1 Running 0 39m
rook-discover-vdjhm 1/1 Running 0 39m
rook-discover-zc6x7 1/1 Running 0 39m
$ kubectl get pvc -n rook-ceph
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
rook-ceph-mon-a Bound pvc-afb4db9c-184d-11ea-9b39-16d8ab163d04 20Gi RWO default 48m
rook-ceph-mon-b Bound pvc-b8c8330b-184d-11ea-9b39-16d8ab163d04 20Gi RWO default 48m
rook-ceph-mon-c Bound pvc-c1c37a06-184d-11ea-9b39-16d8ab163d04 20Gi RWO default 48m
set1-0-data-f2hbj Bound pvc-6eb3ca6e-184e-11ea-9b39-16d8ab163d04 20Gi RWO default 43m
set1-1-data-n6hq5 Bound pvc-6eb9cb4d-184e-11ea-9b39-16d8ab163d04 20Gi RWO default 43m
set1-2-data-5c57b Bound pvc-6ebe6dbc-184e-11ea-9b39-16d8ab163d04 20Gi RWO default 43m
$ kubectl get pv -n rook-ceph
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-6eb3ca6e-184e-11ea-9b39-16d8ab163d04 20Gi RWO Delete Bound rook-ceph/set1-0-data-f2hbj default 43m
pvc-6eb9cb4d-184e-11ea-9b39-16d8ab163d04 20Gi RWO Delete Bound rook-ceph/set1-1-data-n6hq5 default 43m
pvc-6ebe6dbc-184e-11ea-9b39-16d8ab163d04 20Gi RWO Delete Bound rook-ceph/set1-2-data-5c57b default 43m
pvc-afb4db9c-184d-11ea-9b39-16d8ab163d04 20Gi RWO Delete Bound rook-ceph/rook-ceph-mon-a default 48m
pvc-b8c8330b-184d-11ea-9b39-16d8ab163d04 20Gi RWO Delete Bound rook-ceph/rook-ceph-mon-b default 48m
pvc-c1c37a06-184d-11ea-9b39-16d8ab163d04 20Gi RWO Delete Bound rook-ceph/rook-ceph-mon-c default 48m
無事にデプロイが完了し、Ceph Monitor Daemon、OSDとしてPodが立ち上がりました。
またAzureではAzure Diskが作成されたことも確認できます。
StorageClass/CephBlockPoolのデプロイ
ここまででCephクラスターが構築されたので、あとはCeph上で利用するストレージプールとなるCephBlockPool
をデプロイします。
# StorageClass/CephBlockPoolデプロイ
$ cd csi/rbd
$ $ kubectl apply -f storageclass.yaml
cephblockpool.ceph.rook.io/replicapool created
storageclass.storage.k8s.io/rook-ceph-block created
# デプロイ後確認
$ kubectl get sc
NAME PROVISIONER AGE
default (default) kubernetes.io/azure-disk 68m
managed-premium kubernetes.io/azure-disk 68m
rook-ceph-block rook-ceph.rbd.csi.ceph.com 2m
$ kubectl get cephblockpool.ceph.rook.io -n rook-ceph
NAME AGE
replicapool 2m32s
なおstorageclass.yaml
は以下の通りです。provisionerをrook-ceph.rbd.csi.ceph.com
に指定しています。
apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
name: replicapool
namespace: rook-ceph
spec:
failureDomain: host
replicated:
size: 3
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: rook-ceph-block
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
# clusterID is the namespace where the rook cluster is running
# If you change this namespace, also change the namespace below where the secret namespaces are defined
clusterID: rook-ceph
# Ceph pool into which the RBD image shall be created
pool: replicapool
# RBD image format. Defaults to "2".
imageFormat: "2"
# RBD image features. Available for imageFormat: "2". CSI RBD currently supports only `layering` feature.
imageFeatures: layering
# The secrets contain Ceph admin credentials. These are generated automatically by the operator
# in the same namespace as the cluster.
csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node
csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
# Specify the filesystem type of the volume. If not specified, csi-provisioner
# will set default as `ext4`.
csi.storage.k8s.io/fstype: ext4
# uncomment the following to use rbd-nbd as mounter on supported nodes
#mounter: rbd-nbd
reclaimPolicy: Delete
テスト用Podのデプロイ
上記手順により、Cephのストレージプールまで構築されました。最後にストレージプールを利用できることを確認するため、テスト用のPodをデプロイします。
利用するPod、PersistentVolumeClaimsはそれぞれ以下の通り定義されています。
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rbd-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: rook-ceph-block
---
apiVersion: v1
kind: Pod
metadata:
name: csirbd-demo-pod
spec:
containers:
- name: web-server
image: nginx
volumeMounts:
- name: mypvc
mountPath: /var/lib/www/html
volumes:
- name: mypvc
persistentVolumeClaim:
claimName: rbd-pvc
readOnly: false
# PersistentVolumeClaimsデプロイ
$ kubectl apply -f pvc.yaml
persistentvolumeclaim/rbd-pvc created
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
rbd-pvc Bound pvc-63072b5e-1855-11ea-9b39-16d8ab163d04 1Gi RWO rook-ceph-block 17s
# Podデプロイ
$ kubectl apply -f pod.yaml
pod/csirbd-demo-pod created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
csirbd-demo-pod 1/1 Running 0 28s
以上の通りPodも正常に動作しています。
最後に
Rookはストレージオーケストレーターとして位置付けられていますが、現状ではCephを利用することを念頭に開発されているように感じます。そのため、Rookを導入するか否かを判断する基準としては、既にKubernetes上でCephを構築している、あるいはこれからCephを利用することを検討している現場が向いているのでは、と考えています。またRookについて詳しく知ろうと思うと、Cephのことを十分理解していないと難しいでしょう。RookはあくまでOperatorとしての機能が強く、実際はその上に乗ったストレージプロバイダーがストレージとして機能します。変な話に聞こえるかもしれませんが、 Rookを扱うにはまずCephを扱えるようになるべきだ、というのが個人的な感想です。
また日本国内でも少しずつ注目を集めているRookですが、Rookを本番環境で利用する例が発表されています。これからさらに実例も増え、開発が活発になることが予想されますので、引き続き注目していきたいと思います。