1. はじめに
複数のサーバでコンテナを運用する際、コンテナ内で動作するアプリケーションが保存するファイルをどのように保持するかを考える必要があります。Kubernetesでは、CephやGlusterFSなどの分散ストレージが利用できます。この記事では、十数台程度の小規模なオンプレミスのdocker実行環境で、GlusterFSによるデータ保持機構を構築するときに検討した内容をまとめたものです(下図のように、コンテナの参照先をファイルサーバにすることで、どのサーバでコンテナが稼働しても同じデータを参照できます。)。
記事にまとめるにあたり、「オンプレミスな環境で0からGluster側の構築を如何に簡単に行うか」に焦点を当てるため、以降の説明ではアプリケーションサーバは1台、Glusterサーバは2台とします。
2. ねらい
参考1:GlusterFS Containers
参考2:Official GlusterFS Image [ CentOS-7 + GlusterFS ]
- 本番環境の構築を易化するため、Glusterサーバはコンテナで構築する。検証として、Glusterコンテナは、Officialのものを活用する。
- 本番環境は、ホスト側にネットワークが構築された環境であり、参考1にあるよう本番環境では、--net=hostオプションを使用する。ただし、開発環境で常に2サーバ用意するのは手間なので、開発環境ではdokcer networkを用いて本番環境を模擬する。(ネットワークアドレスは仮のものです)
3. 検討
3.1. 基本的なこと
- 本番環境のGlusterサーバのホスト名は、それぞれserver1とserver2とする。
- Glusterコンテナの内部ホスト名は、gluster-server-1とgluster-server-2とする。
- 参考1より、Glusterコンテナは/sbin/initで起動し、glusterdをサービス起動する。D-Bus関連のサービスはdisableとなっているが、privilegedオプションを使用する。
- systemdを使用する関係で、CMD設定を/sbin/initから変更できないので、entry-pointを仕込むためにentry-point.service(このサービスでentry-point.shを呼び出す)を設定する。
- Glusterのボリューム名はVOL1とし、それぞれ/home/HDD1にBrickを作成する。
3.2. Glusterの設定を構築し、コンテナイメージに組み込む方法
- 開発環境に、以下のようなdocker-compose.ymlでコンテナを構築する。マウントディレクトリの選定は、参考1で示されたディレクトリに加えて、Brickの隠しディレクトリがあるHDD1を指定している。
version: "3.7"
services:
gluster-server-1:
hostname: gluster-server-1
image: gluster/gluster-centos:gluster3u10_centos7
volumes:
- ${PWD}/volume/gluster-server-1/etc-glusterfs:/etc/glusterfs
- ${PWD}/volume/gluster-server-1/var-lib-glusterd:/var/lib/glusterd
- ${PWD}/volume/gluster-server-1/HDD1:/home/HDD1
extra_hosts:
- "gluster-server-2:192.168.3.20"
privileged: true
networks:
app_net:
ipv4_address: 192.168.3.10
gluster-server-2:
hostname: gluster-server-2
image: gluster/gluster-centos:gluster3u10_centos7
volumes:
- ${PWD}/volume/gluster-server-2/etc-glusterfs:/etc/glusterfs
- ${PWD}/volume/gluster-server-2/var-lib-glusterd:/var/lib/glusterd
- ${PWD}/volume/gluster-server-2/HDD1:/home/HDD1
extra_hosts:
- "gluster-server-1:192.168.3.10"
privileged: true
networks:
app_net:
ipv4_address: 192.168.3.20
networks:
app_net:
name: app_net
driver: bridge
ipam:
driver: default
config:
- subnet: 192.168.3.0/24
- docker-compose up -dでコンテナ起動後、参考3に従って設定を行う。この設定を行うことで、必要なコンフィグファイルをマウントディレクトリに格納される。
- docker buildでコンテナイメージ内に組み込むのだが、設定ファイルを以下のように配置する。リンク作成やディレクトリ移動は、起動時に呼ばれるentry-point.serviceを組み込み、その中で実施する。
- Dockerfileは以下のように作成した。
FROM gluster/gluster-centos:gluster3u10_centos7
COPY ./volume /tmp/volume
COPY ./script /tmp/script
RUN systemctl disable glusterd.service; systemctl disable gluster-setup.service; \
mkdir -p /home/gluster; \
mv /tmp/volume/gluster-server-1 /home/gluster/; mv /tmp/volume/gluster-server-2 /home/gluster/; \
mkdir -p /home/HDD1; \
mv /tmp/script/entry-point.service /etc/systemd/system/; \
systemctl enable entry-point.service; \
mv /tmp/script/entry-point.sh /entry-point.sh; \
rm -rf /tmp/*
- entry-point.shは以下のように作成した。
#!/bin/bash
function main() {
echo "entry-point start." > /tmp/start.log
# delete default gluster setting
rm -rf /etc/glusterfs
rm -rf /var/lib/glusterd
# gluster-server-1 ?
echo $HOSTNAME | grep "gluster-server-1" >/dev/null
local ret=$?
local gluster=""
if [ $ret = "0" ]; then
gluster="gluster-server-1"
fi
# gluster-server-2 ?
echo $HOSTNAME | grep "gluster-server-2" >/dev/null
ret=$?
if [ $ret = "0" ]; then
gluster="gluster-server-2"
fi
mv /home/gluster/$gluster/etc-glusterfs /etc/glusterfs
mv /home/gluster/$gluster/var-lib-glusterd /var/lib/glusterd
local init_flag="0"
if [ -d /home/HDD1/.glusterfs ]; then
# non-first start
echo "exist /home/HDD1/.glusterfs" >>/tmp/start.log
else
# first start
echo "no exist /home/HDD1/.glusterfs" >>/tmp/start.log
echo "mv /home/gluster/$gluster/HDD1/.glusterfs /home/HDD1/" >>/tmp/start.log
mv /home/gluster/$gluster/HDD1/.glusterfs /home/HDD1/
init_flag="1"
fi
sleep 1
# starting glusterd
systemctl restart glusterd
if [ $init_flag != "0" ]; then
sleep 10
# gluster force-restart
echo "gluster vol start VOL1 force" >>/tmp/start.log
gluster vol start VOL1 force
fi
echo "entry-point started." >>/tmp/start.log
return 0
}
main
exit 0
3.3 本番環境へデプロイする設定
- 実行環境で動作させるためのdocker-compose.ymlを以下のように作成し、コンテナイメージのsaveデータを展開して動作させる。(コンテナイメージ名は適当につけているため、docker build時に適切な名前を設定すること。)
version: "3.7"
services:
gluster-server-1:
hostname: gluster-server-1
image: my-gluster:0.0
volumes:
- ${PWD}/HDD1:/home/HDD1
- ${PWD}/log:/var/log/glusterfs
extra_hosts:
- "gluster-server-1:192.168.3.10"
- "gluster-server-2:192.168.3.20"
privileged: true
network_mode: host
gluster-server-2:
hostname: gluster-server-2
image: my-gluster:0.0
volumes:
- ${PWD}/HDD1:/home/HDD1
- ${PWD}/log:/var/log/glusterfs
extra_hosts:
- "gluster-server-1:192.168.3.10"
- "gluster-server-2:192.168.3.20"
privileged: true
network_mode: host
3.4 プロジェクトの全体構成
上記の情報をまとめると、以下のような構成となった。setupが開発環境で構築する内容で、deployが本番環境の設定をまとめるところ、としている。
4. まとめ
自分がこの構成を検討するとき、なかなかGlusterの設定内容をコンテナイメージ内に組み込んでデプロイする事例が見つからなかったため、備忘録として記事にまとめてみました。コンテナ内でglusterを起動するときに、事前にコンフィグを移動したり、強制起動し直す、といったハマるポイントがあったので注意が必要です。
また、検証の側面が強かったので、IPアドレスとかの設定が直書きです。そのあたりを環境変数にするなど、実際にデプロイするものに仕上げるにはもう少し改良が必要です。
(2021/3/28 追記)
本記事の設定スクリプトやまとめでの改善内容を加味したものをGithubにコミットしました。
https://github.com/tomoten-umino/portable-gluster