Kubernetesのオンプレ用ソフトウェア IBM Cloud Private Community Edition からコントロールできる永続ストレージが、別途構築が必要なので、Vagrantを利用してGlusterFSとの連携を検証してみました。
システム構成
k8sからGlusterFSをコントロールするために次の様な構成をとりました。 HeketiとGlusterFSの概要も以下にあります。
GlusterFSとは
GlusterFSは、スケーラブルなストレージのための汎用分散ファイルシステムの1つ。InfiniBandのRDMAやTCP/IPインターコネクトなどの各種ストレージを集約し、大規模並列ネットワークファイルシステムを構築できる。GlusterFSはユーザー空間で構築されており、性能を低下させることがない。クラウドコンピューティング、生物医学、超大容量ストレージなど様々な応用がなされている。GlusterFSは、当初Gluster, Inc.によって開発された。2011年のレッドハットによるGluster買収の後はレッドハットにより開発されている。
出典 GlusterFS https://ja.wikipedia.org/wiki/GlusterFS
Heketiとは
Heketiは、GlusterFSボリュームのライフサイクルを管理するために使用できるRESTfulな管理インタフェースを提供します。Heketiを利用する事で、OpenStack Manila、Kubernetes、OpenShiftなどのクラウドサービスは、動的に堅牢さを保証するGlusterFSのボリュームをプロビジョンできます。Heketiは自動的にクラスタ全体でブロックを決定して、その複製を異なる障害ドメインに配置します。 Heketiはまた、任意の数のGlusterFSクラスタをサポートしているため、クラウドサービスは単一のGlusterFSクラスタに限定されずにネットワークファイルストレージを提供できます。
出典 Heketi ホーム https://github.com/heketi/heketi/wiki
GlusterFSとHeketiのVagrantfile
GlusterFSを複数の物理サーバーにインストールして、テスト環境を構成すると大変なので、自分のMacやWindowsの仮想環境で、GlusterFSクラスタとHeketiを構成するためのVagrantfileを作成しました。 このVagrantfileを利用すると、次の図の右側の様に、3つのクラスタメンバーのGlusterFSクラスタと、一つのHeketiサーバーが起動します。
Vagrantfileの説明
次のリストが、vagrant でオートマチックに、GlusterFSのクラスタを構成して、起動するためのRubyで書かれたファイルです。 作業内容が判る様コメントを入れています。IPアドレスを必要に応じて自身の環境に合わせて変更して、ICP-CEと通信できる様にします。 このファイルを利用したクラスタの起動方法は、後述します。
# coding: utf-8
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
# VirtualBoxで起動する仮想サーバーのOS
config.vm.box = "ubuntu/xenial64"
# GlusterFSのバージョン
glusterfs_version = "3.12"
# GlusterFSのサーバーの構成と起動
# ホスト名 gluster-1〜gluster-3の3つのホストを起動するループを回します。
# 192.168.1.91〜93のIPアドレスを付与、仮想サーバーのNICはブリッジモードで外部と通信できるモードにします。
# この3つのホストには、それぞれ 20GiBのデータ保存用のディスクを付与します。
# このデータ保存用の仮想ディスクは、
# 仮想サーバーが起動したら、GlusferFSのリポジトリからインストールします。
(1..3).each do |i|
config.vm.define vm_name = "gluster-#{i}" do |config|
config.cache.scope = :box
config.vm.hostname = vm_name
# IPアドレスは、ICP-CEに付与したIPアドレスからアクセスできる様に編集してください。
ip = "192.168.1.#{i+90}"
config.vm.network :public_network, ip: ip, bridge: "en0: Ethernet"
# データ保存用ディスクの増設
config.vm.provider :virtualbox do |p|
vdisk = "vdisk/sdb-#{i}.vdi"
if not File.exist?(vdisk) then
p.customize [
'createmedium', 'disk',
'--filename', vdisk,
'--format', 'VDI',
'--size', 20 * 1024]
end
# Gluster device 1GiB
p.customize [
'storageattach', :id,
'--storagectl', 'SCSI',
'--port', 2,
'--device', 0,
'--type', 'hdd',
'--medium', vdisk]
end
# 仮想サーバー起動後のGlusterFSのインストール
config.vm.provision "shell", inline: <<-SHELL
export DEBIAN_FRONTEND=noninteractive
apt-get update && apt-get install -yq python-software-properties
add-apt-repository ppa:gluster/glusterfs-#{glusterfs_version}
apt-get update && apt-get install -yq glusterfs-server thin-provisioning-tools
cp /vagrant/ssh/id_rsa.pub /root/.ssh/authorized_keys
SHELL
end
end
# Heketiのインストールと GlusterFSのクラスタ設定
# IPアドレス 192.168.1.90でブリッジモードで起動します。 必要に応じて変更してください。
config.vm.define vm_name = "heketi" do |config|
config.cache.scope = :box
config.vm.hostname = vm_name
ip = "192.168.1.90"
config.vm.network :public_network, ip: ip, bridge: "en0: Ethernet"
# 仮想サーバー起動後のインストールとクラスタの設定のシェルです。
# こちらにもIPアドレスが入っているので、合わせて修正をお願いします。
config.vm.provision "shell", inline: <<-SHELL
export DEBIAN_FRONTEND=noninteractive
apt-get update && apt-get install -yq python-software-properties
add-apt-repository ppa:gluster/glusterfs-#{glusterfs_version}
apt-get update && apt-get install -yq glusterfs-client
cp /vagrant/ssh/id_rsa /root/.ssh/id_rsa
cp /vagrant/ssh/id_rsa /home/ubuntu/.ssh/id_rsa
chown ubuntu:ubuntu /home/ubuntu/.ssh/id_rsa
ssh -o 'StrictHostKeyChecking no' root@192.168.1.91 hostname
ssh -o 'StrictHostKeyChecking no' root@192.168.1.92 hostname
ssh -o 'StrictHostKeyChecking no' root@192.168.1.93 hostname
wget https://github.com/heketi/heketi/releases/download/1.0.1/heketi-1.0.1.linux.amd64.tar.gz
tar xzvf heketi-1.0.1.linux.amd64.tar.gz
cp /vagrant/heketi/heketi.json /home/ubuntu/heketi/heketi.json
# cd heketi
# nohup ./heketi -config heketi.json &
SHELL
end
end
起動方法
上記のVagrantfile、必要なフォルダ、関連のファイルは、すべて GitHub の https://github.com/takara9/vagrant-glusterfs-heketi にありますので、IPアドレス以外に編集する箇所はありません。 ここから起動までのステップを記していきます。
次のコマンドで、必要なファイルをローカルに落として、作業をします。
git clone https://github.com/takara9/vagrant-glusterfs-heketi
クローンしたディレクトリに移動
cd vagrant-glusterfs-heketi
vagrantのプラグインをインストール
vagrant plugin install vagrant-cachier
ここで Vagrantfile の IPアドレスの編集をします。
終わったら、いよいよ、仮想サーバー4台の起動です。
vagrant up
上記のコマンドで、自分のPC上に、GlusterFSのクラスタとHeketiサーバーが起動して、ICP-CEからアクセスできる様になります。
Heketiのセットアップ
heketi-cliを使って、クラスタをセットアップするのですが、手順は、GitHub https://github.com/takara9/vagrant-glusterfs-heketi/blob/master/README.md にありますので、それに従って、セットアップを完了させます。
最後に、ICP-CEのサーバーにログインして、以下のcurlコマンドを実行してください。 以下の様に応答があれば完了です。
curl http://192.168.1.90:8080/hello
HelloWorld from GlusterFS Application
ICP-CEのセットアップ
ICP-CEは、v2.1.0.1のインストールが完了して、稼動状態にあるものと仮定して、セットアップを進めて行きます。 設定の参考資料は、Adding GlusterFS storage to your IBM® Cloud Private clusterにあります。このマニュアルは、現在のk8sのバージョンに対して、少し古い部分がありますので、Hello World application using GlusterFS Dynamic Provisioningも合わせて参考にしながら、進めます。
ICP-CEサーバーへの設定
ICP-CEのサーバーにログインして、sudo -s でrootで作業します。 dockerコマンドで実行するものは、Ansibleのplaybookを反映させるもので、ICP-CEが稼働するLinuxサーバーの設定を変更するものです。
cd /opt/ibm-cloud-private-ce-2.1.0.1/cluster
sudo -s
docker run --net=host -it -e LICENSE=accept -v $(pwd):/installer/cluster ibmcom/icp-inception:2.1.0.1 bash
コンテナのシェルから、以下を実行します。
./installer.sh install --tags "Glusterfs,always" -vv | tee cluster/gluster_install.txt
ストレージクラスの設定
次に、YAMLファイルを利用して、ストレージクラスの設定を行います。 heketiのIPアドレスは環境に合わせて修正をお願いします。 ユーザーとパスワードは、前述のVagrantfileから処理するheketi.jsonでユーザー認証を無効にしてあり、認証していないのですが、必要な行だけ入れておきます。
apiVersion: storage.k8s.io/v1beta1
kind: StorageClass
metadata:
name: "gluster-heketi"
provisioner: kubernetes.io/glusterfs
parameters:
resturl: "http://192.168.1.90:8080"
restuser: "admin"
restuserkey: "admin"
上記のYAMLを適用します。 以下を実行するには、bx pr login
と bx pr cluster-config mycluster
が実行されている事が必要です。
kubectl create -f heketi-glusterfs.yaml
次の様に、Storage Classが作られて入れば、OKです。
$ kubectl get sc
NAME PROVISIONER AGE
gluster-heketi kubernetes.io/glusterfs 5s
下記の様に、ICP-CE 2.1.0.1 の Kubernetes 1.8.3 では、前述のStorage Classを設定する事でGlusterFSのエンドポイントが、自動的に設定されます。
$ kubectl get ep
NAME ENDPOINTS AGE
glusterfs-dynamic-gluster-vol 192.168.1.91:1,192.168.1.92:1,192.168.1.93:1 18m
PVCの設定
アプリケーションを実行するポッドから永続ボリュームをマウントできる様に、PersistantVolumeClaimを定義する必要があります。
定義のYAMLファイルの例を以下にあげます。 以下は、前述で定義したストレージ・クラスを指定して10GiBのボリュームの確保を行ないます。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gluster-vol
annotations:
volume.beta.kubernetes.io/storage-class: gluster-heketi
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
上記のファイルを適用して、設定を反映します。
kubectl create -f heketi-pvc.yaml
上記が適用されると、GlusterFSのボリュームに、ロジカルボリュームが定義され、以下のサイズの永続ボリュームが利用できる様になります。
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
gluster-vol Bound pvc-707745ee-1c20-11e8-979e-0022cfe54f6d 11Gi RWX gluster-heketi 18s
ここで、ストレージのサイズが小さいと実行に失敗します。 筆者の環境では、7GiB以上のサイズでしか作成に成功しませんでした。
pvcを設定する事で、PersistentVolumeも自動的に設定されます。
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM
pvc-707745ee-1c20-11e8-979e-0022cfe54f6d 11Gi RWX Delete Bound default/gluster-vol
ICP-CEの管理画面の表示
kubectlコマンドから定義されたpvcは、管理コンソールでは次の様に表示されます。
ポッドからストレージの利用
永続ボリュームを利用するポッドとNodePortのセットを立ち上げて、前述の永続ボリュームをマウントしてみます。
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod1
labels:
app: nginx-pod1
spec:
containers:
- name: nginx-pod1
image: gcr.io/google_containers/nginx-slim:0.8
ports:
- name: web
containerPort: 80
volumeMounts:
- name: gluster-vol1
mountPath: /usr/share/nginx/html
volumes:
- name: gluster-vol1
persistentVolumeClaim:
claimName: gluster-vol
---
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport-service
spec:
type: NodePort
selector:
app: nginx-pod1
ports:
- protocol: TCP
port: 80
nodePort: 31590
この状態だと、ボリュームの中身は空ですから、curl http://192.168.1.100:31590
を実行しても、エラーメッセージが表示されるだけです、
そこで、このボッドにログインして、ファイルを作成します。
kubectl exec -ti nginx-pod1 /bin/sh
$ cd /usr/share/nginx/html
$ echo 'Hello World from GlusterFS!!!' > index.html
$ ls
index.html
$ exit
これで、GlusterFS上のデータが帰ってきました。
curl http://192.168.1.100:31590
Hello World from GlusterFS!!!
もう一つ名前とポート番号を変えて、ポッドを起動すると、今度は、共有するGlusterFSからindex.htmlで応答が帰ってきます。
imac:icp maho$ kubectl create -f nginx_pod2.yaml
pod "nginx-pod2" created
service "nginx-nodeport-service2" created
imac:icp maho$ kubectl get pods
NAME READY STATUS RESTARTS AGE
bash-client-84bb76f87b-2l7ps 1/1 Running 4 7d
first-apl-b5d79797b-fjzkz 1/1 Running 2 7d
nginx-pod1 1/1 Running 0 6m
nginx-pod2 0/1 ContainerCreating 0 25s
imac:icp maho$ kubectl get pods
NAME READY STATUS RESTARTS AGE
bash-client-84bb76f87b-2l7ps 1/1 Running 4 7d
first-apl-b5d79797b-fjzkz 1/1 Running 2 7d
nginx-pod1 1/1 Running 0 9m
nginx-pod2 1/1 Running 0 3m
imac:icp maho$ curl http://192.168.1.100:31592
Hello World from GlusterFS!!!
まとめ
IBM Cloud Private Community Editon は、無料で利用できて、ターンキーインストールができる良いソフトなのですが、複数のノードの対応する、動的に永続ボリュームは、他のストレージ・システムと接続する必要があります。手軽に検証ができる様に、VagrantfileでGlusterFSとHeketiを組み合わせたストレージを構築して、ICP-CEの検証を実施しました。 ICP-CEの設定後は、特別な設定をする事なく、Kubernetesのチュートリアルのページに従って、利用できる様にする事ができました。
参考資料
Glusterfs
- GlusterFS Documentation http://docs.gluster.org/en/latest/
- GlusterFS https://ja.wikipedia.org/wiki/GlusterFS
- GLUSTER https://www.gluster.org/
- Glusterfs / Storage Classes / Concept https://v1-8.docs.kubernetes.io/docs/concepts/storage/storage-classes/#glusterfs
Heketi
- Heketi GitHub https://github.com/heketi
- Heketi Home https://github.com/heketi/heketi/wiki
IBM Cloud Private
- Adding GlusterFS storage to your IBM® Cloud Private cluster https://www.ibm.com/support/knowledgecenter/SSBS6K_2.1.0/manage_cluster/add_glusterfs.html
- Adding GlusterFS storage https://www.ibm.com/support/knowledgecenter/SSBS6K_2.1.0/installing/storage_settings.html
- Creating a storage class for GlusterFS https://www.ibm.com/support/knowledgecenter/SSBS6K_2.1.0/manage_cluster/create_sc_glusterfs.html
- Creating a GlusterFS PersistentVolume https://www.ibm.com/support/knowledgecenter/SSBS6K_2.1.0/manage_cluster/create_glusterfs.html
- Increasing the storage capacity of a GlusterFS cluster https://www.ibm.com/support/knowledgecenter/SSBS6K_2.1.0/manage_cluster/increase_gluster_storage.html
Gluster-Kuberntes
- Gluster-Kuberntes https://github.com/gluster/gluster-kubernetes
- Hello World application using GlusterFS Dynamic Provisioning https://github.com/gluster/gluster-kubernetes/blob/master/docs/examples/hello_world/README.md
YouTube
- Provision Gluster Storage with REST API using Heketi
- Dynamically Provision Gluster Volumes for Kubernetes Persistent Volume Claims