UPS からの shutdown について

なんてこった。前回の更新から 1 年以上が経過しているではないですか。 新しいサーバはときどきさわって、いらいらする程度には systemd について知ることができました。

さて、我が家では家庭内での瞬電に備えて UPS をサーバに繋いでおります。 RAIDZ2 といえでも電源が落ちて、ディスクのヘッドに何か起きてしまうことを防ぐためです。 想定される瞬電は、夏場や冬場によくあるブレーカが落ちる、くらいしか考えていませんでした。 この場合は、電源はすぐに復旧するため、人間がブレーカを上げるまでの時間生きていれば問題ない、という設計でした。

ところが、久しぶりに地震が発生したことをうけて、しばらく電力の共有が止まってしまう状況を考慮したくなりました。 一昔前であればシリアルで UPS につなぐのですが、私が使っている製品は USB 経由でつながるようなので繋げてみました。

使っている UPS はこれです。

無停電電源装置(UPS) BY50S https://socialsolution.omron.com/jp/ja/products_service/ups/direct/ups/by.html#DIRECT_BY50S

2014 年 2 月頃から利用していて、バッテリも 2 回ほど交換しております。 たぶん、ロードの低いサーバを 1 台維持するにはちょうどよい一般家庭モデルだと思います。 Linux からの制御プログラムはソース付きで公開していただいているので、今回はこれを使います。

Simple Shutdown Software Ver 2.41(Linux版) https://socialsolution.omron.com/jp/ja/products_service/ups/support/download/soft/sss/sss.html

スクロールして下の方に行くとあります。 結論だけ先に書くと、 Makefile を少し直して環境を整えてビルドするのが楽だと思います。 config.sh という sh のスクリプトでもない実行バイナリから設定を行いますが、このプログラムが libusb-0.1.so.4 を要求してきます。 ここ最近の libusb は 1.0 系のバージョンなのですが、 0.1 系と互換性がないんですよね。 ちょっとはまりました。 Gentoo Linux だと、こんな名前で別途用意があるので、とりあえずは大丈夫です

# emerge --ask dev-libs/libusb-compat

次は SimpleSoftwareVer241_Linux_X64/Source にある以下の Makefile を直します。

やることは簡単で、 -DREDHAT っていう文字列を消すだけです。 -D に REDHAD って、初めてみましたよ。 複数ファイルで同じ作業したくないので、 1 行で書くとこんな感じでしょうか。 完全に手癖ですね。

/root/SimpleSoftwareVer241_Linux_X64/Source # grep REDHAT * -R -H | sed -e 's/:..*$//g' | sort -u | while read -r I; do sed -i 's/\-DREDHAT//g' $I; done

ここまで準備してから make すると、通りました。 あとは添付のドキュメント通りにやれば動きます。 とはいえ、個人的にやりたいとおもっていることは結構あるんですよね。

  1. ユーザが人間であることを前提とした設計の各プログラムの改修
  2. systemd あるいは OpenRC へ組み込むための ebuild の作成
  3. libusb 1.0 系への移行

1 はですね、インタラクティブな UI をやめてオプションや標準入出力で制御できるようにしたいってことです。ソフトウェアの梃子を使うのです。 自動化しようと思ったら避けられません。 2 で言いたいことは、現在のままだと root が動かしている野良プログラムになっちゃってるんですよね。 きちんとパッケージとして管理したほうが依存関係で壊れたり、起動し忘れることもなくなります。 3 は楽しいこと間違いなしですが、こう見えて結構忙しい生活をしているので、気が向いて能力があったらですね。

というか、電源を落とすことは滅多にないので、現状維持で問題ないかもしれません。

ファイルサーバのリプレイス 2020 感想

基本的な作業が終わって、一区切りついたこともあり、個人の感想を残しておきます。未来の自分が読んで、どうしてこんなことになったのか、思い出すきっかけになれば良いです。

PC-UNIX で遊ぶ、という趣味を始めて 20 年くらい経ちます。特にこの 5 年くらいの間に、私自身に大きな変化がありました。英語の運用能力が桁違いに上がったのです。すると、いろいろな調査や問題解決に必要な情報は、英語の一次情報を参照することがほとんどになりました。当然、理解も速くなりますし、問題解決に至る時間も短くなることがあります。そして、ここがポイントなのですが、だからと言って英語で得た知識を日本語にするかというと、しません。得た知識を日本語におとすことはしないのです。知識の言語化という作業は大変だからです。これは、結構大きい分断であるように感じました。

英語の運用能力といってもいろいろあります。教科書や論文を読む程度から、読んで聞いて話して書く程度まであります。個人的には、話す書く機会が増えてから、読む速度が上がったように感じます。実際、仕事のドキュメントは英語が中心となって 8 年くらいたちます。ネットワークや OS を扱う仕事ではないので、いざ趣味で英語を使うと、以前と比べて世界の見え方がずいぶんと変わることに気付きます。

ドキュメントの読み方について、今回 Gentoo Wiki にむちゃくちゃお世話になりました。そこで気づいたことがあります。Arch Linux のドキュメントは結構よくまとまっています。

ArchWiki
https://wiki.archlinux.org/

Gentoo Wiki の各ページでも External resources で ArchWiki への参照があることも多かった印象です。ディストリビューションに依存しない知識ついては、 ArchWiki を参照したこともあります。どれがどうだったかは覚えていません。ちなみに Arch Linux については、名前しか知りません。深そうな沼であることはよくわかりました。

とりあえずそんな感じです。

いかがでしたか?

ファイルサーバのリプレイス 2020 その 4

これで最後です、たぶん。たくさん書いて疲れたので、ちょっと休憩しました。

ZFS でのファイルシステムの構築と、一般的なリプレース作業について残しておきます。

前回までのあらすじとして、なにはなくとも、内部ストレージから boot していると思います。ここまで来たら、ユーザランドZFS を扱うプログラムを用意して設定を行うことができます。以下のドキュメントを読んでおけば大丈夫です。

ZFS
https://wiki.gentoo.org/wiki/ZFS

今回はハードディスク 6 本で RAIDZ2 のボリュームを作ります。ディスクが 2 本まで壊れても大丈夫な構成です。

# zpool create -o ashift=12 -m /home home raidz2 sda sdb sdc sdd sde sdf

ashift オプションに 12 を指定しているのは、使っているハードディスクのセクタ長が 4096 バイトだからです。2 の 12 乗が 4096 になります。デフォルトでは自動でカーネルが検知した値を使ってくれるそうですが、明示的に指定しています。セクタ長より大きい値を用いると I/O で用いる単位が大きくなるのでパフォーマンスが良くなるそうです。しかしながら、これは利用可能なストレージ容量とのトレードオフになります。好み、でしょうね。

このボリュームの利用用途は、まさにホームディレクトリなので名前は home ですし、 mount ポイントも /home です。この mount の設定は /etc/fstab に書く必要はありません。ZFS 関連のデーモンが上がれば、自動的に mount してくれます。なので、 OS の起動時に自動でデーモンをあげるよう、忘れずに設定する必要があります。最初の 1 回を忘れなければ大丈夫です。

さて、ようやく広大なファイルシステムを手に入れることができました。いよいよリプレースの作業を行いますが、オリジナルから移行するのは /etc/passwd, /etc/shadow, /etc/group くらいでしょうか。ログインするユーザの UID と GID を移行しておけば概ね問題はありません。

いよいよ、データを移行します。すでに稼働しているファイルサーバからデータを持ってくるわけですが、幸にして両方とも ZFS を利用しています。なので、現行のサーバでスナップショットを作成して、新しいサーバに適用できるわけです。受け渡し方法として、スナップショットを標準出力で ssh へ渡して、受け取る側も標準入力で受け取るという、なかなかシンプルな方法があります。これだとファイルごとに TCP コネクションを作り直す必要がないので、 TCP 的には絶好調な Window サイズでどんどんデータを遅れる、と思います。

ZFS のバージョンは同じではないので、そのまま適用できるわけではないのですが、意外にも Oracle のドキュメントにいろいろヒントがあります。もともとは Sun Microsystems の成果物ですしね。

Oracle Solaris ZFS 管理ガイド > ZFS データのリモート複製
https://docs.oracle.com/cd/E24845_01/html/819-6260/gbchx.html#gbinz

もしかしたら、英語版のドキュメントの方が新かったり、メンテナンスされているかもしれません。日本語ドキュメントがとても読みやすかったので、とくに英語版はみていません。

新しく作ったサーバの IP アドレスを 192.168.0.127 にしたので、現行のファイルサーバから以下を実行しました。

# zfs snapshot home@today
# zfs send home@today | ssh root@192.168.0.127 zfs recv -F home@today

途中経過とか一切わからないので、ひたすら信じて放置します。正常終了したら、データ移行はおしまいです。あっけないですね。

ちなみに、現行のファイルサーバの uptime がひどいことになっていました。

# uptime
 18:03:30 up 380 days,  3:22,  1 user,  load average: 0.00, 0.03, 0.27

ユーザランドはちょいちょい更新して、遊んだりしていたのですが、カーネルは何も変えていなかったのです。とはいえ、 1 年以上も安定稼働していたわけで、ちょっとごつい PC のわりにはよくがんばったと思います。

主な作業はこれでおしまいです。あとは現行サーバの IP アドレスと新しいサーバの IP アドレスをスイッチして、動作確認して問題なければ大丈夫です。他にもいつものツール群やサーバアプリケーションなどなど、設定事項はいくらでもありますが、いったんはおしまいとします。

ファイルサーバのリプレイス 2020 その 3

リプレースが終わって、もうどれくらい経ったのだろうか。動き始めてしまうと、構築の時の苦労なんて忘れてしまいます。とはいえ何年か後に、どうしてこんなことになったのか問い詰めたいという自分自身のために、参照情報を残しておきます。

今回はブートローダカーネルのお話です。

ブートローダの話の前に、カーネルの作り方について少し考える必要があります。ハンドブックと異なり、 OpenRC ではなく systemd を使いたいので、systemd のユーザランドを持つ stage3 を選択しました。このユーザランドを使うためには、当然カーネルも systemd の要求を満たす必要があります。個人的には Linux の make menuconfig はあまり好きではなく(略)。例によって Gentoo Wiki で大抵の情報は集まります。

systemd
https://wiki.gentoo.org/wiki/Systemd

せっかくなので、 docker が動くようにもしておきましょう。

Docker
https://wiki.gentoo.org/wiki/Docker

当然、 ZFSカーネルが機能を持たなくては扱うことができないので、設定します。

ZFS
https://wiki.gentoo.org/wiki/ZFS

今回は MBR(Master Boot Record) ではなく UEFI(Unified Extensible Firmware Interface) から boot するようにしたいので、 UEFI へのインターフェースをカーネルに持つようにします。

EFI System Partition
https://wiki.gentoo.org/wiki/EFI_System_Partition

Efibootmgr
https://wiki.gentoo.org/wiki/Efibootmgr

この段階では、上記のドキュメントの全てに目を通す必要はなく、 Kernel の設定部分を参照するだけで大丈夫です。他の部分は、あとでまた参照することになります。

次は、いよいよブートローダの設定になります。結論から説明すると、今回はブートローダを導入することはしません。UEFI の機能とファイルシステムに直接カーネルを設定します。まず、この UEFI で用いる特別なパーティション ESP(EFI System Partition) が必要なわけですが、 FAT32 とか VFAT と呼ばれるファイルシステムである必要があります。実はここで少しはまりました。こんな大事な規格に Microsoft の独自規格が採用されるわけがない、なんてことはないのです。

忘れずにファイルシステムを作って /boot に mount します。

# mkfs.fat -F 32 /dev/nvme0n1p2
# mount /boot

ブートローダを利用しないということは、直接 UEFI からカーネルが boot してストレージなどのリソースを管理し、ファイルシステムを認識した上で、ファイルシステムにあるプログラムを実行して OS として起動します。これでは、異なるストレージやパーティションに存在するファイルシステムを boot のプロセス中に参照することができません。そのため、ブートローダを使う場合には、任意の boot 可能なプログラムを実行し、 RAM ディスクという MS-DOS 時代はたくさん使ったあの仕組みに似た方法で、いったんファイルシステムを mount します。

という仕組みがあって、デュアルブートや起動前にカーネルを選択することのない環境であってもブートローダを使っていたのではなかろうかと、今では思うわけです。

今回は root パーティションの場所をあらかじめカーネルに持たせます。 / を mount しているブロックデバイスですね。さらに、今回は root パーティションさえ mount できれば /usr も /var も同じパーティションにあります。そのため、カーネルが root パーティションを mount できてしまえば、必要なプログラムへの参照には困らないことになります。なので、以下のページについてもカーネルの設定をみておけば大丈夫です。

EFI stub kernel
https://wiki.gentoo.org/wiki/EFI_stub_kernel

ここ 10 年くらいで /dev のブロックデバイスに UUID を振って識別するようにしているディストリビューションもあるようです。ユースケースがあまり思いつかないのですが、オンプレミスで使う限りは今まで通り /dev/sda1 とかっていう、人間が識別できる名前のほうが良いと思っています。確かにデバイスファイルの名前が変わることはあります。しかし、いずれも新しくデバイスを追加削除したり、カーネルを変えたときに限られます。大抵は人間の手が入った時なんじゃないかな、と思うわけです。朝起きたらデバイスファイルの名前が変わってるとか、ほんと何それ怖い、なのですが、あなたの知らない世界はまだまだたくさんあるのかもしれません。

さて、実はカーネルの構築はまだ終わっていません。ここまで設定したら、いよいよカーネルを然るべき場所に置き、UEFI に認識してもらうための設定を行います。

# cd /usr/src/linux
# make -j7 && make -j7 modules_install
# mount /boot
# make install

とか。 -j7 は make が同時に実行するジョブの最大数です。 20 年くらい前は CPU の数、またはコアの数 + 1 がちょうど良い、と言われていました。今回は 6 コアの CPU なので 7 という数字になります。

/boot に作ったカーネルがあります。 ESP に使ってもらえうよう、 efibootmgr というプログラムで設定します。詳細はこのページにあるので、今回は最後まで読みましょう。

Efibootmgr
https://wiki.gentoo.org/wiki/Efibootmgr

ファイルを然るべきところに置いて、 UEFI に設定します。

# cd /boot
# mkdir -p efi/boot/
# cp vmlinuz-5.4.48-gentoo efi/boot/bootx64.efi
# efibootmgr --create --disk /dev/nvme0n1 --part 2 --label "Gentoo" --loader "\efi\boot\bootx64.efi"

ファイルシステムFAT32 なので、パスは \ で区切られます。モヤモヤする。--part 2 では /boot に mount するブロックデバイスがストレージの 2 番目のパーティションにあることをプログラムに教えています。

ここまでの設定が無事に終われば、マザーボードの設定からこのエントリ Gentoo が見えるようになるはずです。見えたら、 boot の優先順位を 1 番にしてあげれば、内部のストレージから起動するようになります。多分、ここが一番ハマりどころだと思います。あちこちにトラップがあるので、 UEFI のエントリに登録されなかったり、登録されてもカーネルが boot しなかったり、カーネルが boot しても panic が起きたり、ユーザランドが動いても root ユーザのパスワードを設定していなかったり、楽しいですね!

次はいよいよ ZFS とリプレース作業そのものです。

ファイルサーバのリプレイス 2020 その 2

なんだかんだで、リプレースは完了しています。思いついてから納品まで 2 週間くらいでした。これから、ゆっくりと運用プロセスを考えますが、これは本当に趣味だからできることだと思います。

さて、未来の自分はきっとこんなところで行き詰まったりしないと思いますが、念のため残しておきます。基本的に Handbook を見ていれば間違いありません。Stage 3 で使うイメージには systemd の名前が入ったものを使いましょう。あとでユーザランドを作り替えるのは大変です。あとは、 OpenRC が呼び出すけど systemd に標準で入っているものも、インストールする必要はありません。いろいろ思い浮かぶけど、きっと見ればわかる。

Handbook:Main Page
https://wiki.gentoo.org/wiki/Handbook:Main_Page

今回の特徴として、 boot するストレージデバイスは NVMe を使うんですね。NVMe でも SATA インターフェスのものと PCIe のものと、形が似ているから本当に注意した方がいいです、というか間違えて買いましたよ。安いな〜、って思ったんですよ、ほんと、認識しませんでした orz。認識したところで試してみたベンチマークがこちらです、好き。

# hdparm -tT --direct /dev/nvme0n1

/dev/nvme0n1:
 Timing O_DIRECT cached reads:   4684 MB in  2.00 seconds = 2341.84 MB/sec
 Timing O_DIRECT disk reads: 8424 MB in  3.00 seconds = 2807.81 MB/sec

こちらの製品を使いました。きっと数年後に参照する。

Transcend TS256GMTE220S
https://jp.transcend-info.com/Products/No-991

OS まわりの話は、この辺を起点にするとちょいちょい知識を得ることができます。

NVMe
https://wiki.gentoo.org/wiki/NVMe

さらに、今回は初めて F2FS というファイルシステムを使ってみました。フラッシュメモリの特性を考慮した、ことになっているファイルシステムということで、特に大事なデータを置くわけではないので、トライします。

F2FS
https://wiki.gentoo.org/wiki/F2FS

実際、 Android 端末でもいくつか採用されているようです。Linux カーネルリポジトリも少し覗きましたが、全く放置されているわけではないようです。動かしてみたくなりますよね。

今回採用したマザーボードはこちら。

ASRock B460M Pro4
https://www.asrock.com/MB/Intel/B460M%20Pro4/index.jp.asp

このマザーボードに載っている Ethernet card がですね、Intel の I219V というチップを使っていて、安心のインテルと思っていたわけですよ。はい、新しいバージョンのドライバでないと認識されません。ここから落としてきて、 make install && modprobe e1000e してください。

https://downloadcenter.intel.com/ja/download/15817/Intel-Network-Adapter-Driver-for-PCIe-Intel-Gigabit-Ethernet-Network-Connections-Under-Linux-

このファイルをブート後にコピーするのがちょっと面倒だったので、ブートイメージの /boot/boot/grub の下にあらかじめ置くようにしておきました。さらに、このドライバかデバイスがまた不安定で、しばらくするとおかしなフレームを吐くのか所属する L2 ネットワークが死にます。てっきり L2 スイッチが寿命を迎えたと思って、新しく買ってしまいましたよ。ですので、このデバイスが正気を保っているうちに sshd をあげてリモートで作業する必要があります。

ちょっと苦労したのは、ブートローダーですね。440byte から boot する BIOS を卒業して、いよいよ UEFI を使うわけですが、理解することが少しあります。だいたい、以下のドキュメントを読んでおけばなんとかなります。

EFI System Partition
https://wiki.gentoo.org/wiki/EFI_System_Partition

Efibootmgr
https://wiki.gentoo.org/wiki/Efibootmgr

EFI stub kernel
https://wiki.gentoo.org/wiki/EFI_stub_kernel

具体的な話はまた今度です。つづきます。

ファイルサーバのリプレイス 2020 その 1

ここ最近は 10 年に 2 回くらいのペースでファイルサーバのリプレイスを行っています。だいたい 20 年くらい前に FreeBSD(98) で始めた趣味なので、結構長く続いている方だと思います。近年は使いやすいオンラインストレージやクラウドサービスが普及してきたこともあり、もうこれは本当に趣味ですよね、としかいいようのない時代になりました。何が楽しいかと言うと、思いがけず発生するトラブルとその問題解決、そして思った通りに動く喜び、これに尽きます。

進捗ですが、計画してから 2 週間経って、ようやく OS が内部ストレージからブートするようになりました。リプレイスが完了するまでのプロセスは、だいたいこんな感じになります。

1. 思いつく
2. 最近の CPU などの情報を調べる
3. パーツを発注する
4. 組み立てる
5. OS とアプリケーションをインストールする <- 今ここ
6. データを移行する
7. 既存のサーバと入れ替える

1 と 2 はだいたい 1 日でなんとなく終わります。3 にはいろいろと家庭内決済プロセスがあり、予算の承認と効果、そしてリスクの説明が求められます。4 では、最近はないですが、 CPU のピンを折ったり、やったことあります。で、現在 5 まできました。

作業内容ですが、幸いなことに、過去の自分がメモを残してくれていました。

ファイルサーバのリプレイス
http://blog.maedee.net/entry/2015/09/27/135933

さすが自分、ありがとう、読ませてもらったけど、あまり役に立たないよね、これ。リンクのドキュメントは 2 年近く更新が行われていません。メモとして残すのであれば、一次情報か、それに近いドキュメントでないと、あっというまに風化しますよ。一昔前に個人のブログや日記が情報源だったのは、自分自身が活発にこの分野で活動していたのだと思う次第です。むしろ 1 年前の自分の方が、より今の自分の考え方に近いです、あたりまえですが。

ファイルサーバの再構築
http://blog.maedee.net/entry/2019/08/03/172813

ということもあり、今回も役に立っているのは以下の 2 つのドキュメントです。

Handbook:Main Page
https://wiki.gentoo.org/wiki/Handbook:Main_Page

Gentoo wiki
https://wiki.gentoo.org/wiki/Main_Page

歳をとったからかもしれないのですが、 10 代や 20 代の頃より落ち着いてドキュメントやマニュアルを読めるようになったように感じます。それでもトラブルはあるので、楽しめなくなったというわけではありません。というわけで、つづきます。

なんの説明もなく Gentoo Linux を使うことになっているのは、想定している読者が未来の自分だからです。

ファイルサーバの再構築

自宅のファイルサーバで docker を動かしたくなってしまったので、いろいろ再構築しました。過去の記事が役に立ちました。

http://blog.maedee.net/entry/2015/09/27/135933

なんでルートファイルシステムまで zfs にしちゃうかな?、4 年前の自分。ブートしなくなった場合、 zfsカーネルモジュールがロードされる Live イメージから起動しないと、何が起きたかわからないとか、怖い。主な作業としては以下の 2 つです。

  1. init から systemd へ移行
  2. docker と zfs が動くようカーネルを再構築

1. はねぇ、カーネルはすでに systemd に対応しているので、ユーザランドだけ「移行」しようと試みましたが、あきらめました。いろいろ依存関係がめんどくさくて、ちょっとパッケージ消して再起動したら起動してこなくなる事象が発生したので。zfs をルートファイルシステムに使っているためか、ブートローダが systemd をうまく呼び出せていないからか、原因の切り分けが面倒になってきたので、 zfs をやめて普通に再インストールしました。そもそも、 systemd 自体が UNIX のコンセプトに反するもののように(略。というわけで、久しぶりにハンドブックを読みながらの作業でした。

Gentoo AMD64 Handbook
https://wiki.gentoo.org/wiki/Handbook:AMD64

もう、ハンドブックがすばらしくて、日本語でも懇切丁寧で、サクサクとインストールできちゃいましたよ。さらに言うとね、どこでも動くバイナリが容易に手に入るこのご時世に、なんで自分はこんなに時間のかかるディストリビューションを選んでいるのか、いろいろ思うところもありました。時間はかかりますが、「わかりやすい」ディストリビューションだと思います、 Gentoo は。理解度が上がる、という意味で、わかりやすいです。ハンドブックと異なるのは、 systemd のユーザランドを持っている stage3 のイメージを使ったくらいかな。なので、忘れちゃいけないのは、ブートローダの設定で systemd を指定すること。

このページの後ろの方に記載があります。

GRUB2 Quick Start
https://wiki.gentoo.org/wiki/GRUB2_Quick_Start

2. についても、 Wiki ページがあるので、かなり楽ができます。

Docker
https://wiki.gentoo.org/wiki/Docker

ZFS
https://wiki.gentoo.org/wiki/ZFS

なんというか、 Linuxカーネル再構築って、設定がものすごくわかりにくいよね。make menuconfig って、とっつきやすいように見えて、 GUI 特有の再現性のなさ、みたいなところがあってもどかしいです。昔、FreeBSD で生活していた頃はコメント付きの設定ファイルを編集して、 make してエラーがなければ OK でした。そのぶん、依存関係のあるような設定で詰まったりしないから、そこは良いところだと思います。と、もどかしいながらも上記のドキュメント通りにカーネルを作って、必要なパッケージを入れると zfs のプールも認識されますし、 docker も動くようになります。

というわけで、 docker は簡単なテストが通りました。俺たちの戦いはこれからだ!