LoginSignup
4
4

More than 3 years have passed since last update.

おうち環境でRook CephのExternal Clusterを構築する

Last updated at Posted at 2020-08-14

はじめに

前回「kubesprayで構築したk8s環境にTopoLVMを使用してRook Cephのブロックストレージを構築する」作成したKubernetesベースのCephクラスタを別のKubernetesクラスタから使ってみたいと思います。
環境を構築するにあたり、以下の記事には大変お世話になりました。ありがとうございます。
参考にした記事からは使用しているrookのバージョンが上がっていることでちょっとした躓きもあったため、参考になればと記事にしました。

 参考「Rook-Ceph External Cluster ~Rook-Cephクラスター間でExternal Clusterを利用する~


環境

Kubernetes: 1.18.6
Rook: 1.4
Ceph: v15.2.4
OS: Ubuntu20.04LTS

k8s-external-storage.png


手順

用語から

  • Local Cluster

    Cephストレージに接続したいクラスタを指す。Kubernetes / OpenShift クラスタの必要がある。
    今回はKubernetesクラスタをCephストレージに接続します。

  • External Cluster
    Ceph Mons、Mgr、OSD、およびMDSが実行されているクラスタ。
    今回はKubernetesにRookで構築したCephクラスタを使用します。


要件

Local ClusterのクライアントがExternal Clusterに接続するための要件は次のとおりです。

  • External Cluster側にLocal Clusterから接続可能な少なくとも1つのmon endpointが必要
  • External Clusterを管理するためのAdmin Keyring情報
  • Local ClusterからExternal Clusterのmons、mgr、osds、mdsへネットワーク接続できること

参考:Requirements


External Clusterの作成

ほとんど「kubesprayで構築したk8s環境にTopoLVMを使用してRook Cephのブロックストレージを構築する」の記事の通り作成すればよいですが、以下の要件を満たすために設定を一部変更する必要があり、作り直すことになりました。。。まあ仕方ないです。

「External Cluster側にLocal Clusterから接続可能な少なくとも1つのmon endpointが必要」
「Local ClusterからExternal Clusterのmons、mgr、osds、mdsへネットワーク接続できること」


修正ファイル(cluster-on-pvc.yaml)

変更が必要なファイルは、cluster-on-pvc.yamlです。
このファイルを修正してExternal ClusterのCephのネットワークにhostnetworkを使用することでLocal Cluster側からアクセスできるようにします。

cluster-on-pvc.yaml

以下の設定を追加しています。

  network:
    provider: host    # rook 1.3からhost networkを使用したい場合このように記載する

このファイルを使って「kubesprayで構築したk8s環境にTopoLVMを使用してRook Cephのブロックストレージを構築する」の手順で構築すると、以下のようにhost networkでmonのポートが公開されます。


root@k8s-node1:~# ss -anp | grep ceph-mon | grep LISTEN
u_str             LISTEN                 0                   5                                                                    /var/run/ceph/ceph-mon.b.asok 332537                                                  * 0                      users:(("ceph-mon",pid=88919,fd=7))
tcp               LISTEN                 0                   512                                                                                192.168.123.181:3300                                              0.0.0.0:*                      users:(("ceph-mon",pid=88919,fd=27))
tcp               LISTEN                 0                   512                                                                                192.168.123.181:6789                                              0.0.0.0:*                      users:(("ceph-mon",pid=88919,fd=28))
root@k8s-node1:~#

root@k8s-node2:~# ss -anp | grep ceph-mon | grep LISTEN
u_str             LISTEN                 0                   5                                                                    /var/run/ceph/ceph-mon.c.asok 360856                                                  * 0                      users:(("ceph-mon",pid=100347,fd=7))
tcp               LISTEN                 0                   512                                                                                192.168.123.182:3300                                              0.0.0.0:*                      users:(("ceph-mon",pid=100347,fd=27))
tcp               LISTEN                 0                   512                                                                                192.168.123.182:6789                                              0.0.0.0:*                      users:(("ceph-mon",pid=100347,fd=28))
root@k8s-node2:~#

root@k8s-node3:~# ss -anp | grep ceph-mon | grep LISTEN
u_str             LISTEN                 0                   5                                                                    /var/run/ceph/ceph-mon.a.asok 351210                                                  * 0                      users:(("ceph-mon",pid=87768,fd=7))
tcp               LISTEN                 0                   512                                                                                192.168.123.183:3300                                              0.0.0.0:*                      users:(("ceph-mon",pid=87768,fd=27))
tcp               LISTEN                 0                   512                                                                                192.168.123.183:6789                                              0.0.0.0:*                      users:(("ceph-mon",pid=87768,fd=28))
root@k8s-node3:~#

Local Clusterの作成

Rook Operatorの作成

まずは、Local ClusterのKubernetesクラスタのControl Planeから以下のコマンドを実行してRook Operatorを作成します。

参考:External cluster

git clone --single-branch --branch release-1.4 https://github.com/rook/rook.git
kubectl apply -f rook/cluster/examples/kubernetes/ceph/common.yaml
kubectl apply -f rook/cluster/examples/kubernetes/ceph/operator.yaml
kubectl apply -f rook/cluster/examples/kubernetes/ceph/common-external.yaml

External Clusterの接続に必要なリソースの作成

Rookを使用してExternal cluster(Cephクラスタ)に接続するためにConfigMapおよびSecretリソースを作成する必要があります。
import-external-cluster.sh というスクリプトが用意されており、これを実行することで一通り作成できます。

参考:Pre-requisites

  • NAMESPACE:configmapとsecret格納用の名前空間
  • ROOK_EXTERNAL_FSID:External cluster(Cephクラスタ)のfsid。ceph fsidコマンドで取得
  • ROOK_EXTERNAL_CEPH_MON_DATA:External cluster(Cephクラスタ)で実行中のmonのIPアドレスとそのポートのリスト     例:a=172.17.0.4:6789,b=172.17.0.5:6789,c=172.17.0.6:6789。       すべてのmonを指定する必要はなく、1つでも、Operatorが残りを検出します。
  • ROOK_EXTERNAL_ADMIN_SECRET:オプション:External cluster(Cephクラスタ)のAdmin secret key。ceph auth get-key client.adminコマンドで取得

External Clusterで必要な値を取得

前述した値を、External Clusterで toolbox podを使用して取得します。

External Cluster側でtoolboxのコマンドを実行して値を取得

root@k8s-master:~# kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') -- ceph fsid
3619d955-c1a1-4a63-990b-1764be70930e
root@k8s-master:~# 
root@k8s-master:~# kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') -- ceph auth get-key client.admin
AQBhpTZfvTujOBAA0t9rxUYSyNt5cBgz8rUBZQ==root@k8s-master:~#
root@k8s-master:~# kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') -- ceph mon stat
e3: 3 mons at {a=[v2:192.168.123.183:3300/0,v1:192.168.123.183:6789/0],b=[v2:192.168.123.181:3300/0,v1:192.168.123.181:6789/0],c=[v2:192.168.123.182:3300/0,v1:192.168.123.182:6789/0]}, election epoch 12, leader 0 a, quorum 0,1,2 a,b,c
root@k8s-master:~#

Local Clusterで実行(はまりポイント)

「External Clusterの接続に必要なリソースの作成」で記載したパラメタのみ設定してもCephクラスタに接続することができませんでした。
import-external-cluster.sh スクリプトのソースやLocal CLusterが出力するエラーメッセージ、スクリプトが登録するConfigMapやSecretの内容を見ながら悩みに悩んだ結果、スクリプトを修正することでようやくExternal Clusterに接続することができました。

失敗例

例えば、以下のように設定してシエルスクリプトを実行すると、エラーになります。

root@k8s-control:~# export NAMESPACE=rook-ceph-external
root@k8s-control:~# export ROOK_EXTERNAL_FSID=3619d955-c1a1-4a63-990b-1764be70930e
root@k8s-control:~# export ROOK_EXTERNAL_CEPH_MON_DATA=a=192.168.123.183:6789,b=192.168.123.181:6789,c=192.168.123.182:6789
root@k8s-control:~# export ROOK_EXTERNAL_ADMIN_SECRET=AQBhpTZfvTujOBAA0t9rxUYSyNt5cBgz8rUBZQ==
root@k8s-control:~# bash rook/cluster/examples/kubernetes/ceph/import-external-cluster.sh
secret/rook-ceph-mon created
configmap/rook-ceph-mon-endpoints created
secret/rook-csi-rbd-node created
secret/rook-csi-rbd-provisioner created
secret/rook-csi-cephfs-node created
secret/rook-csi-cephfs-provisioner created
root@k8s-control:~#

接続失敗です。

root@k8s-control:~# kubectl get cephcluster.ceph.rook.io -A
NAMESPACE            NAME                 DATADIRHOSTPATH   MONCOUNT   AGE   PHASE        MESSAGE                 HEALTH
rook-ceph-external   rook-ceph-external                                32s   Connecting   Cluster is connecting
root@k8s-control:~#

オペレータには以下のログが出ます

root@k8s-control:~# kubectl logs -f rook-ceph-operator-58496b74f9-9jptz -n rook-ceph
:
2020-08-14 15:55:30.566520 E | cephclient: ceph username is empty
2020-08-14 15:55:30.577853 E | ceph-cluster-controller: failed to reconcile. failed to reconcile cluster "rook-ceph-external": failed to configure external ceph cluster: the cluster identity was not established

rook-ceph-monシークレットでROOK_EXTERNAL_ADMIN_SECRET指定時に作成される "ceph-secret"と"ceph-username"を削除したりもしてみましたが、以下のようなエラーになってアァーもうだめだーと投げそうになりました。

2020-08-14 17:22:24.115022 E | ceph-cluster-controller: failed to reconcile. failed to reconcile cluster "rook-ceph-external": failed to configure external ceph cluster: failed to create csi kubernetes secrets: failed to create kubernetes csi secret: failed to create kubernetes secret map["adminID":"csi-cephfs-node" "adminKey":"AQDDpTZfdDC+IhAAFuKaRQqu7EWy/4aGvJXA6A=="] for cluster "rook-ceph-external": failed to update secret for rook-csi-cephfs-node: Secret "rook-csi-cephfs-node" is invalid: type: Invalid value: "kubernetes.io/rook": field is immutable
悩んだ結果の解決策

op-cluster: Failed to configure external ceph cluster #5732」ここに同じような事象があり、このコメントを参考に以下のようにすることで問題を回避?しました。とりあえずこの方法でうまく動いています。

rook/cluster/examples/kubernetes/ceph/import-external-cluster.shの修正箇所
(右が修正後です)

79,81c79,80
<     --from-literal="$MON_SECRET_MON_KEYRING_KEYNAME"="$ROOK_EXTERNAL_MONITOR_SECRET" \
<     --from-literal="$MON_SECRET_CEPH_USERNAME_KEYNAME"="$ROOK_EXTERNAL_USERNAME" \
<     --from-literal="$MON_SECRET_CEPH_SECRET_KEYNAME"="$ROOK_EXTERNAL_USER_SECRET"
---
>     --from-literal="$MON_SECRET_MON_KEYRING_KEYNAME"="$ROOK_EXTERNAL_MONITOR_SECRET"
>
140,143d138
< importCsiRBDNodeSecret
< importCsiRBDProvisionerSecret
< importCsiCephFSNodeSecret
< importCsiCephFSProvisionerSecret

シェルの実行

export NAMESPACE=rook-ceph-external
export ROOK_EXTERNAL_FSID=3619d955-c1a1-4a63-990b-1764be70930e
export ROOK_EXTERNAL_CEPH_MON_DATA=a=192.168.123.183:6789,b=192.168.123.181:6789,c=192.168.123.182:6789
export ROOK_EXTERNAL_ADMIN_SECRET=AQBhpTZfvTujOBAA0t9rxUYSyNt5cBgz8rUBZQ==
bash rook/cluster/examples/kubernetes/ceph/import-external-cluster.sh

繋がりました(ニッコリ

root@k8s-control:~# kubectl get cephcluster.ceph.rook.io -A
NAMESPACE            NAME                 DATADIRHOSTPATH   MONCOUNT   AGE   PHASE       MESSAGE                          HEALTH
rook-ceph-external   rook-ceph-external                                9s    Connected   Cluster connected successfully   HEALTH_OK
root@k8s-control:~#

動作確認

「(Rook-Ceph External Cluster ~Rook-Cephクラスター間でExternal Clusterを利用する~)[https://techstep.hatenablog.com/entry/2020/02/27/155621]」このサイトの「Local ClusterからExternal Clusterを利用する」をそのまま利用させていただきました。
この辺りはまだまだ勉強不足で書いてあることをそのまま実行しています。。。

CephBlockPoolの作成

cephblockpool.yaml

apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
  name: replicapool-external04
  namespace: rook-ceph-external
spec:
  failureDomain: host
  replicated:
    size: 1
root@k8s-control:~# kubectl apply -f cephblockpool.yaml
cephblockpool.ceph.rook.io/replicapool-external04 created
root@k8s-control:~#

StorageClassの作成

storageclass.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
   name: rook-ceph-block
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
    clusterID: rook-ceph-external  # local clusterのnamespaceに合わせる
    pool: replicapool-external04  # cephblockpoolで指定したPool名に合わせる
    imageFormat: "2"
    imageFeatures: layering
    csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
    csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph-external
    csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner
    csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph-external
    csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node
    csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph-external
    csi.storage.k8s.io/fstype: ext4
allowVolumeExpansion: true
reclaimPolicy: Delete
root@k8s-control:~# kubectl apply -f storageclass.yaml
storageclass.storage.k8s.io/rook-ceph-block created
root@k8s-control:~#
root@k8s-control:~# kubectl get cephblockpool.ceph.rook.io -n rook-ceph-external
NAME                     AGE
replicapool-external04   83s
root@k8s-control:~# kubectl get sc -n rook-ceph-external
NAME              PROVISIONER                  RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
rook-ceph-block   rook-ceph.rbd.csi.ceph.com   Delete          Immediate           true                   83s
root@k8s-control:~#

# External Cluster側で確認

root@k8s-master:~# kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') -- ceph osd pool ls
device_health_metrics
replicapool-external04   ★Poolが作成されている
root@k8s-master:~#

PersistentVolumeClaimsの作成

configmapを修正する

修正前

root@k8s-control:~# kubectl describe cm rook-ceph-csi-config -n rook-ceph
Name:         rook-ceph-csi-config
Namespace:    rook-ceph
Labels:       <none>
Annotations:  <none>

Data
====
csi-cluster-config-json:
----
[]
Events:  <none>
root@k8s-control:~#

修正後

Dataのcsi-cluster-config-jsonの値を以下のように修正する(kubectl editコマンドで修正)。

root@k8s-control:~# kubectl describe cm rook-ceph-csi-config -n rook-ceph
Name:         rook-ceph-csi-config
Namespace:    rook-ceph
Labels:       <none>
Annotations:  <none>

Data
====
csi-cluster-config-json:
----
[{"clusterID":"rook-ceph-external","monitors":["192.168.123.183:6789","192.168.123.181:6789","192.168.123.182::6789"]}]
Events:  <none>
root@k8s-control:~#

以下のファイルをデプロイします。

pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rbd-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: rook-ceph-block

root@k8s-control:~# kubectl apply -f pvc.yaml
persistentvolumeclaim/rbd-pvc created
root@k8s-control:~# kubectl apply -f pvc.yaml
persistentvolumeclaim/rbd-pvc created
root@k8s-control:~#

root@k8s-control:~# kubectl get pvc
NAME      STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
rbd-pvc   Bound    pvc-ebcfe192-6868-42a3-a6ce-963be1e96c34   1Gi        RWO            rook-ceph-block   52s
root@k8s-control:~#

Podの作成

作成したpvcを使用するPodをデプロイします。

pod.yaml

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
root@k8s-control:~# kubectl apply -f pod.yaml
pod/csirbd-demo-pod created
root@k8s-control:~# kubectl get pod csirbd-demo-pod
NAME              READY   STATUS    RESTARTS   AGE
csirbd-demo-pod   1/1     Running   0          20s
root@k8s-control:~#

マウントされています

root@k8s-control:~# kubectl exec -it csirbd-demo-pod -- mount | grep /var/lib/www/html
/dev/rbd0 on /var/lib/www/html type ext4 (rw,relatime,stripe=16)
root@k8s-control:~#

まとめ

今回は予期せぬ動作に悩まされましたが、なんとか目的を達成することができました。
環境の構築は中の動きを理解する助けになるので今後も手を出していきたいです。
しかしながら調査の仕方もよくわからないのでエラーが出るとくじけそうになります。。。
がんばりたいです。


参考URL

Rook-Ceph External Cluster ~Rook-Cephクラスター間でExternal Clusterを利用する~
Cluster Settings
Network Configuration Settings
Rook and External Ceph Clusters
Ceph Cluster CRD

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4