4ステップ完全ガイド!KubernetesでCephを活用した高可用性ストレージ管理術

こんにちは、GMOインターネットグループ株式会社の長谷川です。
今回は Kubernetes 環境での Ceph CSI を使ったストレージ活用と導入に関して語っていこうと思います。

前回のあらすじ

前回は Kubernetes上(k8s上)に分散ストレージの Ceph をデプロイし、ストレージの運用を自動化するストレージオペレーターで、Ceph は分散オブジェクトストレージ機能を提供する、オープンソースのストレージソフトウェアの Rook-Ceph を紹介しました。

今回は外部の Ceph を Ceph CSI 経由でどのように活用していくのかを紹介します。

Ceph CSI とは

https://github.com/ceph/ceph-csi

Ceph CSI(Container Storage Interface)は、コンテナオーケストレーションプラットフォーム(Kubernetesなど)と Ceph ストレージクラスター間のやり取りを可能にするプラグインスイートです。言い換えると、Ceph CSI は、コンテナ化されたアプリケーションが Ceph の分散ストレージ機能を利用できるようにするドライバーのようなものです。

今回は Ceph CSI の導入に関して説明していこうと思います。

【STEP1】リポジトリの取得と namespace の作成

git clone https://github.com/ceph/ceph-csi.git
kubectl create namespace ceph-csi

【STEP2】RBD 前準備(Ceph ストレージ側)

まず、今回 Kubernetes から Ceph ストレージを使用するので pool 等の事前準備が必要になります。
以下コマンドを参考に pool を作成してください。

ceph osd pool create kubernetes # pool 名は任意で変更
rbd pool init kubernetes
ceph auth get-or-create client.kubernetes mon 'profile rbd' osd 'profile rbd pool=kubernetes' mgr 'profile rbd pool=kubernetes'

【STEP3】Ceph-CSI-RBD のデプロイ(Kubernetes 側)

まずは、先ほど取得したリポジトリから deploy/rbd/kubernetes/csidriver.yaml をデプロイします。

cd ceph-csi
kubectl apply -f deploy/rbd/kubernetes/csidriver.yaml -n ceph-csi

deploy/ceph-conf.yaml をデプロイします。
これもデフォルトのままで問題ありません。

kubectl apply -f deploy/rbd/kubernetes/ceph-config.yaml -n ceph-csi

examples/kms/vault/kms-config.yaml も後で必要になるのでデプロイします。

kubectl apply -f examples/kms/vault/kms-config.yaml -n ceph-csi

次に、deploy/rbd/kubernetes/csi-config-map.yaml をデプロイ
ただしここでは外部の Ceph の情報を記載します。

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: "ceph-csi-config"
data:
  config.json: |-
    [
      {
        "clusterID": "58f22b19-3a76-4dbe-b5d0-8e2dcd9e0879", # Ceph のクラスタ ID
        "monitors": [
          "10.10.10.10:6789", # Ceph monitor の IP と Port
          "10.10.10.11:6789",
          "10.10.10.12:6789"
        ],
      }
    ]

なお、Ceph のクラスタ ID は Ceph の /etc/ceph/ceph.confglobal.fsid から取得できます。

kubectl apply -f deploy/rbd/kubernetes/csi-config-map.yaml  -n ceph-csi

examples/rbd/secret.yaml をデプロイ
ここでは、rbd pool の userID と userKey が必要です。

---
apiVersion: v1
kind: Secret
metadata:
  name: csi-rbd-secret
  namespace: ceph-csi
stringData:
  userID: kubernetes # pool 名がユーザー名になる
  userKey: AQBLtbmmLTijMRccJFeNecr+rH+8cfMPJbfs5C== # Ceph の kubernetes pool の key

なお以下のコマンドで kubernetes pool の key を調べることができる。

ceph auth get-or-create client.kubernetes mon 'profile rbd' osd 'profile rbd pool=kubernetes' mgr 'profile rbd pool=kubernetes'

変更後適用します。

kubectl apply -f examples/rbd/secret.yaml -n ceph-csi

deploy/rbd/kubernetes/csi-provisioner-rbac.yaml を適用します。
ここでは、デフォルトで記述されている namespace が適用先と異なるので修正します。

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: rbd-csi-provisioner
  # replace with non-default namespace name
  namespace: ceph-csi # マニフェストファイル内のすべての namespace を編集する。

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
....
....

編集後に適用します。

kubectl apply -f deploy/rbd/kubernetes/csi-provisioner-rbac.yaml -n ceph-csi

deploy/rbd/kubernetes/csi-nodeplugin-rbac.yaml に関しても適用します。
ここでも適用先の namespace が異なるので修正します。

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: rbd-csi-nodeplugin
  # replace with non-default namespace name
  namespace: ceph-csi # ここをデプロイ先の namespace に変更
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1

deploy/rbd/kubernetes/csi-rbdplugin-provisioner.yaml のデプロイ
ここでも namespace を修正します。

---
kind: Service
apiVersion: v1
metadata:
  name: csi-rbdplugin-provisioner
  # replace with non-default namespace name
  namespace: ceph-csi # マニフェストすべての namespace を修正
  labels:
    app: csi-metrics
spec:
  selector:
    app: csi-rbdplugin-provisioner
  ports:
    - name: http-metrics
      port: 8080
      protocol: TCP
      targetPort: 8680
....
....
kubectl apply -f deploy/rbd/kubernetes/csi-rbdplugin-provisioner.yaml -n ceph-csi

deploy/rbd/kubernetes/csi-rbdplugin.yaml の適用、ここでも namespace を修正します。

---
kind: DaemonSet
apiVersion: apps/v1
metadata:
  name: csi-rbdplugin
  # replace with non-default namespace name
  namespace: ceph-csi # マニフェストすべての namespace を修正
spec:
  selector:
    matchLabels:
      app: csi-rbdplugin
....
....
kubectl apply -f deploy/rbd/kubernetes/csi-rbdplugin.yaml -n ceph-csi

最後に kubectl get pods -n ceph-csi で確認した際に以下の Pod が出来ていると思うので Kubernetes のストレージクラスを定義します。

root@dev-k8s-master-b001:~# kubectl get po -n ceph-csi
NAME                                           READY   STATUS    RESTARTS   AGE
csi-rbdplugin-76z5v                            3/3     Running   0          18d
csi-rbdplugin-jkw55                            3/3     Running   0          18d
csi-rbdplugin-mltqr                            3/3     Running   0          18d
csi-rbdplugin-n7d6z                            3/3     Running   0          18d
csi-rbdplugin-provisioner-796f7dbcb8-9lfq8     7/7     Running   0          18d
csi-rbdplugin-provisioner-796f7dbcb8-9mrhk     7/7     Running   0          18d
csi-rbdplugin-provisioner-796f7dbcb8-fb7wm     7/7     Running   0          18d
csi-rbdplugin-z8sdf                            3/3     Running   0          18d

ストレージクラスに関しては examples/rbd/storageclass.yaml に必要情報を記載し適用します。
コメント行が多いので、そこを省略すると以下のようになります。

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
   name: csi-rbd-sc
provisioner: rbd.csi.ceph.com
parameters:
   clusterID: 58f22b19-3a76-4dbe-b5d0-8e2dcd9e0879 # Ceph のクラスタ ID
   pool: kubernetes
   csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
   csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi
   csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
   csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi
reclaimPolicy: Delete # reclaimePolicy はお好みで
mountOptions:
   - discard

ストレージクラスを確認します。
また、必要に応じて rbd のストレージクラスをデフォルト設定にします。

root@dev-k8s-master-b001:~# kubectl get sc
NAME                   PROVISIONER           RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
csi-rbd-sc (default)   rbd.csi.ceph.com      Delete          Immediate           false                  18d

今回デプロイしたのは rbd のストレージクラスなので 、コンテナからのアクセスは RWO に対応したストレージクラスとなります。

次のステップでは RWX のアクセスに対応したストレージクラスを CephFS 作成し CSI 経由で利用します。

【STEP4】CephFS 前準備

Ceph ストレージに以下コマンドで CephFS を作成します。

# CephFS のデータ pool を作成
ceph osd pool create cephfs_kubernetes_data
# CephFS のメタデータ pool を作成
ceph osd pool create cephfs_kubernetes_metadata
# CephFS を作成
ceph fs new cephfs_kubernetes cephfs_kubernetes_metadata cephfs_kubernetes_data

# mds のデプロイ [HOSTNAME] 部分は mds をデプロイするノード名
ceph orch apply mds cephfs_kubernetes --placement="1 [HOSTNAME]"
# 認証情報を作成し、ファイルにも保存
ceph fs authorize cephfs_kubernetes client.kubernetes_user / rw   | sudo tee /etc/ceph/ceph.client.kubernetes_user.keyring
chmod 0600 /etc/ceph/ceph.client.kubernetes_user.keyring

# 意外と忘れがちですが、サブボリュームグループを作成しないと csi から CephFS を使えません。(名前は任意で決める)
ceph fs subvolumegroup create cephfs_kubernetes subgroup_kubernetes

【STEP4】Ceph-CSI-CephFS のデプロイ

ここからは CephFS CSI をデプロイしていきます。
なお今回は rdb でデプロイした ConfigMap などのリソースを再利用する前提として、
使う namespace は 【STEP3】でデプロイしたものと同じ namespace を使います。

examples/cephfs/secret.yaml をデプロイします。

---
apiVersion: v1
kind: Secret
metadata:
  name: csi-cephfs-secret
  namespace: default
stringData:
  userID: kubernetes_user # CephFS で作成したユーザー名
  userKey: <Ceph auth key> # /etc/ceph/ceph.client.kubernetes_user.keyring から値を取得
  adminID: admin
  adminKey: <Ceph auth key> # ceph auth list 等のコマンドで探してくる

  # Encryption passphrase
  encryptionPassphrase: test_passphrase # ここは暗号化しなければなしでOK
kubectl apply -f examples/cephfs/secret.yaml -n ceph-csi

deploy/cephfs/kubernetes/csidriver.yaml のデプロイ

kubectl apply -f deploy/cephfs/kubernetes/csidriver.yaml -n ceph-csi

deploy/cephfs/kubernetes/csi-provisioner-rbac.yaml ここも前 STEP で行ったのと同様に namespace を書き換える

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: cephfs-csi-provisioner
  namespace: ceph-csi # namespace 書き換え
....
....
kubectl apply -f deploy/cephfs/kubernetes/csi-provisioner-rbac.yaml -n ceph-csi

deploy/cephfs/kubernetes/csi-nodeplugin-rbac.yaml こちらも namespace の書き換え

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: cephfs-csi-nodeplugin
  namespace: ceph-csi # namespace 書き換え
....
....
kubectl apply -f deploy/cephfs/kubernetes/csi-nodeplugin-rbac.yaml -n ceph-csi

deploy/cephfs/kubernetes/csi-cephfsplugin-provisioner.yaml デプロイ

kubectl apply -f deploy/cephfs/kubernetes/csi-cephfsplugin-provisioner.yaml -n ceph-csi

deploy/cephfs/kubernetes/csi-cephfsplugin.yaml デプロイ

kubectl apply -f deploy/cephfs/kubernetes/csi-cephfsplugin.yaml -n ceph-csi

またここで CephFS を利用するために以前適用した、ConfigMapceph-csi-config を修正します。

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: "ceph-csi-config"
data:
  config.json: |-
    [
      {
        "clusterID": "58f22b19-3a76-4dbe-b5d0-8e2dcd9e0879", # Ceph のクラスタ ID
        "monitors": [
          "10.10.10.10:6789", # Ceph monitor の IP と Port
          "10.10.10.11:6789",
          "10.10.10.12:6789"
        ],
        # 以下三行記載、subvolumeGroup は作成したものに変更
        "cephFS": { 
          "subvolumeGroup": "subgroup_kubernetes"
        }
      }
    ]

apply して変更を適用します。

kubectl apply -f deploy/rbd/kubernetes/csi-config-map.yaml -n ceph-csi

examples/cephfs/storageclass.yaml を編集しストレージクラスをデプロイ

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: csi-cephfs-sc
provisioner: cephfs.csi.ceph.com
parameters:
  clusterID: 58f22b19-3a76-4dbe-b5d0-8e2dcd9e0879 # Ceph のクラスタ ID
  fsName: cephfs_kubernetes # CephFS の名前
  pool: cephfs_kubernetes_data # data pool の名前

  csi.storage.k8s.io/provisioner-secret-name: csi-cephfs-secret # シークレット指定
  csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi # namespace 指定
  csi.storage.k8s.io/controller-expand-secret-name: csi-cephfs-secret
  csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi
  csi.storage.k8s.io/node-stage-secret-name: csi-cephfs-secret
  csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi

reclaimPolicy: Delete # ここはお好みで
allowVolumeExpansion: true
kubectl apply -f examples/cephfs/storageclass.yaml -n ceph-csi

以下のようにストレージクラスが表示されれば成功です。

root@dev-k8s-master-b001:~# kubectl get sc
NAME                   PROVISIONER           RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
csi-cephfs-sc          cephfs.csi.ceph.com   Delete          Immediate           true                   18d
csi-rbd-sc (default)   rbd.csi.ceph.com      Delete          Immediate           false                  18d

まとめ

Ceph CSI は、Kubernetes 上で Dynamic PV を運用するための方法を提供します。また外部にあるエンタープライズの Ceph にストレージを任せることにより、高いスケーラビリティ、高可用性、コスト効率など、多くの利点がありますので是非チャレンジしてみてください。

ブログの著者欄

長谷川 泰斗

GMOインターネットグループ株式会社

2020年 GMOインターネットグループ株式会社 新卒入社
クラウド基盤エンジニア
お名前.com KVM, ConoHa VPS等の開発運用に従事

採用情報

関連記事

KEYWORD

採用情報

SNS FOLLOW

GMOインターネットグループのSNSをフォローして最新情報をチェック