LoginSignup
3
2

More than 5 years have passed since last update.

DRBDのFlexVolume driverを作ってみる。

Last updated at Posted at 2019-04-05

TL;DR

  • KubernetesのFlexVolume driverを自作してみた。
  • DRBDボリュームをマウントするだけの簡単なdriver、bashで作成。
  • Volume周りの動きが分かるようになり、CSIの理解にもつながる。

検証の前に

これまでの投稿で書いているように、PostgreSQL on Kubernetesをする際にRook(というかCeph)を使ってきました。しかし、Cephは分散に重きをおいており、ストレージ・ノードが少ない環境では十分な性能が出るものではないようです。
※私のCeph RBDのチューニングスキルが低いことも付け加えておきます。

すると、今回考えているKubernetesを用いたHAのDBクラスタ構成で性能も同時に向上させたい場合、データ・ローカリティの観点が重要になることに気付きます。つまり、

  • DBMSのPodと同一ノードにデータが配置され、KubernetesがPodを動かした際にはデータもその先に準備されている

という状態を作ることで、DBからみたIOレイテンシの改善を図ることが可能です。

Kubernetesという文脈からは外れますが、データ・ローカリティについて分かりやすいのはNutanixについてのこちらの解説で、以下の特徴が挙げられています。

  • Readでは単一ノードで、ディスクアクセスのみ行う。
  • Writeでは最小限のノードで、データ冗長化のために通信を行う。

DRBDによる永続ボリュームの冗長化

データ・ローカリティの観点で注目したのがDRBDです。DRBD(Distributed Replicated Block Device)は、LinuxでHA構成を作る際にお馴染みのソフトウェアで、ネットワーク越しに複数サーバのHDD(パーティション)を同期してくれます。

現在のバージョンはDRBD9で、シンプルなレプリケーションだけでなくSDS機能を合わせ持ちます。そして、コンテナやKubernetesへの対応も進められています

DRBDをKubernetesから利用する方法

DRBDをKubernetesから使う方法はサイオステクノロジー(旧サードウェア)のDRBD Tech Infoというブログに良くまとまっています。

やり方は大きく2つあり、KubernetesのFlexVolumeプラグインとして利用する方法とCSIプラグインを使用する方法が紹介されています。Kubernetes 1.13でCSIがGAとなり、今後はそちらがメインとなりますが、それぞれの特徴に簡単に触れてみます。

LINSTOR FlexVolume Provisioner

こちらのブログに具体的な構築方法が記述されていますが、概要としては以下のようになります。

  • k8sの各ノードにDRBDとLINSTORというモジュール導入が必要。
  • LINSTORは、KubernetesからDRBDを永続ボリュームとして扱う際の管理・制御を行う。
  • LINSTOR External ProvisionerがMatsterノードに配置されてコントローラとして稼動、ボリュームの作成と削除を行う。
  • LINSTOR FlexVolume Provisionerが各ノードに配置され、ボリュームの接続/切断、マウント/アンマウント等を行う。これがdriverの実体である。

但し、githubリポジトリは2019年4月時点でアーカイブされており、DRBD9の公式ドキュメントでもFlexVolume関連の記述はなくなっています。

linstor-csi plugin

こちらの構築方法も同じブログで紹介されています。

  • linstor-csi-controllerというStatefulSetとlinstor-csi-nodeというDaemonSetがデプロイされる。
  • 後はk8sのボリューム割当の手順(StorageClass、PVC、PV)を使ってボリュームをプロビジョニング可能。

こちらは当ポストとは別に検証を行う予定です。

FlexVolume driverの試作

ここまで見てきて、DRBDをシンプルにKubernetesから使いたいだけなのに、意外と手順が面倒なことに気付きます。「各ノードにDRBDとLINSTORのモジュールを入れて、ノード登録も事前に行っておく」という部分があり、それをするならプロビジョニング(つまりボリュームの作成)も手動でやってしまえば、残りはPodからDRBDボリュームをマウントするだけです。

ということで、今回のKubernetesからのDRBD利用を以下2つの作業に分解します。

  1. 各ノードにDRBDとLINSTORをインストールし、ボリュームとファイルシステム作成まで行う(ここまではホストOSレベルの作業)
  2. 上記で準備したボリュームのマウントをk8sのPodから行うために、FlexVolumeのdriverを自作する。

FlexVolumeのdriver自体は難しいことを考えなければシェルでも実装が可能で、こうした記事でも紹介されています。それを踏まえ、下図の構成を作るに当たって「FlexVolume driver」の箇所をbashで書いてみることにします。

image.png

DRBDデバイスをマウント/アンマウントするプラグイン

LVMのボリュームを操作するFlexVolume driverのサンプルがここにありますので、これを参考にします。

上記にあるFlexVolume driverを読むと、bashで必要なドライバのIFを実装しています。実際にどのようなIFが必要かはバージョンによって異なるため、自身のk8s環境とあわせる必要がありますが、

  • Kubernetesのpkg/volume/flexvolume/driver-call.go

にドライバで実装すべきコマンドが記述されていますので、それを参照するのが最も確実でしょう。

今回の検証ではKubernetes v1.11(Rancher v2.1で使われているもの)を使っているので、そちらを参考にドライバを書いてみたものが以下となります。

mount関連を一部抽出
#!/bin/bash
domount() {
    MNTPATH=$1
    DMDEV=$2
    FSTYPE=$(echo $3|jq -r '.["kubernetes.io/fsType"]')

    if [ ! -b "${DMDEV}" ]; then
        err "{\"status\": \"Failure\", \"message\": \"${DMDEV} does not exist\"}"
        exit 1
    fi

    if [ $(ismounted) -eq 1 ] ; then
        log "{\"status\": \"Success\"}"
        exit 0
    fi

    VOLFSTYPE=`blkid -o udev ${DMDEV} 2>/dev/null|grep "ID_FS_TYPE"|cut -d"=" -f2`
    if [ "${VOLFSTYPE}" == "" ]; then
        mkfs -t ${FSTYPE} ${DMDEV}
        if [ $? -ne 0 ]; then
            err "{ \"status\": \"Failure\", \"message\": \"Failed to create fs ${FSTYPE} on device ${DMDEV}\"}"
            exit 1
        fi
    fi

    mkdir -p ${MNTPATH} &> /dev/null

    mount ${DMDEV} ${MNTPATH} &> /dev/null
    if [ $? -ne 0 ]; then
        err "{ \"status\": \"Failure\", \"message\": \"Failed to mount device ${DMDEV} at ${MNTPATH}\"}"
        exit 1
    fi
    log "{\"status\": \"Success\"}"
    exit 0
}

(開発中のドライバ全文はこちら

driverのデプロイとkubeletの設定変更

FlexVolumeのdriverが出来たら、それをKubernetesから使えるように設定していきます。具体的には以下の手順になります。

  • kubeletに--enable-controller-attach-detach=falseを設定して再起動
  • 先述のbashをKubernetes各ノードに、/usr/libexec/kubernetes/kubelet-plugins/volume/exec/<vendor~driver>/drbdとしてデプロイして実行権限を付与

kubeletのパラメータ修正やFlexVolumeプラグインの配置方法は環境によって異なるため、次の投稿で解説したいと思います。

まとめ

ドライバの動作確認までを当投稿に書くつもりでしたが、思ったより分量が多いため、Rancher+Kubernetes環境へのデプロイと動作確認は次記事に譲りたいと思います。

FlexVolumeのdriverを書いてみようと考えたのは海外のブログポストを見つけたこと、そして、KubernetesのMeetupで「CNIのプラグインを自作してみた」という発表を見つけたのがきっかけになっています。

今回はFlexVolumeについてですが、今後の主流となるCSIのプラグインについても既存のものを読んでみたり、必要であれば書いていきたいと思いますので、よろしくお願いします。

3
2
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
3
2