2022/06/17(金)OOM Killerでサーバが死んだ

ある日突然、Webサーバ(Apache)が死亡したときのメモと、実施した対策のまとめ。

OOM Killerとは

メモリが足りなくなったときに、負荷が高そうなプロセスを一撃必殺してくれるLinuxの機能です。

ログ

長いので別ファイルに

この中で、rssが実消費メモリ(KB)なのですが、トータルしても209MBしかありません。ps auxの値(KB)と異なり、OOM Killerプロセス一覧数値はすべてページ単位(4kB単位)なので、836MB。このマシンの実メモリ1GBなのでほとんど無くなっています。

スワップもswapents(Anonymous swap entries)の合計が960589、エントリー1つあたり4KBですので、3.7GB。つまりスワップは完全に食いつぶしてる。

色々調べると、OOM発動時はこの辺を見ると良いらしい。

[7934037.757829] Node 0 DMA: 43*4kB (UME) 14*8kB (UME) 12*16kB (UE) 13*32kB (UME) 2*64kB (UE) 7*128kB (UME) 4*256kB (UME) 3*512kB (UME) 0*1024kB 0*2048kB 0*4096kB = 4476kB
[7934037.762116] Node 0 DMA32: 258*4kB (UME) 252*8kB (UME) 576*16kB (UME) 325*32kB (UME) 105*64kB (UME) 20*128kB (UME) 8*256kB (UE) 3*512kB (UME) 5*1024kB (UME) 0*2048kB 1*4096kB (M) = 44744kB

どれくらいのサイズの連続したメモリをいくつ確保できるかという表示ですが、一番大きいもので「DMA側が512kBを3つ」「DMA32側が4096kBを1つ」ということで、メモリの断片化してますし、そもそも両方合わせて48MBぐらいしか空きメモリがない。

OOM Killerが発生して当然の状況と言えます。

なぜApacheが死んだのか

OOM Killerが発動したのは、sys.fcgiというFastCGI(Apacheの子)プロセスなのですが、なぜかApache自体が死亡しておりました。daemon.logを見ますと、こんな感じ。

systemd[1]: apache2.service: A process of this unit has been killed by the OOM killer.
systemd[1]: apache2.service: Failed with result 'oom-kill'.
systemd[1]: apache2.service: Consumed 1h 21min 18.835s CPU time.

Apacheの子プロセスがOOM Killerされたので、systemdが善きに計らってApache自体を終了させた模様。……やめてくれー(苦笑)

子プロセスが死んでもApacheを生かす

メモリ食いつぶしcgiを作って実験してみたのですが、通常のcgiなら問題なくFastCGIのときだけこの問題が起きるようです。systemdの設定を変更して、Apacheを巻き添えにしないよう変更します。

# Debianの場合, rootでの作業
cd /etc/systemd/system
mkdir apache2.service.d
vi apache2.service.d/oom.conf
systemctl daemon-reload

# oom.confの中身
[Service]
OOMPolicy=continue

/etc/system/systemd/apache2.service.d/oom.conf がきちんと読み込まれてるか、設定を確認してください。

systemctl cat apache2

この状態でメモリ食いつぶしfcgiを実行してみましたが、無事(?)にfcgiだけプロセスkillされました。

その他の対策

  • Swap領域を3.7GBから10GBに増強。
  • sys.fcgiで不要になったメモリを開放することが難しかったので、メモリ使用量(/proc/[pid]/statusのVmHWM)が一定量を超えたら、処理終了後に自動でプロセスを終了するようにした。
  • mod_fcgidの設定を変更して、一定時間使われないプロセスはすべて終了するようにした。
    FcgidMinProcessesPerClass	0
    FcgidProcessLifeTime		600
    FcgidIdleScanInterval		120
    

スワップは実RAMの倍(この場合2GB)という定説を昔読んだ気がしますが、「未開放メモリ→スワップアウト」というケースを考えると、多いに越したことはないかもしれません。

本当はApache側でメモリ制限を実施できたら楽なのですが、mod_fcgidの子プロセスには RLimitMem とか効かないんですよね……。

参考サイト

2022/05/20(金)Dell S150 に Software RAID で Ubuntu 22.04 をインストール

Dell PowerEdgeサーバに乗っているなんちゃってRAIDコントーラーS150を使用した状態で、Ubuntu Desktop 22.04をインストールしたメモ。

S150とは

よくあるBIOSでRAID化するだけの、実質ソフトウェアRAIDです。S150はLinuxのRAIDに対応しており、BIOSからLinuxで作成したRAID情報を参照できるようです。

つまりRAID化した状態でLinuxをインストールすることができれば、そのRAID化されたディスクから起動することも可能です。

Ubuntu Desktop 22.04のインストール

ミラーリング(RAID1)に設定する場合。

  1. BIOSの設定からSATAのモードを「AHCI」から「RAID」に切り替えます。
  2. Ubuntu Desktop 22.04をインストールイメージから起動します。
  3. インストールではなく「Ubuntuを試用する」を選択します。
  4. Terminalを開き、mdadmをインストールします。
    sudo apt-get install mdadm
    
  5. ディスク全体でRAIDを構築します。
    sudo mdadm --create md0 --level=1 --raid-disk=2 /dev/sda /dev/sdb
    
    /dev/md127 として認識されます。
  6. この状態で、Ubuntuをインストールします。インストール先はディスク全体を削除してインストール(自動選択でmd127)です。md127に2つのパーティションが作られます。
  7. 「grub-install /dev/sda の実行に失敗しました」というメッセージが出たら再起動せずにウィンドウを閉じます。
  8. /targetにRAIDディスクの/(md127p2)がマウントされていますので、ターミナルで以下の操作をします。
    sudo su
    cd /target
    mount --bind /dev dev
    mount --bind /sys sys
    mount --bind /proc proc
    cp /etc/resolve.conf etc/
    chroot .
    mount /boot/efi
    apt install mdadm
    grub-install
    
    これにより /boot/efi に必要なファイルが配置されますが、EFIブートメニューへの登録には失敗します。
  9. EFIブートメニューに項目を登録します。
    efibootmgr -c -d /dev/md127 -p 1 -L "ubuntu" -l '\EFI\ubuntu\shimx64.efi'
    

あとはターミナルを抜けて普通に再起動すれば、RAID状態のディスクからUbuntuが起動します。

メモ

# EFIメニュー登録状態の確認
efibootmgr -v
# EFIメニューの項目削除
efibootmgr -B -b 0001
# Software RAIDの状態確認
cat /proc/mdstat
# /etc/defult/grub
GRUB_RECORDFAIL_TIMEOUT=3
GRUB_DISABLE_SUBMENU=y

カーネルだけ更新

v5.17.9の場合。

wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.17.9/amd64/linux-headers-5.17.9-051709-generic_5.17.9-051709.202205180947_amd64.deb
wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.17.9/amd64/linux-headers-5.17.9-051709_5.17.9-051709.202205180947_all.deb
wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.17.9/amd64/linux-image-unsigned-5.17.9-051709-generic_5.17.9-051709.202205180947_amd64.deb
wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.17.9/amd64/linux-modules-5.17.9-051709-generic_5.17.9-051709.202205180947_amd64.deb
wget https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.17.9/amd64/linux-modules-iwlwifi-5.17.9-051709-generic_5.17.9-051709.202205180947_amd64.deb

dpgk -i *.deb

2022/03/09(水)OpenWrtでIPv6とDS-LiteとPPPoEを全部使う

OpenWrtを設定&構築したメモ。DS-LiteではなくMAP-Eでも参考になるかと思います。

※Linuxおよびネットワークの知識がない方はOpenWrtには手を出さないでください。

ことの発端

家庭内ルーターとして「NEC Atermシリーズ」を使っていたのですが、性能は申し分ないものの問題点があります。

  • 最新機種でもDS-Lite使用時PPPoEをパススルーできない*1
  • そのせいで、PPPoEとDS-Liteの併用ができない。*2
  • LAN内にDNSサーバを立てるとルータのDNSマスカレード機能が不安定になる。

WG1200HSはDS-Lite非対応なので、PPPoEと併用可能なら新しいのに買い替えてもよかったのですが、こんな状況ではAtermが選択肢に入らない。かといってBuffaloは安定性に問題ありそうなので、いっそのことOpenWrtルーターすればよいのでは? と。

*1 : DS-Lite以外ほぼすべての設定でパススルー可能であるのに、DS-Liteだけは絶対に許可しないという謎仕様を貫き通すNEC。

*2 : PPPoEをメインにしてLAN内のLinux等でDS-Liteを構築することは可能ですが、それは求めていない。

構築目標

openwrt-network.png

  • PPPoEとDS-Liteを併用する
  • LAN内の一部のマシンのみPPPoE側を使用する。

前提条件

  • ルーターのWAN側にはONU(光回線終端装置)が接続されている。
  • IPv6オプション(IPv6ネイティブ通信)が利用可能になっている。
  • DS-Lite(or MAP-E等)が使える状況になっている。
  • PPPoEが使える状況になっている(プロバイダ側で併用が許可されている)。

続きを読む

2021/08/24(火)OPA1622のGNDの扱いと音質比較

Ti製のSoundPlus高性能オーディオ・オペアンプ「OPA1622」のGNDをどこに接続するか問題について。

OPA1622とは

高性能オーディオ用ICであり、音質も大変優れていることから人気のオペアンプです。SoundPlusシリーズの中でも最高の「Ultimate」を冠しています。

このICは「100mA以上の電流」を取り出せ、ヘッドホンなどを直接駆動することも可能です。もっぱら「いわゆる載せ替えオペアンプ」として人気のようですが、このICは10pin DFNとして提供されており、通常の方法ではオペアンプとして載せ替え使用することはできません。

またこのオペアンプには±電源ピンの他に、GNDピンがありこのピンの処理方法について多少の議論があるようです。

OPA1622のGND処理と音質比較

GND端子の接続方法は3つ考えられます。

  1. V-(マイナス電源)につなぐ(秋月変換基板ほか)
  2. 変換基板上で仮想GNDにつなぐ(Bispa変換基板)
  3. 8pinオペアンプ互換を諦めGNDに直接接続する(Bispa変換基板では可能)

仮想GNDの回路はこんな感じです。*1

OPA1622_VG.png

比較結果

(3)GND接続 > (1)Vee接続 > (2)仮想GND回路付

ある種、当たり前の結果になりました。

*1 : Bispaの基板では10KΩではなく22KΩが使われているようです。

GNDはどこに接続するべきか?

データシートには次のような記述があります。

OPA1622-GND.png

【赤下線】GNDピンはノイズが最小でインピーダンスが最も低い基準に接続しろ

ノイズが少なくインピーダンスが低い基準点というのは、通常はGNDになりますが*2、GNDに接続できない状況でしたら次点でマイナス電源に接続するのは決して悪いことではありません。*3

上に示した仮想GND回路は、電源ピン(V-)に直接接続するよりインピーダンスが高いので、音が悪くなるのは当たり前です。

*2 : 回路全体が仮想GNDで動作している場合は除く。

*3 : 似たようなものだからとプラス電源に接続すると動作しなくなるのでご注意。

一番良い方法は何?

「なんだ仮想GND基板ク○じゃん」という結論は、実はちょっと焦りすぎです。

OPA1622.jpg

左が仮想GND付き変換基板(R/C裏面実装)で、右がGND-Vee接続変換基板です。GND-Vee接続基板は、上ではCを載せずに評価しました。ここには0.1uFのECPUを電源パスコンとして接続することができます。

仮想GND付基板は、GNDを接続するためのPAD(旧Bispa変換基板ならばホール)があります。仮想GND付き基板はGNDを正しく接続すると基板中のC1/C2が電源パスコンとして作用します

その結果こうなります。

C付き仮想GND基板のGNDを接続 > C付きGND-Vee接続基板 > GND接続 > その他

まとめ

  • 仮想GND付き変換基板をそのまま使うのは愚行。
  • GND-Vee接続のオペアンプ変換基板は、電源パスコン付きのほうが音が良い。
  • 仮想GND付き変換基板は、Cを付けた状態でGND端子を回路中のGNDに接続する。
    • Rはあってもなくてもどちらでも良い。

おまけ

実験に使った基板はBispaで販売されているものです。

2019/10/19(土)JNBのカード型トークンを分解してみる

ジャパンネットバンク銀行(PayPay銀行)が発行しているカード型トークン(セキュリティキー)を分解してみました。

jnb-token_01.jpg

ネットバンクの操作に必要なワンタイムパスワードを表示する機械で、今では一般的になりましたけど、JNBが最初だったんんじゃないかな。他行では乱数表が一般的だったと思います。

厚さなんと0.8mm。上にシート(約0.15mm)がついているのでこれを慎重に剥がします。

jnb-token_02.jpg

結構しっかりと融着されているので剥がすのは大変です。個体によるのかもしれませんが、特に左上(「電池」の赤字があるところ)は強固に融着されていました。剥がしたあとの厚みはたったの0.65mm。このサイズに回路が入っていて、しかも10年持つというのは驚きです。

余談

分解したものは壊れたトークンです。壊れた場合、電話しなくてもWebから再発行を依頼できたらしい。カードに電話番号しか書いてないので、電話必須だと思ってしまった……。

jnb-token-web.png

ちなみに故障の症状は以下のものでした。参考にしてください。

  • ONにした瞬間「EEEEEE」表示がされ、その後数字が出る。
  • 1分以上経ってもその数字が消えない。
  • 何度ON/OFFしてもその数字が変わらない。

関連記事