7
6

More than 5 years have passed since last update.

kubernetesが外部のGlusterFSを使えるようにして、データを永続化できるようにする

Posted at

Kubernetes界隈だと近頃の永続化ストレージはRook+Cephを扱った記事が多いようですが、こちらでCephは障害が多そうとか、Cephは最低3台必要でちょっとマシンリソース的に厳しいとかで、GlusterFSにしました。前の会社で、ちょっとGlusterFS+Heketiに因縁もあったし。

で、ベアメタル?オンプレミス?環境だから、GlusterFSをPodで動かすより、Kubernetes外部で動かして、データにアクセスしやすくしてみました。GlusterFSも推奨は3台ですが、最低2台でもいけるので、物理ホストと、新しい仮想サーバ(glusterfs-node1)でクラスタを構成しました。KVMの調子が悪くなっても物理ホストにデータが残るように。

物理ホスト

GlusterFSとHeketiのインストール
# yum install -y centos-release-gluster
# yum install -y glusterfs-server heketi heketi-client
# setsebool -P nis_enabled on
# firewall-cmd --add-service=glusterfs --permanent 
# firewall-cmd --add-port=8080/tcp --permanent
# firewall-cmd --reload
  • 8080はHeketiサーバ用のポート。
Glusterノードの作成
Vagrant.configure(2) do |config|
  config.ssh.insert_key = false

  $nodes = [
    { name: "gluster-node1", cpu: "2", memory: "4096", ip: "192.168.122.6", disk: "50G"}
  ]

  $nodes.each do |param|
    config.vm.define param[:name] do |node|
      node.vm.box = "centos/7"
      node.vm.hostname = param[:name]

      node.vm.provider :libvirt do |v|
        v.cpus = param[:cpu]
        v.memory = param[:memory]
        v.storage :file, :size => param[:disk], :type => "raw"
      end

      node.vm.network :private_network, ip: param[:ip], :libvirt__network_name => "default"

      node.vm.provision :shell do |s|
        ssh_insecure_key = File.read("#{Dir.home}/.vagrant.d/insecure_private_key")
        s.inline = <<-SHELL
        mkdir -p /root/.ssh
        echo "#{ssh_insecure_key}" >> /root/.ssh/id_rsa
        chmod 400 /root/.ssh/id_rsa
        cp /home/vagrant/.ssh/authorized_keys /root/.ssh/authorized_keys

        echo "#{ssh_insecure_key}" >> /home/vagrant/.ssh/id_rsa
        chown vagrant /home/vagrant/.ssh/id_rsa
        chmod 400 /home/vagrant/.ssh/id_rsa
        SHELL
      end
      node.vm.provision :shell, inline: $script
    end
  end
end

$script = <<-SCRIPT
yum update -y

# SELinuxの無効化
setenforce 0
sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config

# GlusterFSのインストール
yum install -y centos-release-gluster
yum install -y glusterfs-server

# GlusterFSの起動
systemctl start glusterd
systemctl enable glusterd
SCRIPT
# vagrant up
# echo "192.168.122.6 gluster-node1" >> /etc/hosts
GlusterFS用ディスクの作成

Glusterノードは、追加したストレージが/dev/vdbに割当たるので、それをそのまま使用します。
物理サーバは、構築時に残しておいた領域から論理ボリュームを作成します。

# fdisk /dev/sda

The device presents a logical sector size that is smaller than
the physical sector size. Aligning to a physical sector (or optimal
I/O) size boundary is recommended, or performance may be impacted.
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


コマンド (m でヘルプ): n
Partition type:
   p   primary (2 primary, 0 extended, 2 free)
   e   extended
Select (default p): 
Using default response p
パーティション番号 (3,4, default 3): 
最初 sector (475414528-584843263, 初期値 475414528): 
初期値 475414528 を使います
Last sector, +sectors or +size{K,M,G} (475414528-584843263, 初期値 584843263): 
初期値 584843263 を使います
Partition 3 of type Linux and of size 52.2 GiB is set

コマンド (m でヘルプ): t
パーティション番号 (1-3, default 3): 
Hex code (type L to list all codes): 8e
Changed type of partition 'Linux' to 'Linux LVM'

コマンド (m でヘルプ): w
パーティションテーブルは変更されました!

ioctl() を呼び出してパーティションテーブルを再読込みします。

WARNING: Re-reading the partition table failed with error 16: デバイスもしくはリソースがビジー状態です.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
ディスクを同期しています。

# partprobe /dev/sda
# pvcreate /dev/sda3
  Physical volume "/dev/sda3" successfully created.
# vgcreate gluster /dev/sda3
# lvcreate --name kubernetes --size 52.1GB gluster
  • 最初、パーティションのままHeketiに登録しようとしたらエラーになって途方に暮れたが、設定例で論理ボリュームを指定してるものがあって助かった。
GlusterFSクラスタの作成

後述するHeketiで、GlusterFSクラスタを作成してくれるのですが、今回の環境だとちょっと不都合が発生しました。
物理サーバからはプールを確認すると、、、

# gluster pool list
UUID                    Hostname        State
35d6e969-b8cb-4f81-9a36-f0556fea7c5c    192.168.122.6   Connected 
06c5039c-53d4-4ceb-a7a6-25c4bf090968    localhost       Connected

で問題ないですが、Glusterノード側からは、、、

# gluster pool list
UUID                    Hostname        State
06c5039c-53d4-4ceb-a7a6-25c4bf090968    192.168.122.1   Connected 
35d6e969-b8cb-4f81-9a36-f0556fea7c5c    localhost       Connected

物理サーバのアドレスが、KVMネットワークのゲートウェイになってしまいます。GlusterFSのコマンドにはホスト名を指定するので、各ノードが認識しているホスト名とズレているとエラーになります。

  • これは物理ホストから手動でgluster peer probe 192.168.122.6としたのと同じ状態です。
  • ちなみにGlusterノード側からgluster peer probe ${物理ホストIPアドレス}とした場合には、物理ホスト側から見たGlusterノードはvagrant-libvirt管理ネットワークで割り振られたIPアドレス(192.168.121.*)になってしまいました。Glusterノードのデフォルトゲートウェイが管理ネットワークの方なのが悪いのだと思います。

ネットワークの設定を見直すべきなのかもしれませんが、ここでは/var/lib/glusterd/peers配下にあるファイル中のホスト名を修正してglusterdを再スタートすることで回避しました。

Heketiサーバの設定と起動

/etc/heketi/heketi.jsonを修正。

  • "executor": "mock", ⇒ "executor": "ssh",
  • "sshexec"配下を適切に設定。
    "keyfile": "/var/lib/heketi/.ssh/id_rsa",
    "user": "root",
    "port": "22",
    "fstab": "/etc/fstab"

heketiユーザで実行するHeketiサーバが、sshの公開鍵認証で各ノードにアクセスするので、Vagrantが生成した秘密鍵をheketiユーザホームに置いたり、物理ホスト側にも仮想サーバからauthorized_keysをコピーしたりしておきます。
そして起動。

# systemctl start heketi
# systemctl enable heketi

次にHeketiが管理するGlusterFSクラスタを設定します。
以下のようなノードとデバイスの組み合わせをJSON形式で定義してコマンドで登録します。

# cat <<EOF > topology.json
{
  "clusters": [{
    "nodes": [{
      "node": {
        "hostnames": {
          "manage": ["物理サーバのIP"],
          "storage": ["物理サーバのIP"]
        },
        "zone": 1
      },
      "devices": [{
        "name": "/dev/mapper/gluster-kubernetes",
        "destroydata": false
      }]
    }, {
      "node": {
        "hostnames": {
          "manage": ["192.168.122.6"],
          "storage": ["192.168.122.6"]
        },
        "zone": 1
      },
      "devices": [{
        "name": "/dev/vdb",
        "destroydata": false
      }]
    }]
  }]
}
EOF

# heketi-cli topology load --json topology.json 
Creating cluster ... ID: 0627d2d2996d2f903434b296fd89c4c0
    Allowing file volumes on cluster.
    Allowing block volumes on cluster.
    Creating node 物理サーバのIP ... ID: 115f74b5a300266ff99cb940a3f18ce3
        Adding device /dev/mapper/gluster-kubernetes ... OK
    Found node 192.168.122.6 on cluster 556644d30e71710cf76f3e74e15b251b
        Found device /dev/vdb

ストレージクラスの登録

Kubernetesに、作成したHeketiを利用するストレージクラスを登録します。

# cat <<EOF > gluster.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1beta1
metadata:
  name: gluster-dyn
provisioner: kubernetes.io/glusterfs
parameters:
  resturl: "http://kubernetes.local:8080"
  restauthenabled: "false"
  volumetype: "replicate:2"
EOF
# kubectl create -f gluster.yaml

これで環境としては構築できたので、実際にストレージを要求してみます。

# cat <<EOF > gluster-test.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: gluster-dyn-pvc
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  storageClassName: gluster-dyn
EOF
# kubectl create -f gluster-test.yaml
# kubectl get pvc
NAME              STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
gluster-dyn-pvc   Bound    pvc-9fc01705-0f69-4798-b072-5a1d9ec270fe   1Gi        RWX            gluster-dyn    11m

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6