Kubernetes環境におけるGlusterFSの動的ストレージ構成

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クラスタのセットアップ

  1. 全ノードで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
    
  2. glusterFSサービスを起動
    [root@glusterfs-01 ~]# systemctl start glusterd.service
    [root@glusterfs-01 ~]# systemctl enable glusterd.service
    [root@glusterfs-01 ~]# systemctl status glusterd.service
    
  3. 任意のノードから他のノードを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
    
  4. 全ノードのデータディスクをフォーマットし、物理ボリュームを作成
    [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を選択し、必要なボリュームを構築します。

  1. 全ノードにheketiとheketi-clientをインストール
    [root@glusterfs-01 ~]# yum install -y heketi heketi-client
    
  2. 主ノードで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*
    
  3. 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"
      }
    }
    
  4. 全ノードでheketiサービスを自動起動し起動
    [root@glusterfs-01 ~]# systemctl restart heketi
    [root@glusterfs-01 ~]# systemctl enable heketi
    
  5. Heketi接続テスト
    [root@glusterfs-01 ~]# curl http://glusterfs-01:8080/hello
    Hello from Heketi
    
  6. 主ノードでHEKETI_CLI_SERVER環境変数を設定
    [root@glusterfs-01 ~]# export HEKETI_CLI_SERVER=http://glusterfs-01:8080
    
  7. 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
                            }
                        ]
                    }
                ]
            }
        ]
    }
    
  8. ノードとデバイスを登録
    [root@glusterfs-01 ~]# heketi-cli topology load --json=/usr/share/heketi/topology-sample.json
    
  9. ボリュームの作成テスト
    [root@glusterfs-01 ~]# heketi-cli volume create --size=2
    
  10. ボリューム情報の確認
    [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

タグ: GlusterFS Kubernetes StorageClass DynamicStorage Heketi

7月15日 21:45 投稿