モーダルを閉じる工作HardwareHub ロゴ画像

工作HardwareHubは、ロボット工作や電子工作に関する情報やモノが行き交うコミュニティサイトです。さらに詳しく

利用規約プライバシーポリシー に同意したうえでログインしてください。

工作HardwareHub ロゴ画像 (Laptop端末利用時)
工作HardwareHub ロゴ画像 (Mobile端末利用時)

RancherOS で構築した k8s クラスタ用に GlusterFS で簡単な分散ファイルシステムを構築

モーダルを閉じる

ステッカーを選択してください

モーダルを閉じる

お支払い内容をご確認ください

購入商品
」ステッカーの表示権
メッセージ
料金
(税込)
決済方法
GooglePayマーク
決済プラットフォーム
確認事項

利用規約をご確認のうえお支払いください

※カード情報はGoogleアカウント内に保存されます。本サイトやStripeには保存されません

※記事の執筆者は購入者のユーザー名を知ることができます

※購入後のキャンセルはできません

作成日作成日
2019/01/13
最終更新最終更新
2021/10/07
記事区分記事区分
一般公開

目次

    学生(?)エンジニア

    0
    ステッカーを贈るとは?

    k8s クラスタの各 Node マシンに GlusterFSサーバのコンテナを一つだけ起動して、簡単な分散ファイルシステムを構築します。各 Node へのコンテナ設置のためには DaemonSet が利用できそうですが、ここでは RancherOS の rancher.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
    
    0
    詳細設定を開く/閉じる
    アカウント プロフィール画像 (本文下)

    学生(?)エンジニア

    記事の執筆者にステッカーを贈る

    有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。

    さらに詳しく →
    ステッカーを贈る コンセプト画像

    Feedbacks

    Feedbacks コンセプト画像

      ログインするとコメントを投稿できます。

      関連記事