tuned

先ほどのLeapへの変更もそうだが、環境が安定すると弄ってみたくなってしまう。
RedHatなどでは標準で有効化されているtunedデーモンがOpenSUSEでは有効ではなかったので試してみることに。
2.5. Tuned - Red Hat Customer Portal
各種リソースの動作状態を見てパラメータを設定するらしい。
設定項目はかなり多いが、"〜〜向け"というプロファイル設定機能があるため、それを使えば使い始めるのは難しくない。


仮想化環境向けの"virtual-guest","virtual-host"というプロファイルがあるので、まずは仮想マシン側で試し、良さそうならホスト側にも使ってみる。

VFIO-PCI

以前試した時KVMPCI Passthroughで繋がっているっぽい挙動を示したいた無線LANアダプタがVFIO(Virtual Function I/O)で繋がるようになっていた。
PCI Passthroughよりもジェントルに切り離しているように見える。
起動時にintel_iommu=on引数を与えると自動的にVFIOモジュールなどもロードしてきているっぽい。


しばらくqemuの更新→libvirtの更新→カーネルの更新があってなんかうまく動かない時期があったが、抜けたと思われる。


今までは仮想化モニタ側でもドライバがロードされ、仮想マシンを起動させると切り離される動作になっていたが、/etc/modprobe.d/99-local.confにblacklist iwlwifiを書き込みモジュールをロードさせないことでモニタ側からは見えないようにした。
NUCに搭載のIntel 8260はBluetoothWifiの複数機能モジュールだが、WifiはPCIe接続、BluetoothはUSB接続になっているらしく、完全に別のデバイスとして認識されるのでPCIe部分だけ仮想マシン渡すようにした。

Tumbleweed→Leap→Tumbleweed

ふと、"仮想化モニタにはローリングリリースのTumbleweedよりもLTS版のLeapを使った方が良いんじゃないか"と思いついて試してみた。
更新とそれに伴う再起動が結構多く、サーバーとしてこれで良いのかと思ったのもある。


流石に環境を構築して仮想マシンも新規に作り直してダメだったら気が滅入るので、新規インストールではなく、Upgradeで何とかならないか検討する。
本番環境をいきなり試すのもアレだが…


SUSE同士ならLeap→Tumbleweedの移行はリポジトリの置き換えとアップグレードでできることが説明されている。
openSUSE:Tumbleweed インストール - openSUSE Wiki
TumbleweedからLeapに戻すのはできるのか不明だったので、最低限の設定のバックアップを行った後、インストールUSBを作ってやってみたら普通にできた。
ただし、設定ファイルなどが古いバージョンに巻き戻されるため、一部更新が必要な箇所があった。


libvirt仮想マシン定義でQemuのバージョン番号が仮想マシンに入っているため、それを古く(2.6→2.3)する。
また、PCIeのスロット番号に0が許されていないので1からにすれば動いた。


しかしカーネルのマイナーバージョンは上がったものの、IOMMUを有効にするとカーネルパニックを起こす問題は直っておらず、IOMMUを使わずにhostapdを仮想化モニタ側で動かすようにしたが、なんか意味がない気がしてきて結局Tumbleweedに戻してしまった。


Leap42.2が正式リリースされたころにもう一度考えよう。

zswap

KSMから更に"スワップさせない"機能で調べていたらzswapという機能があることを知った。
これは、MacOS MavericksやWindows10で搭載された圧縮メモリと似たようなシステムで、いきなりスワップアウトするのではなく、使用率の低いページを圧縮することでメモリを空ける仕組み。
これによりディスクへのI/Oが減るので高速化と、SSDに関しては書き込みが減るのがメリットになる、CPU負荷は増えるが、現在のマルチコアならそこまで問題にならないだろうということらしい。


SUSEカーネルはサポートしているので、カーネル引数に設定するだけで動く。
Release Notes | SUSE Linux Enterprise Server 12


KSMは仮想化モニタだけで実行すれば良さそうだが、こちらは仮想マシンのOS側でも有効にしてみた。
しばらく様子を見たい。

KSM

pfSenseルータ(メモリ2GB)×2とSSHサーバー(メモリ1.2GB)×3+仮想化モニタでfreeコマンドで8GBほどメモリを占有していると表示される。
KVM+QEMUは起動時に必要なメモリページは確保してしまい、そのあと実際に使っていなければスワップされるという戦略で動いているらしい。
VirtualBoxは逆に必要になったらホストOS上でメモリを確保する戦略で動いているように見える。


仮想化サーバーNUCはメモリ16GBに加え、メモリオーバーコミットに備えた16GBのスワップ領域を用意してあるので特に問題なく動くとは思うが、仮想マシン上では未確保(=ALL 0?)のメモリをわざわざスワップアウトするのも何となくバカらしい気がしたので、KSM(Kernel Samepage Merging)を使ってみることにした。
例によってIBMのサイトに詳細な解説があった。


Linux カーネル共有メモリーの徹底調査


専用のデーモン(ksmd)がメモリページをスキャンし、"あまり更新されない(読み出しデータ/プログラムや0領域)"かつ"内容が同じ"ページを同一のメモリアドレスにまとめることでメモリ使用量を節約する仕組みらしい。
まとめられたページはCoW(Copy on Write)フラグがつけられ、書き込みがない間はそのまま保持され、書き込みが起きると再び分離される。
試すだけならSysfsにechoで1を書き込めば動き出す。


8GBほど使用していたのが、デフォルトパラメータでKSMを有効にすると3.5GBぐらいまで減った。
全ての仮想マシンで同じディストリビューション/カーネルを使っているとKSMの効果が出やすいらしいが、SSH側は多様性のために異なるマシンを使っているので空き容量ぐらいしか効いていない様子。
ルーターの方はまとめられているっぽい。


効果があったので、systemdのksmサービスを使って自動起動するようにする。
とは言っても、上記のecho書き込みを自動化するだけのワンショットサービス。


似たようなシステムはXenvmwareも備えているメジャーな機能らしい。
パフォーマンスへの影響も特になさそうなので、しばらく使ってみる。

三重化SSHサーバー

今までは仮想化モニタがSSHサーバーを兼任していたが、役割を切り分けるためにSSH専用の仮想マシンを立てた。
1台だと外部から接続している際にミスって接続できなくなると実マシンにアクセスするまで復帰できなくなるので、互いにアクセス可能な3台の仮想マシンを作った。
同じOSでホスト名と鍵だけ変えて複製しても良かったが、多様性を考え、SUSE Tumbleweed,Leap,Arch*1とバリエーションを用意した。


…実際はここまで6月中旬に完了し、6月19日から6月30日の間の海外出張&バケーションを使っていきなり実践テストを行った。
たまに更新をしくじったり、DHCPゲートウェイ情報を取り損なったりである1台が不通になったりしたが、他の無事な2台のどちらかにログインし、さらに仮想化モニタに接続してからシリアルコンソールで回復させるという方法で2週間乗り切った。
一応の実績とほとんどSSHとセキュリティ対策ソフトしか動いていないためリソースを食わないので、そのまま三重化を本番にも使うことを決め、運用中。


仮想化モニタとルータのpfSense×2は多重化していないため、更新は家で機械の横にいるときだけというルールで運用すれば、SSHが不通になるまでやらかすことはほぼなさそう。

*1:同僚の推薦

小変更

NUCにはEthernetポートが一つしかないため、各ゾーンはTagged VLAN(IEEE802.1Q)を使ってスイッチで振り分けている。
今まではTag⇔Untagの変換を仮想モニタ上のYaSTとWickedで行っていたが、ブリッジが時々よくわからない挙動を起こしていたので、ふと思い立ってpfSenseで直接VLANを扱うようにした。
これだとブリッジはタグ付きパケットを素通しさせるだけなので、設定も簡単になった。


ブリッジが一つになってパケットが大丈夫か?と思ったが、前の構成でも結局Ethernetの口の部分で一つになってるから似たようなものだった。