RancherOS で構築した k8s クラスタ用に GlusterFS で簡単な分散ファイルシステムを構築
[履歴] [最終更新] (2019/01/22 09:55:34)
1
作品
409
技術情報
最近の投稿
ここは
趣味の電子工作を楽しむ人のためのハードウェア情報共有サイト

技術情報や作品の投稿機能、リアルタイム遠隔操作 API をご利用いただけます。
新着作品

概要

こちらのページで設定した k8s クラスタの各 Node マシンに GlusterFS サーバのコンテナを一つだけ起動して、簡単な分散ファイルシステムを構築します。各 Node へのコンテナ設置のためには DaemonSet が利用できそうですが、ここでは RancherOSrancher.services を利用します。

1台構成

後に rancher.services で起動することを想定して、Debian stretch のイメージでコンテナ内に GlusterFS を設定してみます。GlusterFS は fuse を利用するため適切な権限を付与します。

docker run -h mygluster --cap-add SYS_ADMIN --device /dev/fuse -it --rm debian:stretch /bin/bash

apt インストール

apt update
apt install -y glusterfs-server

サービスの起動および自動起動の設定

/etc/init.d/glusterfs-server start
update-rc.d glusterfs-server defaults

自動起動の設定削除および確認をしたい場合

update-rc.d -f glusterfs-server remove
apt install sysv-rc-conf
sysv-rc-conf

brick を一つだけ作成して、brick をもとに volume を作成

mkdir -p /data/glusterfs/brick0
gluster volume create gv0 mygluster:/data/glusterfs/brick0 force
gluster volume info | grep Status #Status: Created
gluster volume start gv0
gluster volume info | grep Status #Status: Started

マウントして利用できるか確認

mkdir -p /mnt/glusterfs
mount -t glusterfs mygluster:/gv0 /mnt/glusterfs

ログは以下の場所で確認できます

/var/log/glusterfs

ホスト側のディレクトリをマウントしておくとデータを永続化できます。gluster volume create ではディレクトリの内容が削除されません。

docker run -h mygluster --cap-add SYS_ADMIN --device /dev/fuse -it --rm -v /data/glusterfs:/data/glusterfs debian:stretch /bin/bash

ホスト外からマウントするためには更に --net=host を付与します。-h mygluster は付与しません。コンテナのホスト名はホストと同じになります。

docker run --cap-add SYS_ADMIN --device /dev/fuse --net=host -it --rm -v /data/glusterfs:/data/glusterfs debian:stretch /bin/bash
gluster volume create gv0 myhostname:/data/glusterfs/brick0 force

RancherOS の場合

rancher.services の設定は以下のようにできます。

hostname: myhostname
rancher:
  services:
    user-volumes:
      volumes:
      - /home:/home
      - /opt:/opt
      - /var/lib/kubelet:/var/lib/kubelet
      - /data/glusterfs:/data/glusterfs
    glusterfs-server:
      image: my-glusterfs-server:latest
      restart: unless-stopped
      volumes:
      - /data/glusterfs:/data/glusterfs
      cap_add:
      - SYS_ADMIN
      devices:
      - /dev/fuse:/dev/fuse
      environment:
        SERVER_NAME: myhostname
        VOLUME_NAMES: gv0 gv1 gv2
      net: host

Dockerfile

FROM debian:stretch
RUN apt-get update && apt-get install -y glusterfs-server
COPY entrypoint.bash /usr/bin/entrypoint.bash
ENTRYPOINT /usr/bin/entrypoint.bash

entrypoint.bash

#!/bin/bash
set -e

/etc/init.d/glusterfs-server stop || true
/etc/init.d/glusterfs-server start

echo ${VOLUME_NAMES}
VOLUME_NAMES=(`echo $VOLUME_NAMES`)

for VOLUME_NAME in ${VOLUME_NAMES[@]}; do
    echo ${VOLUME_NAME}
    mkdir -p /data/glusterfs/${VOLUME_NAME}
    gluster volume create ${VOLUME_NAME} ${SERVER_NAME}:/data/glusterfs/${VOLUME_NAME} force || true
    gluster volume start ${VOLUME_NAME} || true
done

tail -f /var/log/glusterfs/cmd_history.log

build.bash

#!/bin/bash
set -eu

docker build . -t my-glusterfs-server:latest

動作検証

./build.bash
docker run --cap-add SYS_ADMIN --device /dev/fuse --net=host --rm -v /data/glusterfs:/data/glusterfs \
  -e "SERVER_NAME=`hostname`" \
  -e "VOLUME_NAMES=gv0 gv1 gv2" \
  my-glusterfs-server:latest

Pod からの利用設定

直接 mount する方法もありますが、以下では Persistent Volume として設定しています。

apiVersion: v1
kind: Service
metadata:
  name: glusterfs
spec:
  ports:
  - port: 1
---
apiVersion: v1
kind: Endpoints
metadata:
  name: glusterfs
subsets:
- addresses:
  - ip : 10.0.2.15 # myhostname IP
  ports:
  - port: 1
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: gv0-pv
  labels:
    name: gv0-pv
spec:
  accessModes:
  - ReadWriteMany
  capacity:
    storage: 32Gi
  glusterfs:
    endpoints: glusterfs
    path: gv0
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: gv0-pvc
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 32Gi
  selector:
    matchLabels:
      name: gv0-pv
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  volumes:
  - name: external
    persistentVolumeClaim:
      claimName: gv0-pvc
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - mountPath: /external
      name: external

複数台構成

手動で設定を把握

複数台構成を把握する目的で、以下のようにコンテナを三つ同じ docker ネットワーク内に起動してみます。実際には別々のサーバで一つのコンテナを --net=host を付与して起動します。

docker network create --subnet=172.18.0.0/16 mygluster
docker run -h mygluster1 --name mygluster1 --net mygluster --ip 172.18.0.101 --cap-add SYS_ADMIN --device /dev/fuse -it --rm debian:stretch /bin/bash
docker run -h mygluster2 --name mygluster2 --net mygluster --ip 172.18.0.102 --cap-add SYS_ADMIN --device /dev/fuse -it --rm debian:stretch /bin/bash
docker run -h mygluster3 --name mygluster3 --net mygluster --ip 172.18.0.103 --cap-add SYS_ADMIN --device /dev/fuse -it --rm debian:stretch /bin/bash

apt update
apt install -y glusterfs-server
/etc/init.d/glusterfs-server start
mkdir -p /data/glusterfs/gv0

例えば mygluster1 から mygluster2 と mygluster3 を追加する場合

gluster peer probe mygluster2
gluster peer probe mygluster3
gluster peer status

mygluster1 と mygluster2 および mygluster3 は同じ扱いで主従関係はありません。以下のコマンドはいずれのホストで実行しても動作します。

gluster volume create gv0 replica 3 mygluster1:/data/glusterfs/gv0 mygluster2:/data/glusterfs/gv0 mygluster3:/data/glusterfs/gv0 force
gluster volume start gv0
gluster volume info

実行例

root@mygluster1:/# gluster volume info

Volume Name: gv0
Type: Replicate
Volume ID: 0216131f-643f-485c-a35e-3775d3c9c25b
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 3 = 3
Transport-type: tcp
Bricks:
Brick1: mygluster1:/data/glusterfs/gv0
Brick2: mygluster2:/data/glusterfs/gv0
Brick3: mygluster3:/data/glusterfs/gv0
Options Reconfigured:
transport.address-family: inet
performance.readdir-ahead: on
nfs.disable: on

ボリュームのタイプ

冗長性なし

gluster volume create gv0 mygluster1:/data/glusterfs/gv0 mygluster2:/data/glusterfs/gv0 mygluster3:/data/glusterfs/gv0 mygluster4:/data/glusterfs/gv0 force

すべて同じデータを保持

gluster volume create gv0 replica 4 mygluster1:/data/glusterfs/gv0 mygluster2:/data/glusterfs/gv0 mygluster3:/data/glusterfs/gv0 mygluster4:/data/glusterfs/gv0 force

同じデータを二つのサーバで保持

gluster volume create gv0 replica 2 mygluster1:/data/glusterfs/gv0 mygluster2:/data/glusterfs/gv0 mygluster3:/data/glusterfs/gv0 mygluster4:/data/glusterfs/gv0 force

新規にサーバを追加した場合のオペレーション例

mygluster1 と mygluster2 で volume create して start

gluster pool list
gluster peer status
gluster volume list
gluster volume create gv0 replica 2 mygluster1:/data/glusterfs/gv0 mygluster2:/data/glusterfs/gv0 force
gluster volume start gv0
gluster volume info gv0
gluster volume status gv0
#gluster volume stop gv0
#gluster volume delete gv0

mygluster3 と mygluster4 を pool に追加

gluster peer probe mygluster3
gluster peer probe mygluster4
gluster pool list
gluster volume add-brick gv0 mygluster3:/data/glusterfs/gv0 mygluster4:/data/glusterfs/gv0 force
gluster volume info gv0
gluster volume rebalance gv0 start #force
gluster volume rebalance gv0 status
#gluster volume rebalance gv0 stop

RancherOS の場合の簡単な設定例

簡単のため便宜的な master とその他で設定を分けてみます。SERVER_NAMES 等の環境変数を変更すると docker コンテナ自体が再作成されますが、brick ディレクトリ内のデータは削除されずに引き継がれます。

便宜的な master

rancher.services の設定は以下のようにできます。

hostname: myhostname-master
rancher:
  services:
    user-volumes:
      volumes:
      - /home:/home
      - /opt:/opt
      - /var/lib/kubelet:/var/lib/kubelet
      - /data/glusterfs:/data/glusterfs
    glusterfs-server:
      image: my-glusterfs-server-master:latest
      restart: unless-stopped
      volumes:
      - /data/glusterfs:/data/glusterfs
      cap_add:
      - SYS_ADMIN
      devices:
      - /dev/fuse:/dev/fuse
      environment:
        SERVER_NAMES: myhostname-master myhostname1
        VOLUME_NAMES: gv0 gv1 gv2
      net: host

Dockerfile

FROM debian:stretch
RUN apt-get update && apt-get install -y glusterfs-server
COPY entrypoint-master.bash /usr/bin/entrypoint-master.bash
ENTRYPOINT /usr/bin/entrypoint-master.bash

entrypoint-master.bash

replica 2 としているため、SERVER_NAMES で指定した先頭から二つずつが組になります。以下の例では myhostname-master myhostname1 が組です。SERVER_NAMES: myhostname-master myhostname1 myhostname2 myhostname3 とした場合は更に myhostname2 myhostname3 が組になります。

the order in which bricks are specified has a great effect on data protection.
https://docs.gluster.org/en/latest/Administrator%20Guide/Setting%20Up%20Volumes/#creating-distributed-replicated-volumes

#!/bin/bash
set -e

/etc/init.d/glusterfs-server stop || true
/etc/init.d/glusterfs-server start

VOLUME_NAMES=(`echo $VOLUME_NAMES`)
SERVER_NAMES=(`echo $SERVER_NAMES`)

while [ `gluster pool list | grep Connected | wc -l` -ne ${#SERVER_NAMES[@]} ]; do
    for SERVER_NAME in ${SERVER_NAMES[@]}; do
        echo ${SERVER_NAME}
        gluster peer probe ${SERVER_NAME} || true
    done
done

for VOLUME_NAME in ${VOLUME_NAMES[@]}; do
    echo ${VOLUME_NAME}
    mkdir -p /data/glusterfs/${VOLUME_NAME}
    CMD="gluster volume create ${VOLUME_NAME} replica 2"
    for SERVER_NAME in ${SERVER_NAMES[@]}; do
        CMD="${CMD} ${SERVER_NAME}:/data/glusterfs/${VOLUME_NAME}"
    done
    ${CMD} force || true
    gluster volume start ${VOLUME_NAME} || true
    gluster volume rebalance ${VOLUME_NAME} start || true
done

tail -f /var/log/glusterfs/cmd_history.log

build.bash

#!/bin/bash
set -eu

docker build . -t my-glusterfs-server-master:latest

その他のホスト

hostname: myhostname1
rancher:
  services:
    user-volumes:
      volumes:
      - /home:/home
      - /opt:/opt
      - /var/lib/kubelet:/var/lib/kubelet
      - /data/glusterfs:/data/glusterfs
    glusterfs-server:
      image: my-glusterfs-server:latest
      restart: unless-stopped
      volumes:
      - /data/glusterfs:/data/glusterfs
      cap_add:
      - SYS_ADMIN
      devices:
      - /dev/fuse:/dev/fuse
      environment:
        VOLUME_NAMES: gv0 gv1 gv2
      net: host

Dockerfile

FROM debian:stretch
RUN apt-get update && apt-get install -y glusterfs-server
COPY entrypoint.bash /usr/bin/entrypoint.bash
ENTRYPOINT /usr/bin/entrypoint.bash

entrypoint.bash

#!/bin/bash
set -e

/etc/init.d/glusterfs-server stop || true
/etc/init.d/glusterfs-server start

echo ${VOLUME_NAMES}
VOLUME_NAMES=(`echo $VOLUME_NAMES`)

for VOLUME_NAME in ${VOLUME_NAMES[@]}; do
    echo ${VOLUME_NAME}
    mkdir -p /data/glusterfs/${VOLUME_NAME}
done

tail -f /var/log/glusterfs/cmd_history.log

build.bash

#!/bin/bash
set -eu

docker build . -t my-glusterfs-server:latest

IO の状態を確認

マウントしているクライアント

gluster volume status gv0 clients

各 brick における読み出し、書き込み、ファイルオープン回数の調査

gluster volume top gv0 read
gluster volume top gv0 write
gluster volume top gv0 open

各 brick のプロファイリング

gluster volume profile gv0 start
gluster volume profile gv0 info
gluster volume profile gv0 stop
関連ページ