作業メモ: AWS EC2でEBSにswapファイルを追加する【systemd】

あらすじ: oom-killer先生が仕事しててヤバい

WordPressを動作させているEC2インスタンスで、なんとなくjournalctlを眺めたらヤバいログが出てた。グワーッ

Aug 28 09:22:46 ip-172-30-1-97 kernel: Out of memory: Kill process 13584 (apache2) score 122 or sacrifice child
Aug 28 09:22:46 ip-172-30-1-97 kernel: Killed process 13584 (apache2) total-vm:483384kB, anon-rss:22536kB, file-rss:35624kB
Aug 28 09:22:47 ip-172-30-1-97 kernel: apache2 invoked oom-killer: gfp_mask=0x2420848, order=0, oom_score_adj=0

現代のAWS EC2ではswapをEBS上に作る

メモリが足りないようだけど、概ね動いてるわけだからインスタンスサイズを大きくするのはケチりたい→インスタンスストア(Ephemeral Disk)にswapファイルを作ろう→そういえばインスタンスストアが無いな、AMI変えるか→なんかルートデバイスEBSのAMIしかないぞ→じゃあインスタンス作成時にストレージ追加するか→インスタンスストアを選択できないぞ!(EBSしか無い)

EBSでswapファイルを作るとI/Oが大量に発生するからめっちゃ課金されるじゃん。どうすんだよ、みんなswapなしでメモリが大量にあるインスタンスだけ使ってるブルジョアなのかよ。と思ってたら、今のEBSはI/O回数ではなくIOPSで追加料金を決める料金体系になってたんですね…なんかすいません…ってなりました。今や過去の遺物となった、MagneticなEBSだけなんですね、I/O回数で追加課金されるのは。

誰か教えといてよー、ってなったので自分で書いておきました。

swap追加手順

「AWS EC2でswapファイルを追加する」というタイトルにしましたが、特別なことはありません。systemdを使うLinuxならだいたい同じ方法でやれると思います。今回、実際に使ったのはUbuntu Server 16.04です。

システムのメモリの現状を確認する

swap無いですよね、というのを確認する。t3.nanoインスタンスなのでメモリは0.5GBで切ない。

$ free
              total        used        free      shared  buff/cache   available
Mem:         477660      314648       17396       44784      145616       83444
Swap:             0           0           0

systemdから起動されるサービスでswapを追加する

もはやrc.localとかの時代ではないと思うので、こんな感じのserviceファイルを作ります。以前にCoreOSでswapを作る設定をした時のやつをコピーして、コマンドのパスとかを直しました。

$ cat swap.service
[Unit]
Description=Turn on swap

[Service]
Type=oneshot
Environment="SWAP_PATH=/var/vm" "SWAP_FILE=swapfile1"
ExecStartPre=-/bin/rm -rf ${SWAP_PATH}
ExecStartPre=/bin/mkdir -p ${SWAP_PATH}
ExecStartPre=/usr/bin/touch ${SWAP_PATH}/${SWAP_FILE}
ExecStartPre=/bin/bash -c "fallocate -l 2048m ${SWAP_PATH}/${SWAP_FILE}"
ExecStartPre=/bin/chmod 600 ${SWAP_PATH}/${SWAP_FILE}
ExecStartPre=/sbin/mkswap ${SWAP_PATH}/${SWAP_FILE}
ExecStartPre=/sbin/sysctl vm.swappiness=10
ExecStart=/sbin/swapon ${SWAP_PATH}/${SWAP_FILE}
ExecStop=/sbin/swapoff ${SWAP_PATH}/${SWAP_FILE}
ExecStopPost=-/bin/rm -rf ${SWAP_PATH}
RemainAfterExit=true

[Install]
WantedBy=multi-user.target

これをsystemdさんに読み込んでもらい、サービスを有効にして起動します。失敗したら修正してやり直す。

$ sudo cp swap.service /etc/systemd/system/
$ sudo systemctl daemon-reload
$ sudo systemctl enable swap
Created symlink from /etc/systemd/system/multi-user.target.wants/swap.service to /etc/systemd/system/swap.service.
$ sudo systemctl start swap

swapが追加されたか確認する

free叩いて確認。めでたしめでたし。

$ free
              total        used        free      shared  buff/cache   available
Mem:         477660      309412       18268       40640      149980       92816
Swap:       2097148       15284     2081864

systemctl enableしてあるので、OS再起動してもまた有効になります。状況が許せばそれも確認しておきましょう。