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 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
新規にサーバを追加した場合のオペレーション例
- Managing GlusterFS Volumes
- Gluster Command Line Interface
- Managing Trusted Storage Pools (TSP)
- Managing Directory Quota
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
関連記事
- Rancher で構築した kubernetes クラスタのアップグレード手順RancherOS 等、docker が使える何らかの OS で Rancher によって構築した kubernetes クラスタのアップグレードを行うためには、以下のようにします。 v2.1.5 の Rancher で構築した k8s クラスタに存在する脆弱性 CVE-2019-11253 への対応がなされた [v2.3.2](https://github.com
- Docker CLI チートシートDocker に関するコマンド逆引き集です。公式ページの「Reference documentation」情報をもとにしています。 Docker 用語について コンテナ 後述のイメージという型をもとに作られる実体です。例えるならば、オブジェクト指向プログラミングにおけるクラスが Docker イメージで、インスタンスが Docker コンテナです。ある
- 複数の物理ホストの Debian9 上に Kubernetes (k8s) クラスタを Rancher で立ち上げるDocker オーケストレーションツールの一つに Kubernetes (k8s) があります。k8s 実行環境の構築方法は複数ありますが、ここでは AWS や GCP 等のクラウドサービスを利用せず、Debian9 がインストールされた複数台の物理マシンがネットワーク内に存在する状況を考えます。これら複数の Debian9 上に k8s クラスタを立ち上げるためには [Ranche
- Dockerfile ベストプラクティス (仮)Dockerfile を書く際に気になるポイント集です。「Best practices for writing Dockerfiles」および「Dockerfile Reference」をもとにしています。 Dockerfil
- RancherOS による Kubernetes クラスタの構築Kubernetes クラスタを RancherOS で構築する場合の設定例を記載します。 インストール ISO ファイルをダウンロードして起動すると ros コマンドが利用できるコンソールに入ります。インストール可能なバージョン一覧はコンソール上で以下のコマンドによって確認できます。 sud