DRBDのFlexVolume driverをRancherで動かしてみる。

# TL;DR

- Rancherで構築したKubernetes環境でkubeletのパラメータを更新してみた。
- 同じ環境でFlexVolumeのプラグインをデプロイしてみた。
- DRBDのFlexVolume Driverを動かしてみたが、まだまだ検証レベル。

#「作ってみる。」に続けて
先日、[「DRBDのFlexVolume driverを作ってみる。」](https://qiita.com/tzkoba/items/5e9d4e46aeedea5c6491)をという記事を書きました。
シンプルなDRBDボリュームをマウント／アンマウントするだけのFlexVolume driverをbashで実装してみる、という内容になっています。

今回はその続きで、作ったドライバをKubernetesで動かしてみるという内容になります。私はKubernetes環境の構築に[Rancher](https://rancher.com/)を使っていますので、同様の環境でkubeletのパラメータを更新したり、pluginを実際にデプロイする際の参考にもなると思います。

# 改めてやりたいことは
前回記事で書いたように、LINBIT社（LINSTORの開発元）から提供されているFlexVolume Provisioner／External Provisionerは機能として十分な反面、導入が煩雑です。

LINSTORでDRBDのボリュームまで作成したノードがあれば（これ自体が面倒ですが）、あとはDRBD9の自動プロモーション機能によりマウント／アンマウントだけで複数ノードからのアクセスを制御できます。

つまり、下図にあるNGINXのPodをKubernetesが移動させた際にはそれに追随して、DRBDボリュームを適切なPodでマウントすることが出来るようになります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/54853/5fe90ed8-ba16-8b96-f28c-bdf3182bea77.png)

当然、DRBDのレプリケーションも同時に行われていますので、ノードが移動したとしてもPodからは同じデータを参照することが出来るというわけです。

# RancherでFlexVolume driverを動かす際の問題点
Rancher（今回はv2.1）はKubernetesのクラスタをUIから簡単に構築・管理できる、優秀なツールです。他にk8sのクラスタを構築する方法としてminikubeやkubeadmなどがありますが、私は通常Rancherを使っています。

しかし、特定のソフトウェアをデプロイする際にReadmeで下記のように書かれている場合、Rancherでの対応方法に戸惑います。

- kubeletに```--aaa=BBB```を設定して、kubeletを再起動。
- api-serverに```--ccc=DDD```を設定して、api-serverを再起動。
- ```/usr/libexec/kubernetes/kubelet-plugin```にプラグインをインストール。

というのも、Rancherではkubeletやapi-serverはコンテナとしてデプロイされており、それらの設定変更は簡単でないように見えます。

今回FlexVolumeのプラグインを動かすにあたっての要件をおさらいすると、以下となります。

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

## Rancherでのkubeletパラメータ変更の方法
もちろん、やり方はあります。

Rancher v2.1では、各k8sクラスタのEdit画面に下図のように「Edit as YAML」というボタンがありますので、これを押します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/54853/9f248113-7124-16d4-5d0a-f10f31187d40.png)

「Edit as YAML」を押下すると以下のようなYAML編集画面が表示されますので、そこを直接編集していきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/54853/3ea13be6-47d7-a1a8-5c57-fa7d0355164b.png)

ここで**<font color="red">1.</font>**ではkubeletに```--enable-controller-attach-detach=falase```を与えています。これは**[attach/detach controller](https://github.com/kubernetes/kubernetes/blob/master/pkg/controller/volume/attachdetach/attach_detach_controller.go)**が各NodeのVolumeのアタッチ・デタッチを行わず、kubeletで実行するということを意味しています。デフォルトは**true**です。

もう一つ、**<font color="red">2.</font>**ではvolume-plugin-dirが```/usr/libexec/kubelet-plugin/volume/exec```であることを示しています。そして、先ほど述べたようにRancherではkubeletがコンテナ化されていますので、```extra_binds```の項目でコンテナ内のプラグインディレクトリがホストの```/usr/libexec/kubelet-plugin/volume/exec```にバインドされていることを定義します。

ここまででRancher側の準備は完了です。
あとはkubeletを再起動する必要があるのですが、Rancherでは上記の設定変更をSaveするとしばらくしてkubeletが再起動されるようになっていました。

# いよいよ動かしてみる
さて、ここまででFlexVolume driverをkubernetesで動かす準備と、プラグインを配置するディレクトリをホストOS側に公開することが出来ました。

ドライバの配置は簡単で、各ノードで```/usr/libexec/kubernetes/kubelet-plugins/volume/exec/<vendor~driver>/drbd```に[ドライバファイル](https://github.com/tzkoba/postgres-on-k8s/blob/develop/postgres-install/pg-drbd/drbd.sh)をコピーするだけです。

このとき注意点は配置場所の```<vendor~driver>```部分です。
今回は後述のPesistent VolumeのYAMLと整合性を採って、以下のディレクトリ名で配置してみます。
```/usr/libexec/kubernetes/kubelet-plugins/volume/exec/nri.com~drbd/drbd```

## プラグイン呼び出し側の準備
ドライバファイルを配置したら、後はそれを使うYAML、具体的には以下3つをkubernetesにデプロイします。

1. [Persistent Volume](https://github.com/tzkoba/postgres-on-k8s/blob/develop/postgres-install/pg-drbd/pv-localvolume.yaml)
2. [Persistent Volume Claim](https://github.com/tzkoba/postgres-on-k8s/blob/develop/postgres-install/pg-drbd/pvc-localvolume.yaml)
3. [Deployment](https://github.com/tzkoba/postgres-on-k8s/blob/develop/postgres-install/pg-drbd/nginx-sample.yaml)

ポイントはやはりドライバを指定する1.です。内容は下記のようになっていますが、flexVolumeのdriverセクションで```vendor/driver```の形で指定しています。これがプラグイン配置ディレクトリ・ファイル名と整合していないと呼び出しに失敗します。
さらにoptinosで指定された項目は、JSON形式でドライバに渡されて処理されます。

```YAML:pv-localvolume.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
  - ReadWriteOnce
  flexVolume:
    driver: "nri.com/drbd"
    fsType: "xfs"
    options:
      volumeID: "drbd1000"
      size: "1000m"
      volumegroup: "drbdpool"
```

上記のYAMLを1.から順にデプロイすると、自作のFlexVolume driverでDRBDボリュームをマウントしたNGINX Podが稼動します。

※*前提として、各ノードにDRBD・LINSTORがインストールされ、ボリュームの作成・フォーマットまでを行っておく必要があります。また、driver内でjqコマンドを使っているため、そちらもインストールが必要です。*

# まとめ
前回に引き続き、DRBDのボリュームをKubernetesから自作のFlexVolume driverを使ってマウントしてみる手順を紹介しました。

環境としてRancherで構築したKubernetesを使っているため、その際に必要になるkubeletのパラメータ修正やpluginディレクトリをホスト上に公開する方法も説明しています。

もちろん簡単な方法ではないのですが、今後主流となるCSIが更に多くのコンポーネントに分割されていることを考えると、FlexVolumeで簡単なdriverを書くのは今後も簡便な検証では使えるやり方となるでしょう。また、CSIを学ぶ前段階として、このあたりを触っておく事は役に立つと思います。

よろしくお願いします。