あゝ、めんどくさい

めんどくさがり屋のIT勉強録

Labo用のネットワークを作る

自宅にLaboを作ろうと機材を調達したところまで書いた。今日はネットワークを作る辺り。

ESXiの入っている安鯖には物理NICが2つ付いている。この2つ目の物理NICにLabo用のネットワークをぶら下げたい。今はまだ何も繋がっていないが、将来的に安鯖が2つ・3つと増えた場合にはここからL2スイッチを介して、Labo用ネットワークを繋ぎたいという算段もある。
ネットワークにはゲートウェイが必要。ESXiにVyOSの最新版を入れて、こいつを家庭内ネットワークへのゲートウェイとする。今回はOVAファイルをインポートして使った。
VyOSを触るのは久しぶりなので色々と忘れていたが、ネット上のVyOSチートシートなどを参照して次のような設定を行った。
まずはNICの設定から。

vyos@myhostname# delete interfaces ethernet eth0 address dhcp
vyos@myhostname# set interfaces ethernet eth0 address 192.168.0.101/24
vyos@myhostname# delete interfaces ethernet eth1 address dhcp
vyos@myhostname# set interfaces ethernet eth1 address 172.16.0.1/24
vyos@myhostname# commit
vyos@myhostname# save

Labo側にDHCPをサービスする。

vyos@myhostname# set service dhcp-server shared-network-name LABO subnet 172.16.0.0/24
vyos@myhostname# set service dhcp-server shared-network-name LABO subnet 172.16.0.0/24 start 172.16.0.200 stop 172.16.0.253
vyos@myhostname# set service dhcp-server shared-network-name LABO subnet 172.16.0.0/24 default-router 172.16.0.1
vyos@myhostname# set service dhcp-server shared-network-name LABO subnet 172.16.0.0/24 dns-server 172.16.0.1
vyos@myhostname# commit
vyos@myhostname# save

Labo側にDNSをサービスする。先にVyOS自体にDNS解決できる設定をしておく必要がある。

vyos@myhostname# set system name-server 192.168.0.1
vyos@myhostname# set service dns forwarding listen-on eth1
vyos@myhostname# commit
vyos@myhostname# save

NAT設定。Laboから家庭内LANやインターネットへ抜ける通信用。

vyos@myhostname# set nat source rule 100 translation address masquerade
vyos@myhostname# set nat source rule 100 source address 172.16.0.0/24
vyos@myhostname# set nat source rule 100 outbound-interface eth0
vyos@myhostname# commit
vyos@myhostname# save

今度は外から中へ入る通信用。通信チェック用に172.16.0.11にSSHが通るように設定する。

vyos@myhostname# set nat destination rule 1 destination address 192.168.0.101
vyos@myhostname# set nat destination rule 1 destination port 10022
vyos@myhostname# set nat destination rule 1 protocol tcp
vyos@myhostname# set nat destination rule 1 translation address 172.16.0.11
vyos@myhostname# set nat destination rule 1 translation port 22
vyos@myhostname# set nat destination rule 1 inbound-interface eth0
vyos@myhostname# commit
vyos@myhostname# save

ファイアーウォールの設定。VyOSに対する通信と、VyOSを抜けてLaboに入る通信と両方設定する必要がある。まず前者の「local」通信用のルール。ついでに、SSHサービスを起動しておく。

vyos@myhostname# set firewall name PUBLIC-LOCAL default-action drop
vyos@myhostname# set firewall name PUBLIC-LOCAL rule 10 action accept
vyos@myhostname# set firewall name PUBLIC-LOCAL rule 10 state established enable
vyos@myhostname# set firewall name PUBLIC-LOCAL rule 10 state related enable
vyos@myhostname# set firewall name PUBLIC-LOCAL rule 20 action accept
vyos@myhostname# set firewall name PUBLIC-LOCAL rule 20 protocol tcp
vyos@myhostname# set firewall name PUBLIC-LOCAL rule 20 destination port 22
vyos@myhostname# set interfaces ethernet eth0 firewall local name PUBLIC-LOCAL
vyos@myhostname# set service ssh
vyos@myhostname# commit
vyos@myhostname# save

後者の「in」通信用のルール。

vyos@myhostname# set firewall name PUBLIC-IN default-action drop
vyos@myhostname# set firewall name PUBLIC-IN rule 10 action accept
vyos@myhostname# set firewall name PUBLIC-IN rule 10 state established enable
vyos@myhostname# set firewall name PUBLIC-IN rule 10 state related enable
vyos@myhostname# set firewall name PUBLIC-IN rule 20 action accept
vyos@myhostname# set firewall name PUBLIC-IN rule 20 protocol tcp
vyos@myhostname# set firewall name PUBLIC-IN rule 20 destination port 22
vyos@myhostname# set interfaces ethernet eth0 firewall in name PUBLIC-IN
vyos@myhostname# commit
vyos@myhostname# save

とりあえずここまでやれば、通信は通る。ESXiでLaboネットワーク上にゲストOSを作り、172.16.0.11のアドレスを割り振る。このゲストOSからpingテストでwww.yahoo.co.jpから応答が返ってくることを確認できた。
ゲストOSから家庭内LANにはpingできるが、インターネットに出れないという場合は、VyOSのところで名前解決できていないのが原因なので、name-serverの設定を見直すと良い。

次はVPN辺りかな。

そうだ、自宅にLaboを作ろう

世の中、サーバレスが流行りだ。とても気になるし、触って勉強してみたい。だが、日々クラウド課金の請求額に怯えている身としては、矢鱈滅多らサービスを使って、毎日卵かけご飯のみの生活になるのも辛い。

「そうだ、自宅にLaboを作ろう」

思い立ったら吉日。早速図面を引く。こんなシステムを作ることにした。

f:id:hiroys:20181030001400p:plain

 

自宅ネットワークの中にルータをつなぐ。ルータに「Labo」と呼ぶプライベートネットワークを繋ぎ、開発用のサーバ類を置く。作業に不便しないよう、VPNサーバも置く。肝心のサーバレスの勉強用にはKubernetesのシステムを構築して、Webリバースプロキシ経由でポート番号を指定せずともドメイン名だけで閲覧できるようにする。

Labo内にはDNSサーバを置かずに、route53に登録してそこから引く。ネットワーク的には分離するけど、ドメイン的には自宅内やクラウドにあるサーバと同じドメインを使って、Let's Encryptのワイルドカード証明書を使いまわそうという算段もある。

ん、それならなぜネットワークを分けたかって? そのほうが気分がいいからだよ!!

なお、思いつきのため予算が確保できず、以下の貧乏コースでシステムを構成する。

  • 仮想環境:VMWARE vShpere 6.7無償版
  • 仮想ホストマシン:NTT-X Storeの夜の割引で買った1.7万円サーバ(メモリーを20GBに増設、ストレージは500GB)
  • ルータ:ESXi上にVyOSで構築
  • その他のサーバ:ESXi上にCentOS 7.5で構築

ホスト機については色々不満がある。メモリーは32GBまで載せられるが、結構なお値段だったのでまずは20GBで我慢。ストレージも500GBのSSDが欲しいが当面我慢。CPUがPentium Gの2coreのため、重い作業ができない。CPUだけは予算に目処がつけばまっ先にi7に換装したい。

ルータはソフトウェアのVyOSにした。L3スイッチは高いし、何より操作を覚えるのが面倒くさい。VyOSはなんかのベンチを取る際に別ネットワークを作るのに使ったことがあるので、これが丁度いいやという適当な理由で選択。

ともかくこの構成でネットワークを組んで、Kubernetesを構築して、サーバレスの勉強をするという、なんとも適当なプロジェクトを開始したわけ。

続きは後日。

pythonスクリプトのEXE化

pythonは便利な言語だ。なんにでも使える。たとえばGUIをつけてコマンドラインツールをWindowsの画面から利用するなんてのもお茶の子さいさいだ。

「そう、だがpythonスクリプトWindowsのタスクバーに置いたりできない。不便だと思わないか?」

またかい。batファイル書いてデスクトップに置いておけっていうんだ。

pythonスクリプトWindowsのネイティブアプリにする。すると誰のPCに入っているpythonは2系で、誰のにはPyQtが入っていない……なんて気にしなくていい。これができれば大幅に効率アップすると思うんだけどなぁ」

はいはい、バルスバルス……じゃなかった、調べますよ。

pyinstallerというアプリ

Googleで調べるとすぐに出てきた。あまり凝ったことはできないが、とりあえず必要なライブラリを固めて1個のEXEファイルにできるらしい。

物は試しだ。とりあえず簡単なコードを書く。あまりに雑だが勘弁してくれ。python3から実行すると、ボタンが1つ表示されるウィンドウが開くアプリだ。


#!/usr/bin/python3

from tkinter import Tk, ttk

root = Tk()
btnframe = ttk.Frame(root)
btn = ttk.Button(btnframe, text='button')

btnframe.grid()
btn.grid()

root.mainloop()

このコードと同じディレクトリにアプリアイコン用のicoファイルを置く。pyinstallerはスクリプト中でimportしているpythonのパッケージは自動的に収集するが、ctypesでdllなんかを読み込んでいる場合は同じディレクトリに置いた方がいい予感がするが試していない。

次にsetup.pyを使ってpyinstallerをインストールする。VisualStudio付属のcpythonを使っている場合は「c:\Program Files\Python36\Scripts」以下にインストールされる。

さっそくビルドしてみる。

"c:\Program Files\Python36\Scripts\pyinstaller.exe" TestNativeApp.py --onefile --clean --noconsole --icon=utilities-terminal.ico --windwed

オプションの「--onefile」はzip化して1つのファイルにまとめるもの。「--clean」はmakeでいうところのmake cleanみたいなものか。「--noconsole」と「--windowed」は起動の際にコンソール(コマンドプロンプト)を開かないようにする。「--icon」はアイコンファイル(Windowsの場合はicoファイル)の指定。

処理が終わると作業フォルダ内に「dist」フォルダができあがる。中にEXEファイルが保存されている。ダブルクリックで開くこともできるし、タスクバーに置くこともできる。

ただ一つ失敗したなぁと思ったのはアイコン。急いで128×128pxのファイルを用意したが、これだけだとExplorer上では特大~中アイコンで表示した際にはカスタムアイコンが表示されるが、そのほかのレイアウトを選択した場合、デフォルトのアイコンで表示される。イメージを統一するためにはマルチアイコン形式で用意するのがいい。

確かに便利だなぁ。これならffmpegなんかのフロントエンドをpythonで書いてEXE化、なんてのもやってみたいが、EXEの中にEXEを固めるなんてことができるのだろうか。まあ、いつかやってみよう。

構成管理にAnsibleを使ってみた

構成管理ツール? そんな面倒なもん使わなくてもfabricでちょちょいですよ。

「でも、シェルスクリプトってエラーとかに弱いだろ? fabric上でいちいちtry/exceptを書いていくの? 非効率じゃん」

何の話かというと、各環境の再現性を持たせるためにインストールは自動化しましょうという話。Python上でシェルスクリプトを実行するfabricというのを使ってたんだが、それじゃ中途半端だと言われてる。んじゃ、どうすりゃいいの?

「Ansibleって知ってる? yamlでこういう状態にしてって書くと、その通りにするためのセッティングが走ってくれる。Python 2.5以上が必要だからCentOS 5系(なんでそんなのがまだあるの?)のホストに対する構成管理は無理だけど、最近のCentOSなら楽にセットアップできる」

yaml? その時点で凹むんですけど。

1.構成するファイルは最低2種類

pipでansibleを入れてさっそく試してみた。最低限必要なファイルは2種類。

さっき「こうあってほしい状態を書く」と言っていたyamlファイル。それからどのホストにどういう形でログインするかを書くインベントリファイル。そうそう忘れてたがfabricと同様SSHでログインして実行する。

自分のホームディレクトリにこんな形で展開してみた。

HOME
 ⎿ansible
   ⎿install_ipa-client
     ├run.yaml
     ⎿hosts

hostsにはansible実行時に、対象となるホストとログインに必要な情報を書いておく。複数書いておけば複数を対象に実行される。

[hiroys@utils install_ipa-client]$ vi hosts
[ipaclient]
dev2.example.jp
dev3.example.jp

[ipaclient:vars]
ansible_ssh_user=root
ansible_ssh_pass=********

SSHのユーザを選べるのは俺的にはツボ。fabricだと自分と同じIDでログインしてsudoするという形になっていたからだ。

yamlの方だが、playbookといって「こうあってほしい」というタスクを並べていく形になる。yamlを上から順に読んでいく形になるが、実行条件も設定できるので挙動を振り分けたいときに便利だ。

ipa-clientを新規サーバに入れる前提で書いてみた。

- name: install ipa-client
  gather_facts: True
  tasks:

    - name: rewrite dns server
      when: ansible_distribution_major_version == "7"
      command: nmcli c mod ens192 ipv4.dns 172.16.10.100
    - name: restart NetworkManager
      when: ansible_distribution_major_version == "7"
      command: systemctl restart NetworkManager

    - name: rewrite dns server
      when: ansible_distribution_major_version == "6"
      lineinfile: dest=/etc/sysconfig/network-scripts/ifcfg-eth0 regrex="^DNS1=.*" line="DNS1=172.16.10.100"
    - name: restart network
      when: ansible_distribution_major_version == "6"
      service: name=network state=restarted

    - name: yum install ipa-client
      yum: name=ipa-client state=present

    - name: download get-pip.py
      command: curl -O https://bootstrap.pypa.io/get-pip.py
    - name: install pip
      command: python ./get-pip.py
    - name: pip upgrade
      command: pip install --upgrade pip
    - name: install pexpect
      command: pip install pexpect

    - name: setup ipa-client-install
      expect:
        command: ipa-client-install
        responses:
          'Continue to configure the system with these values' : 'yes'
          'User authorized to enroll computers' : 'admin'
          'Password for admin' : '********'
    - name: mkhomedir
      command: authconfig --enablemkhomedir --update

nameやwhenやcommand、expectと書いてあるのがモジュールと呼ばれるもので、それぞれの挙動はこのモジュールが肩代わりしてくれる。シェルコマンドばかり書いているのでは、fabricとあまり変わりない気がしてくるが。。。expectが使えるのは魅力である。

2.実行する。

実際には知らせる場合はコマンドで次のように打つ。

[hiroys@utils install_ipa-client]$ ansible-playbook ipaclient -i hosts run.yml

fabricを使っていた場合と比べて手間はだいぶ省けているように思える。yamlの取り扱いが面倒なのがやや玉に瑕だが。。。

IdMによるIDの一元管理

「そりゃ、一瞬で全てのサーバからアカウントを削除できたら楽に決まってんだろ」

退職者のアカウント削除、これ一苦労なんだよな。サーバ一個ならいいんだけど、みんな好き勝手にあちこちにアカウントを作っているから、消して回らないとならない。

「そこでだ、アカウントを一括で管理する。これを君が作るんだ」

は? それActive DirectoryOpenLDAPでアカウント管理して統合認証やりましょうってやつでしょ。Windowsはわからないし、OpenLDAPは操作が面倒だから嫌だよ。

OpenLDAPって確かCentOS 7.4から非推奨になったんじゃなかったけな」

な・ん・だ・と?

1.IdMという選択肢

Red Hatのサイトに観に行くと「将来削除」確かに書いてある。

となると、7.xの間はサポートはされるものの、積極的な改修とかは期待できないわけだ。まあうちで使うのはCentOSなので、サポートもへったくれもないんだけど。

代わって6.xの頃からユーザ認証にはIdMというのが用意されている。Identity Managerの略語であるこれはFreeIPAというプロジェクトの成果物で、Red Hat Enterprise Linux上でユーザ、ホスト、サービスの管理を行うもの。もちろんCentOSにも入っている。 LDAPやKerberos、BINDなんかを使ってID管理をするため、一般的なLinuxサーバであればこれで一手に管理できそうだ。Webの管理画面もついている。

2.認証サーバのインストール

さっそくサーバ側の準備をする。DNSの機能が統合されているため、既存のネットワーク上に構築して少しずつ移行しようなんてすると、既存のDNSと管理するゾーンが被ったりして少々面倒。でもなんとかする。

まずは認証サーバにCentOS 7.4を入れ、yum updateをかけておく。そこからFreeIPAのインストールを行う。

[root@ipa ~]# yum -y install ipa-server ipa-server-dns bind bind-dyndb-ldap

インストールが終わったらセットアップを走らせるが、これから設定しようとするDNSゾーンがすでにネットワーク上のDNSサーバで管理されているとセットアップが失敗するので、この時だけは/etc/resolv.confの設定をいじっておく。

[root@ipa ~]# vi /etc/resolv.conf
nameserver 127.0.0.1

また、DNSを見に行かなくなると自身のIPアドレスがわからなくなるため、/etc/hostsに自身のIPアドレスを登録をしておく。

[root@ipa ~]# vi /etc/hosts
172.16.10.100 ipa.example.jp

セットアップの開始

[root@ipa ~]# ipa-server-install
Existing BIND configuration detected, overwrite? [no]: yes↩️

Server host name [ipa.example.jp]: ↩️

Please confirm the domain name [example.jp]: ↩️

Please provide a realm name [EXAMPLE.JP]: ↩️

Directory Manager(LDAPでいうところのroot dnみたいなもの)のパスワード

Directory Manager password: ********↩️
Password (confirm): ********↩️

IPA ADMIN(IPAのadminアカウントのパスワード設定)のパスワード

IPA admin password: ********↩️
Password (confirm): ********↩️

Forwardersだが、今見にいかせると面倒なことになるので設定はしない。あとで設定をする。

Do you want to configure DNS forwarders? [yes]: no↩️

逆引きゾーンの設定はメールサーバとか使うならいるかも。

Do you want to configure the reverse zone? [yes]: ↩️
Please specify the reverse zone name [10.16.172.in-addr.arpa.]:

設定の確認を求められる。

The IPA Master Server will be configured with:
Hostname:      ipa.example.jp
IP address:    172.16.10.100
Domain name:   example.jp
Realm name:    EXAMPLE.JP

Continue to configure the system with these values? [no]: yes ↩️

すると色々設定されて最後にFirewallの設定とIPAへのログインを求められる。

Setup complete

Next steps:
        1. You must make sure these network ports are open:
                TCP Ports:
                  * 80, 443: HTTP/HTTPS
                  * 389, 636: LDAP/LDAPS
                  * 88, 464: kerberos
                UDP Ports:
                  * 88, 464: kerberos
                  * 123: ntp

        2. You can now obtain a kerberos ticket using the command: 'kinit admin'
           This ticket will allow you to use the IPA tools (e.g., ipa user-add)
           and the web user interface.

とりあえずFirewallを開ける。dnsがさっきの一覧にはなかったが、DNSも使うので開ける。

[root@ipa ~]# firewall-cmd --permanent --zone=public --add-service=http --add-service=https --add-service=ldap --add-service=ldaps --add-service=kerberos --add-service=freeipa-ldap --add-service=dns --add-service=ntp
[root@ipa ~]# firewall-cmd --reload

ここまでやったら/etc/resolv.confの設定を元に戻す。

[root@ipa ~]# vi /etc/resolv.conf
nameserver 192.168.0.2
nameserver 192.168.0.3

DNSにForwardersを設定する。

[root@ipa ~]# vi /etc/named.conf
option {
	...
	forwarders {
		192.168.0.2;
		192.168.0.3;
	};
};

通常ならここでnamedを再起動するのだが、namedはmaskと呼ばれる状態になっており、再起動を受け付けない。システムごと再起動しておく。

[root@ipa ~]# systemctl reboot

次に、IPAにログインしてKerberosのチケットを入手する。この状態でIDの管理ができるようになる。

[root@ipa ~]# kinit admin
Password for admin@EXAMPLE.JP: [IPA adminで入れたパスワード]

3.IDの追加

ユーザの追加はコマンドで行う。あとで紹介するWeb画面でもできるが、こっちの方がシンプル。なお、管理者が設定したパスワードは、ユーザの初回ログイン時に強制的に変更を求められるセキュアぶり。

[root@ipa ~]# ipa user-add [ユーザID] --first=[名] --last=[姓] --password=********
-------------------
Added user "fhoge"
-------------------
  User login: fhoge
  First name: fuga
  Last name: hoge
  Full name: fuga hoge
  Display name: fuga hoge
  Initials: fh
  Home directory: /home/fhoge
  GECOS field: fuga hoge
  Login shell: /bin/bash
  Kerberos principal: fhoge@EXAMPLE.JP
  Email address: fhoge@example.jp
  UID: 1113400020
  GID: 1113400020
  Password: True
  Kerberos keys available: True

なんかUID/GIDが桁外れにでかいんですけど。。。。

また、ホストも登録できる。これはクライアントの設定を行う前に対象のホストを登録しておくこと。

[root@ipa ~]# ipa dnsrecord-add [domain名] [host名] --a-rec [IPアドレス]
Record name: dev1
A record: 172.16.10.41

4.クライアントのインストール

クライアントは既存のサーバを移行するのだが、まずDNSの参照先をIPAサーバに変更する。

[root@dev1 ~]# nmcli c modify ens192 ipv4.dns 172.16.10.100
[root@dev1 ~]# systemctl restart NetworkManager

クライアントソフトを入れる。

[root@dev1 ~]# yum -y install ipa-client
Discovery was successful!
Hostname: dev1.example.jp
Realm: EXAMPLE.JP
DNS Domain: example.jp
IPA Server: ipa.example.jp
BaseDN: dc=example,dc=jp

Continue to configure the system with these values? [no]: yes ↩️
User authorized to enroll computers: admin ↩️
Password for admin@EXAMPLE.JP: ******** ↩️
.....
Client configuration complete.

なお、ローカルでユーザを作る場合と違ってホームディレクトリは自動で作成されないので、設定をしておく。

[root@dev1 ~]# authconfig --enablemkhomedir --update

ここからが面倒なのだが、UIDとGIDが変わってしまうため、既存のホームディレクトリのオーナーが変わってしまう。なので、あらかじめchownコマンドでホームディレクトリのオーナーを全員分変えておく必要がある。それが嫌な場合はWeb画面でUIDとGIDを従来と同じものに変えておく。

[root@dev1 ~]# chown -R fhoge:fhoge fhoge

5. Web画面

IPAIPアドレスhttpsでアクセスするとWebの管理画面が表示される。 sudoなど細かい設定はこちらでやるのが楽だろう(後略)。

一元管理というと響きはいいが、既存の環境から移行する際にクライアント側の設定の手間が煩わしく感じた。これ以降のクライアントの構築は構成管理ツールなどであらかじめIdMに対応させておくのがいいだろう。

バックアップサーバをrsyncとGlusterFSで用意する。

「やっちまった」。。。DBサーバのファイルシステムが飛んでしまった。

いろいろ反省会をした後、「やっぱりバックアップって必要だよね」「DNSとか飛んだらおしまいじゃね、どうする?」なんて話が出て、LAN上の重要データについては定期バックアップを取ることになった。

バックアップ要件としては簡単に以下の3を挙げた。

  • 一日一回。夜中に実施。
  • 一世代だけでいい。
  • バックアップが飛ぶことも考慮する。

1.rsyncを使った定期バックアップ

このうち定期実施についてはrsyncを使用する。コピー先とコピー元にそれぞれrsyncを入れる。

[root@ns ~]# yum -y install rsync
[root@backup1 ~]# yum -y install rsync

コピー元にはバックアップ用のシェルスクリプトを用意してcronで動かす。

[root@ns ~]# vi /usr/local/sbin/backup.sh

#!/bin/bash 
cp -pafr /etc/named.conf /var/named/. 
rsync -avz /var/named backup.example.jp::named 

[root@ns ~]# chmod +x /usr/local/sbin/backup.sh
[root@ns ~]# crontab -e 

0 2 * * * /usr/local/sbin/backup.sh

BackupServerのファイアーウォールを開け、rsyncdを設定して起動する。

[root@bakcup1 ~]# firewall-cmd --add-service=rsyncd --permanent --zone=public
[root@bakcup1 ~]# firewall-cmd --reload
[root@bakcup1 ~]# vi /etc/rsyncd.conf

[named]
# path to copy destination
path = /srv/backup/named
hosts allow = 172.16.10.2
hosts deny = *
list = true
uid = root
gid = root
read only = false

[root@backup1 ~]# mkdir -p /srv/backup/named
[root@backup1 ~]# systemctl start rsyncd
[root@backup1 ~]# systemctl enable rsyncd

2.GlusterFSの構成

次にバックアップが飛んだ場合の考慮について。

LAN上のサーバはほぼ全部がVMWARE vSphere上で動いているので、バックアップ用に空いている物理マシンはない。仮想マシン上に構築する必要がある。

考えた方法は以下の3つ。

  • バックアップマシンを2台用意して、それぞれにバックアップを取る
  • バックアップマシンの対象ボリュームをDRBDで二重化する
  • バックアップマシンの対象ボリュームを分散ファイルシステムで二重化する。

この中で検討を行い、やり方としては新しい分散ファイルシステムに挑戦してみることになった。分散ファイルシステムにもいくつか方法があるが、比較的管理が容易なGlusterFSで組んでみた。

構成的にはこんな感じ。この3台は用心のため別々のvSphereにインスタンスを生成する。

BackupServerはrsyncdだけ動かしておいて、GlusterFSで組んだ分散ボリュームをfuseを使ってマウントする。GlusterFSはレプリケーションを組んでおいて、一台が落ちたらもう一台に切り替えてマウントする(ここはノウハウがないので手動で対応する)。

                                172.16.10.50
                         +----------------------+
                         |    [Backup Server]   |
                         |  backup1.example.jp  |
                         |      CentOS 7.4      |
                         +----------------------+
                                     |
+----------------------+             |              +----------------------+
| [GlusterFS Server#1] |172.16.10.51 | 1172.16.10.52| [GlusterFS Server#2] |
|  gluster1.example.jp +-------------+--------------+  gluster2.example.jp |
|      CentOS 7.4      |                            |      CentOS 7.4      |
+----------------------+                            +----------------------+

GlusterFS Server側はOSのボリュームとは別に、ノード用のボリュームを用意する。LAN上のデータは20GiBにも満たないし、1世代しかバックアップしないのでノード用のボリュームは100GiBも用意すれば十分だろう。

3.GlusterFSのインストール

とりあえずインストール。1号機、2号機にそれぞれ同じ作業を行なう。

[root@gluster1 ~]# yum install -y centos-release-gluster
[root@gluster1 ~]# yum install -y glusterfs-server
[root@gluster1 ~]# systemctl start glusterd
[root@gluster1 ~]# systemctl status glusterd
[root@gluster1 ~]# systemctl enable glusterd

firewallを開けます。上からglasterd、brick(ノード)のポート、portmapper。

[root@gluster1 ~]# firewall-cmd --add-port=24007-24008/tcp --permanent --zone=public
[root@gluster1 ~]# firewall-cmd --add-port=49152-49153/tcp --permanent --zone=public
[root@gluster1 ~]# firewall-cmd --add-service=rpc-bind --permanent --zone=public
[root@gluster1 ~]# firewall-cmd --reload

DNSが飛ぶことを考慮し、/etc/hostsにそれぞれのノードを記載する

[root@gluster1 ~]# vi /etc/hosts
172.16.50.2 gluster1
172.16.50.3 gluster2

4.ストレージプールの作成

ここからボリュームをため込む器に当たるストレージプールを作成する。そのためにはそれぞれのノードを認識させる必要がある。

GlusterFSではそれぞれのノードがメタデータサーバに当たる機能を持っている。作業はgluster1からのみ行えばOk。statusサブコマンドえ自分以外のノードが見えれば作業は完了。

[root@gluster1 ~]# gluster peer probe gluster2
[root@gluster1 ~]# gluster peer status

5.Glusterボリュームの用意

それぞれのノードで最初に用意した別ボリュームをフォーマットする。CentOS7なのでxfsで作成する。

[root@gluster1 ~]# fdisk /dev/sdb
[root@gluster1 ~]# mkfs.xfs -i size=512 /dev/sdb1
[root@gluster1 ~]# mkdir -p /export/sdb1
[root@gluster1 ~]# monut -t xfs /dev/sdb1 /export/sdb/1
[root@gluster1 ~]# mkdir -P /export/sdb1/brick
[root@gluster1 ~]# echo "/dev/sdb1 /export/sdb1 xfs defaults 0 0" >> /etc/fstab
[root@gluster1 ~]# mount -a

次にレプリケーションボリュームを作成して起動する。gluster1のみでの作業となる。これによって「gv0」というレプリケーションされたglusterボリュームが作成される。

[root@gluster1 ~]# gluster volume create gv0 replica 2 gluster1:/export/sdb1/brick/gv0/ gluster2:/export/sdb1/brick/gv0/
[root@gluster1 ~]# gluster vol info
[root@gluster1 ~]# gluster volume start gv0

6.ボリュームのマウント

ボリュームはfuseを使ってマウントする。backup1にGlusterFS用のfuseドライバーを入れる。

[root@gluster1 ~]# yum install -y glusterfs-fuse
[root@backup1 ~]# mount -t glusterfs gluster1:/gv0 /srv/backup

7.ボリュームの追加

容量が足りなくなった場合は、ストレージプールにbrickを追加する。ただし、レプリケーション数の倍数になるように追加する必要がある。

[root@gluster1 ~]# gluster vol add-brick gv0 gluster3:/export/sdb1/brick/gv0 gluster4:/export/sdb1/brick/gv0

8.シャットダウン

一応どのノードが落ちても、レプリカの構成の1つが生きていれば大丈夫なはず。。。

backup1からマウントを外す(もしくはシャットダウン)してから、GlusterFSサーバを落とす順番になる。

一応これでDNS->backup1->glusterfs1/2の順でバックアップが作成される。最悪、必要なデータが取り出せる態勢にはなったので、一安心である。