No RebootでAMIを作成したらファイルが消えたりしたので原因を調査した。
AWS公式では以下のように言われているのだけど、なぜ整合性を保証できないのかがわかった。
[No reboot] を選択した場合、Amazon では作成されたイメージのファイルシステムの整合性を保証できません。
発生した現象
端的に言えばNo RebootでのAMI作成直前に配置していたファイルがAMIに含まれない、もしくはファイルサイズ0であるという現象が発生した。
環境
- Amazon Linux AMI 2014.09 (PV)
現象1
- capistranoでEC2にリリースする
- すぐにNo RebootでAMI作成
- 作成されたAMIからEC2作成
- EC2で配置されたファイルの大部分が0バイト
現象2
- 以下のようなスクリプトを実施
#!/bin/sh
TARGET_DIR=`date '+/home/ec2-user/hoge%Y%m%d%H%M%S'`
mkdir $TARGET_DIR
cd [git clone --mirrorした適当なリポジトリのパス] && git archive master | tar -x -C $TARGET_DIR
aws ec2 create-image --region `curl --silent "http://169.254.169.254/latest/meta-data/placement/availability-zone" | sed 's/.$//'` --instance-id `curl http://169.254.169.254/latest/meta-data/instance-id --silent` --name `date '+test-%Y%m%d-%H%M%S'` --no-reboot
- 作成されたAMIからEC2作成
- EC2で作成されたはずのディレクトリが存在しない
調査したこと
cloud-initは無罪だった
Amazon EC2(Linux)システム管理で知らないとハマる5つの環境設定 | Developers.IO
にあるように、EC2インスタンスをコピーすると意図しない環境設定に変わってしまうという問題があるので最初はこれを疑った。
この中でファイルに関わりそうなのがパッケージアップデート。
でも、パッケージアップデートしないようにしてみても現象変わらずでcloud-initは関係ないみたいだった。
Amazon Linuxのファイルシステムを調べてみた
Amazon Linuxの現在のファイルシステムはext4。
ext4では遅延アロケーション機能というものがあるらしい。
Linuxのファイルシステムext4の特徴|もと東大生もと社長の自由奔放ブログ Just do it now!
によると遅延アロケーションとは、以下のような機能らしい。
遅延アロケーションは、通常のファイルシステムでは、書き込みの命令の時点で
ディスクの確保を行いますが、これを実際に書き込まれるギリギリまで遅らせるというもの。
ext3からext4への更新概要なんかもわかりやすい。
EXT4のゼロレングス問題(zero-length problem)に対処したマウントを行う - ktomoyaの日記
のようにファイルサイズが0になってしまう問題もあるようである。
002f5e43_linux_io_subsystem_v1_2.pdf
によると以下のようにあり、デフォルトではディスクに書き出されるまで最大35secくらいかかる場合があるらしい。
従って、デフォルトでは、書き込まれてから30sec以上経過したキャッシュページは、5sec以内に物理デバイスに書き出されることになります。
(ただし、書き出すページが多く、kw_kupdateによる書き出し処理に時間がかかる場合は、れよりも遅くなることはあります。)
実際に遅延アロケーションを確認してみる
以下のようにディスクに書き出されていないDirtyページのサイズを監視しておく(一応スワップデバイスに書き出し中のページも見ている)。
$ watch -n 1 sudo grep -E "Dirty\|Writeback" /proc/meminfo
別端末で以下を実行しbo(ブロックデバイスへの書き込み量)の値に注目しておく。
$ vmstat -1
さらに別端末で以下を実行すると、書き出されるファイル全体のサイズあたりの数値がDirtyとして表示される。
さらにしばらくするとDirtyページがなくなる(Writebackの値は書き込みが一瞬なせいか変わらない)。
同時にvmstatでboの値が一気に増える。
cd [git clone --mirrorした適当なリポジトリのパス] && git archive master | tar -x -C [適当なディレクトリ]
まとめ
原因
ext4に限らずファイルシステムでは高速化などのため書き込みの際にディスクへの書き出しまでタイムラグがある可能性がある。
ディスクの書き出しまでにスナップショットがとられてしまうとファイルシステムの整合性が保たれない。
対策
以下のようなことで対策できそう。
- ディスクに書き出される時間まで十分まってからNo RebootでAMIをとる
- 確実性はないがクリティカルな変更がディスクに反映されるまで待つ。
- XFSなどの書き込みを一次停止出来るファイルシステムを利用する
- 8.6. XFS ファイルシステムの一時停止のように停止できるらしい。
- No Rebootを利用しない。
- Rebootして確実にディスクに書き出されるようにする。