読者です 読者をやめる 読者になる 読者になる

私をペロペロするがよい

lazy_dog のブログです。

Zabbix を Arch Linux に入れよう(ついでに SNMP ものんびり覚える)

Linux

れずれずアドベンドカレンダー 2 日目です。今回は、Arch Linux に Zabbix を入れることにします。

Zabbix とは

http://ja.wikipedia.org/wiki/Zabbix

方針

  • Arch Linux の最新を使用。
  • MariaDB
    • zabbix-server-mysql を使用することになる。
  • Lighttpd
  • Zabbix は AUR から
  • エージェントレスの SNMP を使用した監視にする。

今回の Zabbix の AUR のバージョンは 2.4.3-1

なお、例によって Arch Linux のインストールは割愛。下記を参考にしたので、重要そうなところをコメントする。

Zabbix (日本語) - ArchWiki
https://wiki.archlinux.org/index.php/Zabbix_(%E6%97%A5%E6%9C%AC%E8%AA%9E)

インストール内容

pacman で下記をまずはインストール。

AUR でしかインストールできない iksemel も一緒にインストールする。Jabber (チャットプロトコル)を処理するパーサらしい。不要だが、必須なので入れる他あるまい。。

AUR (en) - iksemel
https://aur.archlinux.org/packages/iksemel/

上記をインストールしたら、AUR から zabbix-server-mysql をのパッケージをダウンロードしビルドする。Zabbix の中身は C で書かれているため、コンパイルに多少の時間がかかる。

AUR (en) - zabbix-server-mysql
https://aur.archlinux.org/packages/zabbix-server-mysql/

/etc/php/php.ini を編集する。値は上記 Wiki をご参考願う。なお、下記の値もコメントアウトし有効化しないといけないので注意。MySQL (MariaDB) を使用する場合は必須。タイムゾーンも日本時間にすると、グラフが日本時間になるので設定すること。

extension=mysqli.so
always_populate_raw_post_data = -1
date.timezone = "Asia/Tokyo"

あとは mysqld を systemctl で enable と start し、Wiki に書かれている SQL のコマンドを実行する。パスワードの文字列(zabbix@localhost を作成している時の "test" の文字列)は適当に変えておくのもいいかも。

/etc/zabbix/zabbix_server.conf を作成する。もちろん、DBPassword の値はパスワードを指定すること。

Lighttpd 設定

Zabbix のアプリケーションが入ったディレクトリに対し、ln でシンボリックリンクを作る。

# ln -s /usr/share/webapps/zabbix /var/www

次に、LighttpdPHP を動かすために FastCGI の設定をする。

Lighttpd - ArchWiki
https://wiki.archlinux.org/index.php/Lighttpd#PHP

のページの config をそのままパクれば動くようになる。/etc/lighttpd/conf.d/fastcgi.conf を作成し、/etc/lighttpd/lighttpd.conffastcgi.conf を include する設定を追加する。

各種デーモン起動

先に動かしている MariaDB の mysqld 以外に、下記を start/enable する。

これで Zabbix が動く。

初期設定

http://{サーバのアドレス}/zabbix にアクセスすると、Zabbix のインストールを行う WebGUI 画面になる。DB の値など、適当に入れること。全て終了すると、ログイン画面になる。

  • ユーザー名: admin
  • パスワード: zabbix

で入られる。

おいらが経験したログイン後のトラブル

ダッシュボードの画面で、"zabbix server is not running" と表示される場合があった。これは zabbix_server.conf の設定がおかしくなっている可能性がある。おいらの場合、"DBuser" の値が空になっていた。

上記を修正したところ、無事 "Zabbix server is running" が Yes になった。

次回

SNMPYamaha RTX の情報を取得する際、もろもろ悩んだことを書く予定。

# Zabbix の設定方法や使い方は割愛。。。

Yamaha RTX の LAN 分割機能

ネットワーク

この記事は「れずれず Advent Calendar」の 1 日目です。表題の件、Cisco の L3 スイッチなどと違いちょっと癖があり、意外にも奥深い設定だなあと思ったので記事にした。

YAMAHA RTX の LAN 分割機能について

YAMAHA RTX シリーズについている LAN 側のポートは、基本的にスイッチングハブとしての役割で、各ポートに IP を持たないというのがデフォルトである。しかし、LAN 分割機能を使えば LAN 側のポートをそれぞれセグメント分割する設定が可能になる。単純に言えば、各ポートに IP アドレスを持たせることができる。

なお、本記事は Yamaha RTX 810 と Rev.11.01.21 のファームウェアを使用している。

デフォルトの状態

LAN ネットワーク、つまりローカル側がぶら下がるポートは基本的に LAN1 と総称され、複数のポートがスイッチングハブとして纏められており、IP アドレスは一つしか持てない。

> show status lan1
LAN1
Description:
IP Address:                     192.168.0.1/24
Ethernet Address:               00:**:**:**:**:**
Operation mode setting:         Type (Link status)
               PORT1:           Auto Negotiation (1000BASE-T Full Duplex)
               PORT2:           Auto Negotiation (100BASE-TX Full Duplex)
               PORT3:           Auto Negotiation (Link Down)
               PORT4:           Auto Negotiation (Link Down)
Maximum Transmission Unit(MTU): 1500 octets
Promiscuous mode:               OFF
(省略)
>

LAN 分割をすると、この LAN1 が分割される。

LAN 分割コマンドについて

YAMAHA RTX の LAN 分割は、「基本機能」と「拡張機能」の2 種類の方法で分けることができるらしいが、Rev.10.01 系以降は「拡張機能」がメインストリームらしいので、基本こちらを設定する。 拡張分割では、LAN1 側のポートをそれぞれ一つずつに独立させ、分割後、VLAN インターフェイスが作成される。その VLAN に各ポートを所属させる。そのため、任意のポート同士を一つのセグメントにすることが可能。

なお、既存で設定がある場合でも「拡張機能」を設定すると、ある程度引き継いてくれる(config のポート名を書き換えてくれる)。

拡張分割の方法

下記コマンドで行える。

lan type lan1 port-based-option=divide-network

これによって、LAN1 がそれぞれ lan1.1, lan1.2 などに分割され、lan1.1 は VLAN1 に所属になる。

ip lan1 address 192.168.0.1/24
↓
ip vlan1 address 192.168.0.1/24

こんな感じに書きかえてくれる。"show status lan1" の結果はこんな感じ。

> show status lan1
VLAN1
Description:
IP Address:                     192.168.0.1/24
VLAN2
Description:
IP Address:
VLAN3
Description:
IP Address:
VLAN4
Description:
IP Address:
Ethernet Address:               00:**:**:**:**:**
Operation mode setting:         Type (Link status)
               PORT1:           Auto Negotiation (1000BASE-T Full Duplex)
               PORT2:           Auto Negotiation (100BASE-TX Full Duplex)
               PORT3:           Auto Negotiation (Link Down)
               PORT4:           Auto Negotiation (Link Down)
Maximum Transmission Unit(MTU): 1500 octets
Promiscuous mode:               OFF
(省略)

VLAN 1 から 4 までの欄が作成されている。現状、ポート 1 の lan1.1 のみが VLAN 1 に所属しているが、これにポート 2 の lan1.2 を所属させるには、、、

vlan port mapping lan1.2 vlan1

と "vlan mapping {ポート名} {VLAN 番号}" とすればよい。

まとめると、

vlan port mapping lan1.1 vlan1
vlan port mapping lan1.2 vlan1
lan type lan1 port-based-option=divide-network
ip vlan1 address 192.168.0.1/24

こんな感じ。

  • RTX のローカル側のポートは、スイッチングハブがデフォルトの動作である。
  • コマンドによって、VLAN が作成され、各ポートがそれに所属することができる。
  • VLAN インターフェイスに IP アドレスを設定する。

まとめ

メリークリスマス。次は、id:lazy_dog さんです。

virt-install 1.1.0 で --os-variant に virtio26 が指定できない

Linux Virtualization
[root@baghdad ~]# virt-install --version
1.1.0
[root@baghdad ~]#
[root@baghdad ~]# osinfo-query os | grep -i virtio26
[root@baghdad ~]#

このように、virt-install 1.1.0 で --os-variant に virtio26 が指定できない。

なんで?

バグらしい。

Bug 1159903 ? /virt/install fails with: Distro 'virtio26' does not exist in our dictionary
https://bugzilla.redhat.com/show_bug.cgi?id=1159903

Cole Robinson 2014-11-16 12:15:49 EST

Sorry for lack of response. Yeah we switched to libosinfo for our os dictionary in virt-install/virt-manager, but we missed carrying over an alias for the old virtio26 option we used to provide. We need to fix that in virt-install

とのこと。

回避策

Fedoraレポジトリに存在する virt-manager.git の virt-install の現在のレポジトリでは修正がされており、内容としては virtio26 は "fedora10 " にエイリアスがされている。

osdict: Add back compat 'virtio26' entry
https://git.fedorahosted.org/cgit/virt-manager.git/commit/?id=60e62e26761072475301729002150ceb0ba617fd

この fix は将来のバージョンで反映されるであろうが、とりあえずのところ --os-variant には fedora10 を指定しておけば virtio26 と同等になるようだ。

Ansible を覚えてみた (その流れ)

Linux

Ansible の初歩までの道程をまとめた。

Ansible って何?

今話題の Chef とか Puppet とかと大体同じやつです。

  • 対象のサーバに対し、設定を行ったりファイルを設置したりする
  • 既に設定済みで何度やっても、対象の全てのサーバが「あるべき状態」に必ずなる → 冪等性
  • Playbook という、クライアントのサーバに対し何をやるか、という設定ファイルを作成する

初歩程度は使いこなせるまでの順序

  • 環境を整える
  • ansible コマンドで ping を飛ばせるようになる
  • データ形式YAML」を覚えつつ、Playbook を作れるようになる

こんな感じで覚えた。

環境を整える

Ansible はサーバ・クライアントの二つに分かれる。クライアントには Ansible のパッケージは一切不要。もちろん、サーバは自分自身がクライアントになることもできる。

Ansible に必要なのは下記の通り。

  • サーバ: Python 2.6 以降 (Python3 は非対応)、Ansible 本体
  • クライアント: Python2.4 以降 (同上)
  • SSH で繋がる環境

Arch Linux 環境で使う場合

Arch Linux は、デフォルトでインストールされている Python のバージョンが 3 系 のため、Python2 をインストールして、エイリアスを作成する必要がある。

[root@bag-ansible-01 ~]# pacman -S python2

... (略)

[root@bag-ansible-01 ~]# ln -s /usr/bin/python2 /usr/bin/python
[root@bag-ansible-01 ~]# python --version
Python 2.7.8

python って打って、Python2 が返ってこなければならない。この辺りは、Arch Linux の OS インストール時に処理しておくと楽。

SSH とか名前解決

Ansible は SSH を使用してクライアントに接続する。SSHPython のパッケージである paramiko を使用するので、OpenSSH には依存せずバージョンなどの指定は関係ない。

Ansible は名前もしくは IP アドレスを指定で、クライアントに接続する。指定の方法は後述する hosts (Ansible 専用) に記載することになるが、管理やコマンドの確認が楽になるため、名前解決できるように DNS か /etc/hosts に記載したほうがいいと思った。

Ansible インストール

サーバにのみ、Ansible パッケージをインストールする。クライアントは SSH が通り、Python の 2 系が使用可能であればよい。

[root@bag-ansible-01 ~]# pacman -S ansible
resolving dependencies...
looking for inter-conflicts...

Packages (8): python2-crypto-2.6.1-2  python2-ecdsa-0.11-2  python2-jinja-2.7.3-1  python2-markupsafe-0.23-1
              python2-paramiko-1.14.1-1  python2-setuptools-1:5.7-1  python2-yaml-3.11-1  ansible-1.7.1-1

....

他のディストリビューションなら、yum や pip でインストールできる。

Installation ? Ansible Documentation
http://docs.ansible.com/intro_installation.html

/etc/ansible/hosts を作成する

/etc/ansible/hosts に、Ansible で管理するホストを記載する。IP アドレス・ホスト名の両方が記載可能であるが、今回は管理が楽になるため DNS を通してホスト名での記載にする。裏の名前を用いて、管理セグメントで接続させる。

[root@bag-ansible-01 ~]# cat /etc/ansible/hosts
[VM-back]
b1-bag-ansible-01
b1-bag-pacmanrepo-01
b1-bag-rss-01
b1-bag-dns-01

[Physical-back]
b1-israel
b1-baghdad
b1-palestine

"[hoge]" の箇所はグループ名となり、このグループ名を対象に指定して、操作することができる。

/etc/ansible/ansible.config 設定

host_key_checking を False にした。これによって、~/.ssh/known_hosts のホストのキーを無視できる。セキュリティとの兼ね合いもあるが、とりあえず無効にした。

他はデフォルト。

サーバに ansible ユーザーを作成

Ansible 実行用のユーザーとして、"ansible" ユーザーを作成する。

[root@bag-ansible-01 ~]# useradd -m ansible
[root@bag-ansible-01 ~]# su ansible
[ansible@bag-ansible-01 ~]$ ssh-keygen
[ansible@bag-ansible-01 ~]$ passwd

これで、、

Ansible を使用できる最低限の環境は揃ったことになる。

Ansible を構成するファイルのおさらい

Ansible のサーバ側を構成する設定ファイルについて。

基本的に、Playbook と呼ばれる各クライアントを設定するレシピのファイルを除けば、Ansible のサーバの設定ファイルは、下記二つのみである。

  • /etc/ansible/ansible.cfg
  • /etc/ansible/hosts

ansible.cfg は、Ansible の全体的な設定を行うファイルである。hosts は上記で説明した通り、管理するクライアントをグループごとに羅列するファイルになる。

ansible コマンドで ping を飛ばせるようになる

ansible コマンドで、各クライアントに ping を飛ばしてみる。

[root@bag-ansible-01 ~]# ansible VM-back -m ping -u root --ask-pass
SSH password:
b1-bag-dns-01 | success >> {
    "changed": false,
    "ping": "pong"
}

b1-bag-ansible-01 | success >> {
    "changed": false,
    "ping": "pong"
}

....

無事、"pong" と返ってきた。サーバとクライアントの疎通が正常に行われていることが分かる。もし上手くいかない場合、python へのバージョンが通っていないか、ssh での接続ができていない可能性がある。ssh コマンドで接続したりして、正常に繋がるか確認すると良い。

ansible コマンド詳細

上のコマンドは、下記の通りとなる。

# ansible {ホスト名・IP アドレス、もしくはグループ名} -m {実行モジュール名} -u {ユーザー名} --ask-pass
 → "--ask-pass" は、ssh 鍵交換でのログインを行わない場合のパスワード指定をするか否か、のオプション。

"-m" で指定するモジュールは、Ansible で用意されているものとなり、シェルで実行できるファイルではない。ちなみに "-a" で、モジュールに対するオプションを指定することができる。

この通り、ansible コマンドで全ての動作を行えるが、より複雑なことをしたい場合、ワンライナーのコマンドでは限界が出てくる。なので、Playbook という「何をやりたいか」が記載されたファイルを作成し、これを ansible-playbook コマンドに読み込ませ実行させることで、より高度で複雑、かつ大規模な運用を行うことができる。

データ形式yaml」を覚えつつ、Playbook を作れるようになる

Playbook は「どのホストに対し、何をやりたいか」ということを記載した設定ファイルとなる。Playbook は YAML という形式を採用しており、シンプルに見えるが、プログラマではない人間の固い頭では理解が難しく、書くに難しい。。。

YAML を覚えよう

おいらが説明するよりかは、他の方の説明の方が大変分かりやすいので、そちらを提示いたしやす。。。御参考させて頂いたのが下記。

Yamlファイル - Bukkit Japan Wiki
http://bukkitwiki.jp/Yaml%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB
ansible使いのためのYAML入門 - @znz blog
http://blog.n-z.jp/blog/2014-06-21-ansible-yaml.html
YAML入門 (全9回) - プログラミングならドットインストール
http://dotinstall.com/lessons/basic_yaml

おいらの雑な覚えかた

本当に雑で恐縮だが、、、同じ色の物がリスト (塊) であると意識したら理解できた。

work ディレクトリ準備

Playbook を書く前に、作業用ディレクトリを準備し、その中で Playbook や設定ファイルなどを格納するようにする。きちんとしたフォルダ構成であれば Mercurial や git でも管理しやすくなる。

/etc/ansible/config/
.
`-- roles
    `-- common
        |-- defaults
        |-- files
        |   `-- tmp
        |-- meta
        `-- tasks

Best Practice なディレクトリ構成については、公式のドキュメントを含めて、色々な所で論じられているので参考にすると吉。

Best Practices ? Ansible Documentation
http://docs.ansible.com/playbooks_best_practices.html
Ansibleのファイルとディレクトリ管理 | /var/log/azumakuniyuki
http://blog.azumakuniyuki.org/2014/05/manage-files-for-ansible.html

どういう単位でフォルダを作成しなければならないかとか、色々難しいところ。

Playbook を書いてみる: ユーザーの作成

"/etc/ansible/config/roles/common/tasks" に、"ansible" ユーザーを作成する Playbook を作ってみる。モジュールは user を使用する。

---
# Add ansible user
- hosts: VM-back
  sudo: yes
  vars:
    password: <<hogehoge>>

  tasks:
    - name: Add ansible user
      user: name=ansible password={{password}}

パスワードは /etc/shadow と同じくハッシュ化したパスワードになる。SHA-512 で作っておけば、セキュリティ的には基本問題ない。

※ インターネット上では、"$1" を指定して MD5 でパスワード作ってる人が何人かいたので。。。理解なしのコピペは本当に危険です。

ひつまぶし食べたい: /etc/shadowについて勉強してみた
ddhttp://hitsumabushi-pc.blogspot.jp/2011/12/etcshadow.htmlMan page of CRYPT
http://linuxjm.sourceforge.jp/html/LDP_man-pages/man3/crypt.3.html
user - Manage user accounts ? Ansible Documentation
http://docs.ansible.com/user_module.html

実行してみよう

ansible-playbook コマンドで実行する。

[root@bag-ansible-01 tasks]# ansible-playbook 01_Add_ansible_user.yml -u root --ask-pass
SSH password:

PLAY [VM-back] ****************************************************************
ok: [b1-bag-ansible-01]
ok: [b1-bag-dns-01]
ok: [b1-bag-rss-01]
ok: [b1-bag-pacmanrepo-01]

TASK: [Add ansible user] ******************************************************
ok: [b1-bag-ansible-01]
ok: [b1-bag-pacmanrepo-01]
ok: [b1-bag-dns-01]
ok: [b1-bag-rss-01]

PLAY RECAP ********************************************************************
b1-bag-ansible-01          : ok=2    changed=0    unreachable=0    failed=0
b1-bag-dns-01              : ok=2    changed=0    unreachable=0    failed=0
b1-bag-pacmanrepo-01       : ok=2    changed=0    unreachable=0    failed=0
b1-bag-rss-01              : ok=2    changed=0    unreachable=0    failed=0

対象のマシンに対し、ansible ユーザーが作成され、パスワードも設定された。

ansible-playbook コマンド詳細

# ansible-playbook {Playbook ファイル名.yml} -u {実行ユーザー} --ask-pass
 → "--ask-pass" は、パスワード指定をするか否か、のオプション。

Playbook: ansible ユーザーの ssh 公開鍵を追加

先程作成した ansible ユーザーに対して、公開鍵を ~/.ssh/authorized_keys に追加する。

---
- hosts: VM-back
  tasks:
  - name: Add authorized key ansible user
    authorized_key: user=ansible key="{{ lookup('file', '/home/ansible/.ssh/id_rsa.pub') }}"

これで、ansible ユーザーで、各ホストに ansible ユーザーで ssh 鍵交換ログインができるようになった。

まとめ

Playbook を作成するところまで。この調子で Playbook を増やしていけば、段々と覚えていけるはず。

今後は、大規模になった場合の Playbook の分割のセオリーや、テクニックを覚えていきたい。

参考

Ansible Documentation ? Ansible Documentation
http://docs.ansible.com/index.html
Ansible チュートリアル | Ansible Tutorial in Japanese
http://yteraoka.github.io/ansible-tutorial/

Arch Linux + NSD で仮想マシン用の DNS サーバを作った

Linux

Ansible で名前で指定して管理したかったので、DNS の勉強がてら作った。とりあえず今回は、内向き DNS のサービスとして動くまでが目標。

環境 + 環境作り

いつも通り、Arch Linux をインストールし、"pacman -Syu" した。

今回は、本来の名前 (表ホスト名) と裏の名前で、正引き・逆引きができるようにした。裏の名前も DNS のゾーンに書いていいかは、マナーとか RFC 的に良いか悪いかは不明。

NSD について

NSD (Name Server Daemon) は高性能で簡単なオープンソースの権威ネームサーバです。

http://unbound.jp/nsd4/

ということなので、シンプルな DNS サーバだった。NLnet Labs という研究所が作っているらしい。

一般的な、というより BIND と違い、DNS 情報をキャッシュするキャッシュサーバ機能が存在しない。NSD は「コンテンツサーバ」としての機能だけを持つ。詳しくは、下記がとても参考させて頂いた。

@IT:DNS Tips:ネームサーバの3つの働きとは
http://www.atmarkit.co.jp/fnetwork/dnstips/005.html

上記で言う、キャッシュサーバー機能こと「フルサービスリゾルバ」と、他のサーバから DNS 情報を教えてもらいに行く「スタブリゾルバ」は、同研究所の Unbound が担う。

NSD インストール

Arch Linux なら pacman で一発です。そう pacman ならね。

[root@bag-dns-01 ~]# pacman -S nsd
resolving dependencies...
looking for inter-conflicts...

Packages (1): nsd-4.0.3-1

...

いつもながら、華麗なお点前でした。ワザマエ!

nsd.conf を編集

/etc/nsd の配下に nsd.conf.sample がデフォルトで配置されているので、cp とかで nsd.conf にする。

nsd.conf の中身

nsd.conf は 3 つのセクションに分かれている。

  • server:
    • NSD の基本的な設定。グローバルオプション。
  • remote-control:
    • NSD をリモート管理する場合の設定。デフォルト無効。
  • zone:
    • DNS のゾーンの設定。ゾーンの数分、セクションが増えることになる。

他に、patternkey があるが、今回は解説しない。多分、使わないから。。。

コメントは "#" を先頭に指定。

server:

server: のセクションは、デフォルトで設定がされているため、ほぼ弄ることはない。おいらは、IPv6 を無効にするのと、zone ファイルの格納先を変更する設定のみを行った。

# listen on IPv6 connections
        do-ip6: no

# The directory for zonefile: files.  The daemon chdirs here.
# zonesdir: "//etc/nsd"
        zonesdir: "/etc/nsd/zones"

remote-control:

nsd-control コマンドから NSD を操作したい場合、このセクションの設定をする必要がある。おいらは使わなかったのでデフォルト。。。

zone:

ゾーン名とゾーンファイルの指定を行う。複数のセクションにすることで、ゾーンを複数指定することが可能。

# zone-1 192.168.0/24 - Front Network

 zone:
        name: example-zone.local
        zonefile: example-zone.local.zone

 zone:
        name: 0.168.192.in-addr.arpa
        zonefile: 0.168.192.in-addr.arpa.zone


# zone-2 192.168.1/24 - Backend Network

 zone:
        name: b1.example-zone.local
        zonefile: b1.example-zone.local.zone

 zone:
        name: 1.168.192.in-addr.arpa
        zonefile: 1.168.192.in-addr.arpa.zone

ゾーンファイルの作成

デフォルトでは /etc/nsd、ないし "zonesdir:" で指定したディレクトリにゾーンファイルを設置する。この DNS ゾーンファイルは、RFC で書式が決められているので、BIND でも NSD でも共通になる。

RFC 1035 - Domain names - implementation and specification
http://tools.ietf.org/html/rfc1035

ゾーンファイルは RHEL のウェブサイトなどを参考に、がんばって作った。見よう見真似で。

14.2.2. ゾーンファイルの編集
https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/s2-bind-zone.html

NSD の起動・停止・再起動

systemctl から行える。

  • 起動: systemctl start nsd
  • 停止: systemctl stop nsd
  • 再起動: systemclt restart nsd
    • ゾーンファイルの編集を行った際などは、再起動が必要

まとめ

とりあえず、必要最低限の DNS サーバは立てられたので、今後はもっと便利に活用できるよう勉強したい。

CentOS 7 + ZFS でファイルサーバを作成

Linux

を、作った。

前置き

以前から、Arch Linux + ZFS でファイルサーバを動かしてたけど、諸々あって CentOS 7 で再作成する運びになった。

理由

  • Arch LinuxZFS パッケージ周りが、しょっちゅう Kernel とコンフリクトおこして、まともに Kernel アップデートもできない。
  • パッケージ名も "zfs" から "zfs-git" になったりと、バタバタしている印象を覚えた。アップデートについていくので精一杯。
    • 大変な思いされてるパッケージメンテナの方々には申し訳ないが。。。
    • コンフリクトおこして、しょっちゅう pacman -Syu 失敗するわで、その度に切り分けやってたらきりがなかった。なので、Arch Linuxzfs で安定はしてても、先行き不安になった。
  • ローリングリリースならではの、「なにかあったときの怖さ」
    • Arch Linux 全否定ですが。。。
    • できる限り安定性求めるなら、CentOS しかないと思った。

以上より、KVM/qemu やその他は安定していたので不安は感じないものの、ZFS だけは Arch Linux じゃ厳しいと思った。

環境

  • HP Micorserver (non Gen8)
  • システム領域用 HDD (250 GB) *1
  • ZFS 用 HDD (3 TB) *3

メモリ 2GB。お値段が安くなったら追加したいですね。

これを RAID 5 同等の信頼性を持ったファイルサーバにする。

基礎知識

そもそも ZFS ってなんなのか。

複数の HDD を束ねて RAID するファイルシステム

ファイルシステムとしては XFS、ext4/3/2 と同じ土俵、Software RAID としては md と同じ土俵らしい。RAID としての機能を持ちながらも、作成した時点で、デバイスはファイルシステムとしてフォーマット済みとなる。

md の場合、mkfs などでファイルシステムとしてフォーマットしなければならない、つまり LUN の提供までを担うが、ZFS はさらにファイルシステムとしてボリュームを見せてくれる。

高機能な RAID 5 が作れる

RAID 5 と同等の RAIDZ (RAID-Z) を作成できる。RAIDZ は RAID 5 の弱点を克服したものになる。

RAID 5 は、サーバに対する突然の停電に弱く、何も対策がされていない場合、データの不整合 → つまりファイル破損などが起きる危険性がある。そのため、ハードウェア RAID の場合、キャッシュやバッテリーが装備される。

詳しく説明すると、ディスクごとに分散させつつ冗長させてデータ (パリティブロック) を書き込んでいる。その冗長させた各パリティブロック同士が同じ値にならないといけないのにもかかわらず、突然の停電などで書き込みがストップし、書き込みタイムラグにより同じデータにならない危険性がある。ハードウェア RAID は、それに対応するため、キャッシュやバッテリーを使い、最後までデータの書き込みを担保し、破損させないようにしている。

RAID-Z (Jeff Bonwick's Blog)
https://blogs.oracle.com/bonwick/entry/raid_z5

上記を RAIDZ は克服している。突然の停電などでも、データ破損は起こらない。対策の結果、「RAID」と「ファイルシステム」を組み合わせることになったらしいが、アーキテクチャ云々の詳しいことはおいらには理解できなかった。。。また、処理も高速らしい。パリティを可変長にした結果とのこと。

なお、ZFS on Linux では、下記のように定義されている。

  • RAID 5 と同等 → RAIDZ-1
  • RAID 6 と同等 → RAIDZ-2
  • RAID 6 に 1 つの冗長ディスクをさらに追加 (3 つの冗長ディスク) → RAIDZ-3

単語など

プール

ZFS で一つのファイルシステム (RAID でまとめられたもの) をこう呼ぶ。

zpool

ZFS もろもろはこのコマンドから行われる。

/tank

ZFS で作られたプールは、/tank というディレクトリ以下にマウントされるのが常っぽい。いわゆる慣例的な。

まとめ

ワンコマンドで、ディスクを束ねて RAID を作りつつ、ファイルシステムとしてフォーマットしてくれるすごい奴と覚えればいい。

ZFS 作成まで

下記のドキュメントを参照しつつ、構築した。

Aaron Toponce's user guide for ZFS on Linux.
https://pthree.org/2012/04/17/install-zfs-on-debian-gnulinux/

ZFS on Linux からリンクが貼られているページ。

CentOS 7 インストール

普通にインストールして、firewalld と selinux を無効にして (良くはないが)、最終的に yum update すれば問題なし。

唯一気をつけることがあるとすれば、HDD は BIOS からは ACHI で見せたほうがいい。ストレージや RAID コントローラを使っている場合は、JBOD を使用すべき。

Consider using JBOD-mode for storage arrays rather than hardware RAID so that ZFS can manage the storage and the redundancy. http://docs.oracle.com/cd/E23823_01/html/819-5461/zfspools-4.html

あたりまえだけど、ディスク 1 本 1 本を束ねず JBOD として LUN を見せないと駄目ですからね。。。

zfs 対象ディスクのパーティションテーブルを GPT に変更

2 TB 以上の HDD は GPT にする必要がある。ZFS でフォーマットされる場合も、もれなくひっかかる。

parted コマンドで変更・確認が可能である。

確認

 [root@palestine ~]# parted -l

(省略)

Error: /dev/sdb: unrecognised disk label
Model: ATA ST3000DM001-1ER1 (scsi)
Disk /dev/sdb: 3001GB
Sector size (logical/physical): 512B/4096B
Partition Table: unknown
Disk Flags:

未フォーマットというのもあり、Partition Table: unknown となっている。

変更

parted で対象のデバイスを選択したあと、シェルから mklabel gpt で変更する。

[root@palestine ~]# parted /dev/sdb
GNU Parted 3.1
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) mklabel gpt
(parted) quit
Information: You may need to update /etc/fstab.

[root@palestine ~]#

"parted -l" をして、GPT であることを確認する。

Model: ATA ST3000DM001-1ER1 (scsi)
Disk /dev/sdb: 3001GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:

"Partition Table" 行が gpt となっていれば OK。

RAIDZ (RAIDZ-1) 作成

下記の通りにコマンドを実行すれば、作成可能。

zpool create -m {マウント先} {プール名} {RAID レベル} {デバイス 1} {デバイス 2} ...

今回は、RAIDZ-1 になるので

zpool create -m /tank/zfs_pool/zfspool01/ zfs-pool1 raidz1 sdb sdc sdd

となる。コマンドを実行して、標準出力・エラー出力に何も表示されなければ、使用可能になる。なお、サーバを再起動しても、何も設定しなくとも自動でマウントされる。また、ファイルシステムが既にあったり、以前 RAIDZ を作成していたりすると、エラーが出る場合があるが、-f オプションで強制することで、回避できる。

ついでに、sambanfs 設定

備忘録として。

samba 設定

yumsamba をインストール。

# yum install samba

/etc/samba/smb.conf を編集。

[datashare_01]
        comment = datashare_01 (/tank/zfs_pool/zfspool01/datashare_01)
        path = /tank/zfs_pool/zfspool01/datashare_01
        public = no
        writeable = yes

[datashare_02]
        comment = datashare_02 (/tank/zfs_pool/zfspool01/datashare_02)
        path = /tank/zfs_pool/zfspool01/datashare_02
        public = no
        writeable = yes

プリントサーバにはしないので、Printing Options セクションの "load printers ="no にしておいた。

下記を実行し、ユーザ登録。

# useradd lazy_dog
# pdbedit -a -u lazy_dog

下記を実行し、起動。

# systemctl enable smb
# systemctl start smb

Windows 8.1 側で、ネットワークドライブ接続を確認した。

nfs 設定

yumnfs-utils をインストール。

yum install nfs-utils

/etc/exports を編集。一応、セキュリティを考慮して、裏のセグメントのみ接続可能に。

[root@israel /]# cat /etc/exports
/tank/zfs_pool/zfspool01/datashare_01 192.168.1.0/24(rw)

下記を実行し、起動。必要なときだけ起動する方針で。

# systemctl start rpcbind
# systemctl start nfslock
# systemctl start nfs

クライアント側から、下記コマンドで接続できることを確認した。

mount -t nfs 192.168.1.7:/tank/zfs_pool/zfspool01/datashare_01 /mnt/nfs

nfs なんて使わないだろうな、と思いきや、virt-install コマンドで iso イメージのパスを samba にすると NG なので、結構に使う。

Arch LinuxKVM/qemu (環境構築から VM の作成まで) - 私をペロペロするがよい
http://lazy-dog.hatenablog.com/entry/2014/07/13/015538

まとめ

エンジョイファイルサーバありの生活。

余談にはなるけど、HP のハードウェア RAID コントローラについての技術文書が面白そうだったから、後で読む。

HP SmartアレイコントローラーおよびRAIDの基本的なパフォーマンスファクター
http://h50146.www5.hp.com/products/servers/proliant/whitepaper/wp122_1008/

Linux Shell: パスワードを聞くシェルスクリプトのサンプル

Linux スクリプト

パスワード聞いてくるあれをシェルスクリプトで実装してみた。bashzsh で動いていることを確認。

スクリプトサンプル

# パスワードを尋ねる

echo ""
echo -n 'password: ' && read -s root_passwd1
echo ""
echo -n 'retype password: ' && read -s root_passwd2
echo ""
echo ""


## パスワードをチェックする。だめだったら、再度聞く。それでもだめならループ。

if [ "${root_passwd1}" != "${root_passwd2}" ]; then

    until [ "${root_passwd1}" = "${root_passwd2}" ]
    do

        echo "Password mismatch. Please retry."
        echo ""
        echo -n 'password: ' && read -s root_passwd1
        echo ""
        echo -n 'retype password: ' && read -s root_passwd2
        echo ""
        echo ""

    done 
fi
echo ""
echo ""


## パスワードを設定する
echo "password for root user"
echo ""

echo "root:"${root_passwd1}"" | chpasswd

read で文字入力を変数に入れつつ、同じ行に echo で文章出すとき、zshbash とで挙動が違って苦労した覚えがある。