GlusterFS分散ファイルシステムの概要
基本概念
分散ストレージは主に以下の3つのインターフェースで分類されます:ファイルストレージ、ブロックストレージ、オブジェクトストレージ。
- ファイルストレージ:POSIXインターフェースをサポートします(例:GlusterFS)。通常のファイルシステム(例えばext4)のようにアクセス可能ですが、並列アクセスと冗長性機能を持っています。主なシステムにはTFS、CephFS、GlusterFS、HDFSなどがあります。非構造化データ(ファイル、画像、音声・動画)を扱います。
- ブロックストレージ:QEMUドライバーやカーネルモジュールとして動作し、主にqemuまたはiscsiプロトコルを通じてアクセスします。代表的なシステムにはCephブロックストレージ、SheepDogがあります。構造化データ(例:データベース)を扱います。
- オブジェクトストレージ:NASとSANの利点を融合し、高速アクセスとデータ共有を提供します。オブジェクトを基本単位として、RESTfulインターフェースでデータを操作します。AWS、Swift、Cephオブジェクトストレージなどが該当します。非構造化データを扱います。
GlusterFSは、スケールアウト型ストレージソリューションの中心であり、水平拡張が可能なオープンソースの分散ファイルシステムです。数千のクライアントに対応し、数PBのストレージ容量をサポートできます。TCP/IPまたはInfiniBand RDMAネットワークを使用して分散されたストレージを統合し、高拡張性、高可用性、高性能を実現します。メタデータサーバーがなく、サービス全体にシングルポイントフォールトがない設計で、グローバル名前空間によりデータ管理が可能です。
GlusterFSのアーキテクチャ
特徴
- 利点:
- 拡張性とパフォーマンス:中心化された構造ではなく、メタデータサーバーがないため、ボトルネックがありません。ファイルの属性と拡張属性にメタデータが含まれており、DHTアルゴリズムによりファイルの位置を特定し、通信を省略できます。
- 良好な拡張性:従来のメタデータノード方式ではなく、弾性ハッシュアルゴリズムにより線形近似の拡張性を実現します。
- 高可用性:レプリカやECによる冗長設計により、ノード障害時もデータの整合性を保ちます。弱い一貫性設計により、書き込み成功を1つでも確認すれば完了と判断し、他のノードとの同期を待たずに高速に処理できます。また、定期的にデータの一貫性をチェックし修復するglustershdプロセスが稼働します。
- 柔軟なストレージプール:粗粒度、ストライプ、レプリカ、ストライプレプリカ、ECなど多様なタイプに対応し、必要に応じて冗長性を調整できます。それぞれの特徴は以下の通りです。
- 粗粒度:冗長なし。ファイル全体を1つのbrickに保存。
- ストライプ:冗長なし。ファイルを複数のbrickに分割して保存し、並列読み書き可能。
- レプリカ:高冗長性。レプリカ数を自由に設定可能。
- ストライプレプリカ:ストライプとレプリカの組み合わせ。
- EC:EC検証アルゴリズムにより、低冗長性(例:2+1)を提供。
- 欠点:
- スケール変更時の影響範囲:brickを追加・削除すると、ハッシュ空間が再計算され、既存ファイルの再配置が必要で、システム負荷が増加します。
- ディレクトリの走査速度:メタデータノードがないため、ハッシュアルゴリズムでファイル位置を決定します。ディレクトリ走査では各brickから情報を集約する必要があり、大量ファイルの場合は遅くなります。
- 小ファイルのパフォーマンス:大ファイル向けに設計されており、小ファイルには最適化されていません。メタデータとデータが同じ場所にあり、アクセス速度が同じになるため、パフォーマンスが劣化します。
GlusterFSコンポーネント
- Brick:ストレージ単位。信頼されたストレージプール内のサーバーのエクスポートディレクトリです。'SERVER:EXPORT'形式で識別されます。brickはXFSまたはext4でフォーマットされた物理ディスクで構成され、その制限を継承します。1ノードに複数のbrickを設置できます。理想的にはクラスタ内のすべてのbrickが同じサイズであるべきです。
- Client:GlusterFSボリュームをマウントしたデバイス。
- GFID:GlusterFSボリューム内の各ファイルやディレクトリに割り当てられる128ビットの一意の識別子。
- Namespace:各GlusterボリュームはPOSIXマウントポイントとして単一の名前空間を提供します。
- Node:複数のbrickを持つデバイス。
- RDMA:リモート直接メモリアクセス。OSを介さず直接メモリにアクセスします。
- RRDNS:ラウンドロビンDNS。負荷分散の目的でDNSが異なるデバイスを返します。
- Self-heal:レプリカボリューム内のファイルやディレクトリの不整合を検出し、修復します。
- Split-brain:クラスタ内のノード間でのデータの不整合状態。
- Volfile:GlusterFSプロセスの設定ファイル。通常は/var/lib/glusterd/vols/volnameにあります。
- Volume:brickの論理的結合。作成時に識別名を付与します。
- Trusted Storage Pool:複数のストレージノードの集合。1つのノードが他のノードを招待して構築され、動的に追加・削除可能です。
GlusterFSクラスタの構築
KubernetesでGlusterFSを動的ストレージとして使用する場合、少なくとも3ノードが必要です。ノードが不足すると、ボリューム作成時に「No space」エラーが発生します。
使用するノードは以下の通り:
| ホスト名 | IPアドレス | データディスク |
|---|---|---|
| glusterfs-01 | 192.168.1.123 | /dev/sdb、/dev/sdc |
| glusterfs-02 | 192.168.1.125 | /dev/sdb、/dev/sdc |
| glusterfs-03 | 192.168.1.127 | /dev/sdb |
5.1 GlusterFSクラスタのセットアップ
- 全ノードでglusterパッケージをインストール
[root@glusterfs-01 ~]# yum install centos-release-gluster -y [root@glusterfs-01 ~]# yum install -y glusterfs glusterfs-server glusterfs-fuse glusterfs-rdma glusterfs-geo-replication glusterfs-devel - glusterFSサービスを起動
[root@glusterfs-01 ~]# systemctl start glusterd.service [root@glusterfs-01 ~]# systemctl enable glusterd.service [root@glusterfs-01 ~]# systemctl status glusterd.service - 任意のノードから他のノードをpeerとして追加
[root@glusterfs-01 ~]# gluster peer probe glusterfs-01 [root@glusterfs-01 ~]# gluster peer probe glusterfs-02 [root@glusterfs-01 ~]# gluster peer probe glusterfs-03 - 全ノードのデータディスクをフォーマットし、物理ボリュームを作成
[root@glusterfs-01 ~]# mkfs.xfs /dev/sdb -f [root@glusterfs-01 ~]# pvcreate /dev/sdb [root@glusterfs-01 ~]# mkfs.xfs /dev/sdc -f [root@glusterfs-01 ~]# pvcreate /dev/sdc
5.2 GlusterFSの動的ストレージをKubernetesで構成
HeketiはRESTfulインターフェースでGlusterFSボリュームを管理し、動的プロビジョニングを可能にします。Heketiはクラスタ内でbrickを選択し、必要なボリュームを構築します。
- 全ノードにheketiとheketi-clientをインストール
[root@glusterfs-01 ~]# yum install -y heketi heketi-client - 主ノードでSSHキーを設定
[root@glusterfs-01 ~]# ssh-keygen -f /etc/heketi/heketi_key -t rsa -N '' [root@glusterfs-01 ~]# ssh-copy-id -i /etc/heketi/heketi_key.pub root@glusterfs-01 [root@glusterfs-01 ~]# ssh-copy-id -i /etc/heketi/heketi_key.pub root@glusterfs-02 [root@glusterfs-01 ~]# ssh-copy-id -i /etc/heketi/heketi_key.pub root@glusterfs-03 [root@glusterfs-01 ~]# chown heketi:heketi /etc/heketi/heketi_key* - heketi設定ファイル(/etc/heketi/heketi.json)を編集
{ "_port_comment": "Heketi Server Port Number", "port": "8080", "_use_auth": "Enable JWT authorization. Please enable for deployment", "use_auth": false, "_jwt": "Private keys for access", "jwt": { "_admin": "Admin has access to all APIs", "admin": { "key": "My Secret" }, "_user": "User only has access to /volumes endpoint", "user": { "key": "My Secret" } }, "_glusterfs_comment": "GlusterFS Configuration", "glusterfs": { "_executor_comment": [ "Execute plugin. Possible choices: mock, ssh", "mock: This setting is used for testing and development.", " It will not send commands to any node.", "ssh: This setting will notify Heketi to ssh to the nodes.", " It will need the values in sshexec to be configured.", "kubernetes: Communicate with GlusterFS containers over", " Kubernetes exec api." ], "executor": "ssh", "_sshexec_comment": "SSH username and private key file information", "sshexec": { "keyfile": "/etc/heketi/heketi_key", "user": "root", "port": "22", "fstab": "/etc/fstab" }, "_kubeexec_comment": "Kubernetes configuration", "kubeexec": { "host" :"https://kubernetes.host:8443", "cert" : "/path/to/crt.file", "insecure": false, "user": "kubernetes username", "password": "password for kubernetes user", "namespace": "OpenShift project or Kubernetes namespace", "fstab": "Optional: Specify fstab file on node. Default is /etc/fstab" }, "_db_comment": "Database file name", "db": "/var/lib/heketi/heketi.db", "_loglevel_comment": [ "Set log level. Choices are:", " none, critical, error, warning, info, debug", "Default is warning" ], "loglevel" : "debug" } } - 全ノードでheketiサービスを自動起動し起動
[root@glusterfs-01 ~]# systemctl restart heketi [root@glusterfs-01 ~]# systemctl enable heketi - Heketi接続テスト
[root@glusterfs-01 ~]# curl http://glusterfs-01:8080/hello Hello from Heketi - 主ノードでHEKETI_CLI_SERVER環境変数を設定
[root@glusterfs-01 ~]# export HEKETI_CLI_SERVER=http://glusterfs-01:8080 - topology-sample.jsonを編集し、ノードとデバイスを登録
{ "clusters": [ { "nodes": [ { "node": { "hostnames": { "manage": [ "glusterfs-01" ], "storage": [ "192.168.1.123" ] }, "zone": 1 }, "devices": [ { "name": "/dev/sdb", "destroydata": false }, { "name": "/dev/sdc", "destroydata": false } ] }, { "node": { "hostnames": { "manage": [ "glusterfs-02" ], "storage": [ "192.168.1.125" ] }, "zone": 1 }, "devices": [ { "name": "/dev/sdb", "destroydata": false }, { "name": "/dev/sdc", "destroydata": false } ] }, { "node": { "hostnames": { "manage": [ "glusterfs-03" ], "storage": [ "192.168.1.127" ] }, "zone": 1 }, "devices": [ { "name": "/dev/sdb", "destroydata": false } ] } ] } ] } - ノードとデバイスを登録
[root@glusterfs-01 ~]# heketi-cli topology load --json=/usr/share/heketi/topology-sample.json - ボリュームの作成テスト
[root@glusterfs-01 ~]# heketi-cli volume create --size=2 - ボリューム情報の確認
[root@glusterfs-01 ~]# gluster volume info
5.3 StorageClassの設定
glusterfs-storageclass.yamlを作成:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gluster-dynmic
provisioner: kubernetes.io/glusterfs
parameters:
resturl: http://192.168.1.123:8080
restauthenabled: "false"
StorageClassを適用:
[root@glusterfs-01 ~]# kubectl create -f glusterfs-storageclass.yaml
5.4 PVCのテスト
pvc.yamlを作成:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gluster-dyn-pvc
annotations:
volume.beta.kubernetes.io/storage-class: gluster-dynmic
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2Gi
PVCを作成:
[root@glusterfs-01 ~]# kubectl create -f pvc.yaml
5.5 Podでの確認
PodとPVCの状態を確認:
[root@glusterfs-01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-6668bbf547-rvmfb 1/1 Running 0 106m
redis-c744fd4c9-5p44g 1/1 Running 0 96m
[root@glusterfs-01 ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
bigdata-pv-claim Bound pvc-1c74445b-19f9-11e9-9f58-000c29c0255c 2Gi RWX gluster-dynmic 108m
gluster-dyn-pvc Bound pvc-0c1cb408-1a08-11e9-9f58-000c29c0255c 2Gi RWX gluster-dynmic 109s
log-pv-claim Bound pvc-1c77ffc0-19f9-11e9-9f58-000c29c0255c 2Gi RWX gluster-dynmic 108m
mysql-pv-claim Bound pvc-1c771e55-19f9-11e9-9f58-000c29c0255c 2Gi RWX gluster-dynmic 108m
shared-pv-claim Bound pvc-1c762bd8-19f9-11e9-9f58-000c29c0255c 2Gi RWX gluster-dynmic 108m
ノードの追加
monmaptool --add node1 10.0.2.21:6789 --add node2 10.0.2.22:6789 --add node3 10.0.2.23:6789 map