はじめに

先日、C100 と Geeko Magazine の告知を出した際、geeko.jp のウェブサーバーが落ちてしまいました。普段は全然問題ないのですが、512 MB の VPS のため、ほんの少しアクセスが増えるとメモリーを使い果たしてしまうようです。

openSUSE の Web サーバーは 2009 年頃から使い続けていることもあって Apache で、しかも MPM (Multi-processing modules) は prefork です。複数のアクセスに対してプロセスを作成して対応するので、メモリー使用量やプロセスの生成コストが課題です。設定変更前のメモリー使用量を見ると次のような状態で、1プロセスあたり 30 MB 前後使っています。とりあえずの対策としては、プロセスの最大数を抑えればよいのですが、メモリー使用量削減のため、これを機に MPM を event にすることにしました。

# smem -U wwwrun -k
  PID User     Command                         Swap      USS      PSS      RSS 
26053 wwwrun   /usr/sbin/httpd-prefork -DS    24.2M   576.0K     1.3M     9.5M 
23952 wwwrun   /usr/sbin/httpd-prefork -DS    14.5M    20.8M    21.7M    30.4M 
26051 wwwrun   /usr/sbin/httpd-prefork -DS     5.6M    23.5M    24.4M    32.9M 
23953 wwwrun   /usr/sbin/httpd-prefork -DS     6.3M    23.7M    24.4M    31.8M 
 2023 wwwrun   /usr/sbin/httpd-prefork -DS     5.4M    24.0M    24.8M    32.7M 
 7054 wwwrun   /usr/sbin/httpd-prefork -DS     7.5M    26.0M    26.8M    35.0M 
23955 wwwrun   /usr/sbin/httpd-prefork -DS     5.0M    32.6M    33.6M    42.2M 
23956 wwwrun   /usr/sbin/httpd-prefork -DS     5.5M    34.2M    34.9M    43.1M 
23959 wwwrun   /usr/sbin/httpd-prefork -DS     5.5M    34.4M    35.3M    43.8M 
 2022 wwwrun   /usr/sbin/httpd-prefork -DS     6.0M    34.7M    35.6M    43.6M

少し前までの Apache の MPM といえば worker で、スレッドを使って並列処理をします。私の知識もここで止まっていました。event は新しい MPM で、今どきのイベント駆動で実装されています。ワーカースレッド内で受信待ちやソケット書き込み待ちをせずに、パケット到着や書き込み可能になったイベントを受けてスレッドに処理を割り当てるようです。

MPM を prefork から event にするために必要なことは、次の通りです。

  • event MPM をインストールする
  • PHP を mod_php による実行から mod_proxy_fcgi + php_fpm (FastCGI) による実行に変える
  • php_fpm で Web アプリを実行できるように AppArmor のプロファイルを設定する

結構面倒くさいですね。

openSUSE のバージョンは Leap 15.4 です。

event MPM をインストールする

これは簡単で apache2-event をインストールするだけです。apache2-prefork もインストールされいる環境では、apache2-event が優先されます。

zypper in apache2-event

mod_proxy_fcgi + php_fpm への変更

これまでは mod_php でこの Word Press などを実行してきました。mod_php の場合、PHP のスクリプトは Apache のプロセスで実行されていました。マルチスレッドに対応していない mod_php は event や worker では使用できません。php_fpm で PHP を別プロセスで起動しておき、リクエスト時にこの PHP プロセスに処理を依頼する形に変更する必要があります。

セットアップ手順は以下の通りです。php7-fpm をインストールして、パッケージに含まれるデフォルトの設定を有効化します。

zypper in php7-fpm

cd /etc/php7/fpm
mv php-fpm.conf.default php-fpm.conf
cd php-fpm.d
mv www.conf.default www.conf

systemctl enable php-fpm
systemctl start php-fpm

Apache 側の設定を変えます。openSUSE では Apache で使用するモジュールは /etc/sysconfig/apache2 で有効化します。php7 を削除し、proxy と proxy_fcgi を追加します。

APACHE_MODULES="(省略)proxy proxy_fcgi"

次に、php ファイルのハンドリングを mod_php から php_fpm に切り替えます。/etc/apache2/conf.d/ に以下のファイルを作成します。openSUSE のデフォルト設定では php7_fpm は 9000 で待ち受けていますので、php へのアクセスを 127.0.0.1:9000 に転送するようにします。

ProxyErrorOverride on は php_fpm がエラーを返した場合に、php_fpm のエラーメッセージをそのままブラウザに返すのではなく、Apache 側で設定したエラー画面を表示するための設定です。


SetHandler "proxy:fcgi://127.0.0.1:9000"


SetHandler application/x-httpd-php-source

DirectoryIndex index.php4
DirectoryIndex index.php5
DirectoryIndex index.php7
DirectoryIndex index.php
ProxyErrorOverride on

AppArmor の設定変更

openSUSE Leap 15.4 では php_fpm 用の AppArmor プロファイルが含まれており、php_fpm が行える操作に制限がかかっています。そのため、何も設定しないと、php-fpm が php ファイルにアクセスできません。/var/log/audit/ に次のようなログが出力され、403 が返ります。

type=AVC msg=audit(1661003085.840:89050): apparmor="DENIED" operation="open" profile="php-fpm" name="/srv/www/htdocs/index.php" pid=20329 comm="php-fpm" requested_mask="r" denied_mask="r" fsuid=498 ouid=498

php_fpm のプロファイルを調整するには、/etc/apparmor.d/php-fpm.d/ に次のような設定ファイルを作成し、php-fpm がアクセスできるディレクトリを設定します。

  # tmp へのアクセス
  include 
  # htdocs への読み書き
  # 読み取りだけであれば  もあり
  owner /srv/www/htdocs/** rw,

結果

設定後にメモリー使用量を見てみます。

  PID User     Command                         Swap      USS      PSS      RSS
29193 wwwrun   /usr/sbin/httpd-event -DSYS   208.0K   804.0K     1.3M     4.9M
29195 wwwrun   /usr/sbin/httpd-event -DSYS   208.0K     1.6M     2.8M    11.0M
29194 wwwrun   /usr/sbin/httpd-event -DSYS   208.0K     1.6M     2.8M    11.1M
29196 wwwrun   /usr/sbin/httpd-event -DSYS   208.0K     2.2M     3.4M    11.6M
29278 wwwrun   /usr/sbin/httpd-event -DSYS   208.0K     3.2M     4.4M    12.7M
29094 wwwrun   php-fpm: pool www             208.0K    25.3M    30.3M    47.1M
29306 wwwrun   php-fpm: pool www             208.0K    33.8M    38.4M    54.5M
29337 wwwrun   php-fpm: pool www             208.0K    35.6M    39.5M    54.0M

php-fpm のプロセスが増えましたが、Apache のプロセスのメモリー使用量はぐっと小さくなりました。Apache と php-fpm の初期プロセス数、最大プロセス数はこれから調整したいと思います。

今回は ncdu を紹介します。

ncdu は curces を使用した、ディスク使用量を表示するツールです。その名の通り、du の curces 版です。起動すると、カレントディレクトリの各サブディレクトリやファイルの大きさや使用量を表示します。

注目するディレクトリは、カーソルキーまたは jk キー(vi と同じ)で移動でき、ENTERキーで、そのディレクトリに入ることができます。また、名前順、日付順、項目の数順(おそらく、サブディレクトリ中の項目数)、mtime順に整列し直すこともできます。項目数については、c キーを入力することで表示することもできます。画面の左端には、そのディレクトリの状況(空白とか、読み取れないとか)が表示される場合があります。
起動時にディレクトリを指定することで、任意のディレクトリの状況を表示できます。また、? キーを押すとヘルプ画面が表示されます。

ヘルプにも書いてあるとおり、ncdu から直接ファイルを削除することもできます。ディレクトリを渡りながら、不要なファイルを削除するという作業が効率的に行えます。

du を使って一つずつ調べていくよりも、ncdu を使った方がはるかに効率的に作業ができるので、不要なファイルの掃除をする際には便利に使えそうです。常備しても良さそうです。

今回は ranger を紹介します。

ranger は、コンソール上で動作するファイラーです。日本語化はされていませんが、要所要所で動的にヘルプが出てくるため、それほど困ることはありません。コンソール上で動作するファイラーには mc が有名ですが、mc とは違い、標準で1つのディレクトリに注目するタイプです。
起動すると、このような画面が表示されます。

画面は、三つのペインからなり、左二つがディレクトリ、一番右が注目しているファイルの内容を表示します。テキストファイルであればほとんどのものが表示できます。UTF-8でエンコードされていれば、日本語も表示できます。また、バイナリファイルでも、一部の形式では、ファイルの情報を表示します。
真ん中のペインが今注目しているディレクトリです。ファイルやディレクトリの選択にはカーソルキーのほか、vi と同じ hjkl のキーが使えます。但し、vi のキー配置は、QWERTY 配列に特化しているので、 DVORAK 配列で使うとかなり使いにくいです。

また、複数の画面を管理出来ます。この機能は、タブ機能を使います。”g”の次に”n”を入力することで、タブが有効になり、複数のディレクトリ表示ができるようになります。TAB キーで画面を切り換えることもできますし、”~”キーで左右に表示させることもできます。たとえば、片方のディレクトリからもう片方のディレクトリにファイルをコピーする際には、スペースキーで対象のファイルやディレクトリを選択した後、vi 風のコマンド yy でコピーして、pp でペーストします。

ranger にはこのほかにも、ファイルの整列や検索、パーミッションの設定、シェルの実行など多数の機能があります。色々試してみても面白いと思います。

この記事は openSUSE Advent Calendar の6日目です。

通常、root になって、 poweroff コマンドを投入すると、システムはシャットダウン動作を行い、電源を落として停止します。しかし、第四世代 Intel CPU の場合、poweroff コマンドで一度電源断まで行ったのち、数秒後に再起動してしまいます。少なくとも手元の i3-4130T、i5-4200M ではこの現象が発生します。
これを解決するには、boot時、grub.cfg の中に、
linux /vmlinuz-........ xhci_hcd.quirks=0x2000

のように、パラメータを追加する必要があります。

第四世代 Intel CPU を使ったマシンは、今から7-8年くらい前のもので、少々古いマシンではありますが、使い方によってはまだまだ使えます。もしもなぜか再起動してしまうという現象にお悩みの場合には上記のパラメータを試してみてください。

この記事は小江戸らぐ 5月のオフな集まりの発表ネタです。

2回目の夏を迎えるに当たり、自宅ファイルサーバーの熱とファンの音が気になり、モニタリングしてみることにしてみました。今回は他の用途でも興味があった Grafana を使ってみました。Grafana は CPU 使用率やメモリ使用量といったハードウェアから、データベースやアプリケーションの性能といった様々なメトリクスを可視化・分析するための Web アプリケーションです。インタラクティブに操作できたり、かっこいい見た目だったりで、最近よく見かけます。

小江戸らぐ向け注記: よくカロスさんの発表に出てきます。K8s のクラスタやラズパイの環境センサーの表示で使っていますね。

Grafana Cloud

今回はちょっと横着して、Grafana の SaaS である Grafana Cloud を使いました。Grafana といえば、多くの場合、メトリクス収集と時系列データベース機能を持つ Prometheus と組み合わせ、これら2つをどこかにインストールして使います。Grafana Cloud では Grafana 本体と Prometheus のデータベース部分は Grafana Cloud で動いているものを使うことができます。データの収集は Prometheus からデータベース部分などを簡略化した Grafana Agent で収集できます。

気になるお値段ですが、Free プランがあります。メトリクスの保持期間は2週間というのがポイントになりますが、ちょっと試して見るには十分です。無料プランの主なスペックはこんな感じです:

  • 10,000 系列(種類)までの Prometheus または Graphite のメトリクス
  • 50 GB のログ
  • 14日間のメトリクスとログの保持期間
  • 3人までのチームメンバー

アカウントを作るためにクレジットカードなどの情報は特に必要ありません。 Grafana Cloud のページでアカウント作成に進み、GitHub などの SSO でログインすればすぐ準備完了です。

メトリクス収集

次に、メトリクスの収集を始めましょう。雷のアイコン(⚡) > Walk through をクリックすると、スクリーンショットのように Grafana Cloud がサポートしているプラットフォームのメトリクス収集を簡単にセットアップできるガイドが用意されています。今回は Linux Server を使用します。Prometheus では Node Exporter と呼ばれているものです。

Linux Server をクリックすると、セットアップするためのスクリプトが表示されます。「Choose your OS」には openSUSE が見当たりませんが、「RedHat – based」で OK です。Go言語で実装されたアプリなので、システムライブラリにほとんど依存していません。

あとは、その下に表示されたスクリプトを実行すれば OK です。Grafana Agent の RPM のインストールと設定ファイルの作成、起動まで一気に行われます。セットアップが終わると、最初から用意されているダッシュボードに収集した情報が表示されます。(datasource で grafanacloud-xxxx-prom を選択)

ダッシュボードの作成

もちろん、ダッシュボードを自分で組み立てることもできます。ここではパネルを配置し、Visualization を Time Series にして次を追加してみました。収集されているメトリクスの一覧がドロップダウンメニューに表示されるので、ここからそれっぽいものを選んで追加することができます。

  • node_cpu_scaling_frequency_hertz
  • instance:node_cpu_utilisation:rate1m
  • node_hwmon_temp_celsius

各系列のスタイルや、単位、Y軸の設定は、ちょっとわかりにくいですが Overrides タブで系列を選んで個別に設定できます。

このファイルサーバーは普段ほとんどアイドル状態なのですが、CPU クロックが思った以上に落ちていないことが分かりました。ファンコントロールのターゲット温度が45℃設定なのですが、55℃くらいをキープしているようです。

おわりに

Grafana Cloud を使って自宅ファイルサーバーの監視を簡単にしてみました。そして Grafana Agent が CPU 時間を他と比較して使ってしまっていますので、場合によっては収集する項目を減らすなどを考えたほうが良いかもしれません。

前回は T でしたが、今回は S です。

パッケージ名 scout
バージョン scout-0.2.4+20210325.6c2d9f3-1.1.noarch
動作 △
詳細
コマンドが見つからない場合、パッケージ内にあれば、そのパッケージを表示してくれるツールです。たとえば、

> scout bin sdl-config
 リポジトリ                            | パッケージ        | パス       | バイナリ
----------------------------------+--------------+----------+------------
 zypp (openSUSE-20210325-0)       | libSDL-devel | /usr/bin | sdl-config
 zypp (download.opensuse.org-oss) | libSDL-devel | /usr/bin | sdl-config

というような感じになります。
ただ、日本語で表示するとカラムがずれてしまうこと、マニュアルに書いた例題が、上記以外では動作しないこと(python のエラーになります)があるので、使えるかどうかは微妙なところです。

パッケージ名 sc
バージョン sc-7.16-13.26.x86_64
動作 ◯
詳細
コンソールで動くスプレッドシートです。但しちょっとくせがあります。文字はそのまま入力できず、必ずプレフィックスをつける必要があります。例えば、数字や数式を入力する際には、まず = キーを押してから、入力したい文字列を入れます。
文字列も入りますが、日本語文字列は、UTF-8環境では入りませんでした。
カーソル移動は矢印キーのほかに、h、j、k、l の vi 風キーバインドでも使えます。
関数は @sum とか @lookup とか、@logとか、最低限のものは揃っているようです。
sc は、大昔のPC を知っている人ならば、 VisiCalc だと思えば感覚が掴めるかと思います。

パッケージ名 socat
バージョン socat-1.7.4.1-1.4.x86_64
動作
詳細
種々のソケットによる通信を中継してくれるツールです。IPv6 にも対応し、種々のネットワークオプションや細かな制御のためのオプションも用意されています。
一番簡単な使い方としては、ファイアウォールの内側にあるサーバに対して、入口のサーバに socat を設定しておき、socat 経由で接続するというやり方でしょう。あるいは直接ルーティングされていないセグメントへの接続時にも使えます。
たとえば、192.168.x.0 のセグメントから、172.31.y.0 のセグメントにあるサーバを経由し、 172.16.z.0 のセグメントにあるマシンに繋ぐには以下のようにします(ここでは、daytime プロトコルを起動しておいてそこに繋ぎます)。

socat tcp4-listen:8089,reuseaddr,fork tcp:172.16.z.zz:13

結果はこうなります。

% telnet 172.31.y.yy  8089
Trying 172.31.y.yy...
Connected to susedev.
Escape character is '^]'.
28 APR 2021 18:00:15 JST
Connection closed by foreign host.

このようにすることで、2段階のログインをしなくとも172.16.z.0 のセグメントにあるマシンに接続することが出来ます。

小ネタ:transactional serverでbtrfs balance

By Syuta Hashimoto @ 2020-12-23 01:30

諸事情で、MicroOSのルートにbtrfsの機能でディスクを追加したのですが、balasceを実行しようとすると「read onlyだよ」と警告が。

ユーザ会slackに投げてみた所、武山さんから「transactional-update shellの中ならいけるのでは?」との助言を頂きました。

結論

成功

コマンド

transactional-update shell

transactional-updateそのもののアップデートが行われた後、独自のシェルに移行しました。

transactional update #

この状態で書き込み可能になります。書き込み後、シェルを抜けてrebootすれば反映されるしくみですね。

btrfs balance /

前後の状態を撮り損ねてしまったのですが、無事にbalanceされてました。

transactional-updateの真価はまだ味わえてないので、ロールバック等含め、近いうちにまとめて検証してみたいですね。

そもそも、transactional-update shellが一体何をどうしているのかも追えていない・・・