本日も乙

ただの自己満足な備忘録。

EC2のEphemeral DiskにSwap領域を作成or拡張する

AWSのEC2インスタンスを使う上で最も不便を感じている点の1つとしてSwap領域が無いことだと思います(個人的観点)。 m1.smallとc1.mediumの場合のみデフォルトでSwap領域が追加されていますが、実運用においてもっと大きいインスタンスタイプを使う場合が多いでしょう。

そこで今回はEC2インスタンスにSwap領域を追加する方法を紹介します。 Swap領域として使用するディスクは、インスタンスストア(Ephemeral Disk)を使用します。その理由は以下の3点です。

  1. ルートデバイスとしてマウントされているEBSボリュームに影響を及ぼさない
  2. 揮発性(EC2を停止するとデータが削除される)ため、用途として向いている
  3. M3, C3タイプなどはSSDなので読み書きが高速

Swap領域の作成には、パーティションを使用する場合とファイルを使用する場合の2つがありますので、両方とも紹介します。 一般的にはスワップパーティションの方が高速ですが、拡張のしやすさやインスタンスストアが無いEC2インスタンスでもSwap領域が確保できる点でファイル・スワップもメリットがあります。

また、Swap領域が足りなくなった場合に拡張する方法も紹介します。 本来なら、Swap領域を常に使うような状態になったらメモリを多く積んでるインスタンスタイプに変更すべきですが、一時的対処したい場合に拡張することもあるかと思います。

環境

EC2インスタンスを起動する場合は、予めインスタンスストアを追加した状態で起動してください。

ec2 instance store

初期状態

$ lsblk
NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
xvda    202:0    0    8G  0 disk
└─xvda1 202:1    0    8G  0 part /
xvdb    202:16   0 15.3G  0 disk /media/ephemeral0
xvdc    202:32   0 15.3G  0 disk


$ sudo fdisk -l
WARNING: fdisk GPT support is currently new, and therefore in an experimental phase. Use at your own discretion.

Disk /dev/xvda: 8589 MB, 8589934592 bytes, 16777216 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: gpt


#         Start          End    Size  Type            Name
 1         4096     16777182      8G  Linux filesyste Linux
128         2048         4095      1M  BIOS boot parti BIOS Boot Partition

Disk /dev/xvdb: 16.4 GB, 16380329984 bytes, 31992832 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト


Disk /dev/xvdc: 16.4 GB, 16380329984 bytes, 31992832 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
$ free
             total       used       free     shared    buffers     cached
Mem:       3858732     704216    3154516         72      18360     588680
-/+ buffers/cache:      97176    3761556
Swap:            0          0          0

パーティションを使用する場合

すでにインスタンスストアがマウントされている場合はアンマウントしておきます。

$ sudo umount /media/ephemeral0/

$ lsblk
NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
xvda    202:0    0    8G  0 disk
└─xvda1 202:1    0    8G  0 part /
xvdb    202:16   0 15.3G  0 disk
xvdc    202:32   0 15.3G  0 disk

fdiskコマンドでパーティションを作成します。

$ sudo fdisk /dev/xvdb
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


コマンド (m でヘルプ): p

Disk /dev/xvdb: 16.4 GB, 16380329984 bytes, 31992832 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0xad731616

デバイス ブート      始点        終点     ブロック   Id  システム

最初の設定を見ると、まだパーティションが作成されていない状態です。 Swap領域用のパーティションを作成します。サイズはメモリとほぼ同サイズの4GBにします。

コマンド (m でヘルプ): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
パーティション番号 (1-4, default 1): 1
最初 sector (2048-31992831, 初期値 2048):
初期値 2048 を使います
Last sector, +sectors or +size{K,M,G} (2048-31992831, 初期値 31992831): +4G
Partition 1 of type Linux and of size 4 GiB is set

コマンド (m でヘルプ): t
Selected partition 1
Hex code (type L to list all codes): 82
Changed type of partition 'Linux' to 'Linux swap / Solaris'

コマンド (m でヘルプ): p

Disk /dev/xvdb: 16.4 GB, 16380329984 bytes, 31992832 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0xad731616

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/xvdb1            2048     8390655     4194304   82  Linux swap / Solaris

保存して終了します。

コマンド (m でヘルプ): w
パーティションテーブルは変更されました!

ioctl() を呼び出してパーティションテーブルを再読込みします。

WARNING: Re-reading the partition table failed with error 0: 成功です.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
ディスクを同期しています。

パーティション(/dev/xvdb1)が作成されればOKです。

$ lsblk
NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
xvda    202:0    0    8G  0 disk
└─xvda1 202:1    0    8G  0 part /
xvdb    202:16   0 15.3G  0 disk
└─xvdb1 202:17   0    4G  0 part
xvdc    202:32   0 15.3G  0 disk

$ ls /dev/xvd*
/dev/xvda  /dev/xvda1  /dev/xvdb  /dev/xvdb1  /dev/xvdc

Swap領域を有効化させます。

$ sudo mkswap /dev/xvdb1
スワップ空間バージョン1を設定します、サイズ = 4194300 KiB
ラベルはありません, UUID=e12331b5-c851-437f-824e-e7e389121819
$ sudo swapon /dev/xvdb1

freeコマンドなどでSwapが表示されれば完了です。

$ free
             total       used       free     shared    buffers     cached
Mem:       3858732     708308    3150424         76      18740     589172
-/+ buffers/cache:     100396    3758336
Swap:      4194300          0    4194300

$ swapon -s
Filename                                Type            Size    Used    Priority
/dev/xvdb1                              partition       4194300 0       -1

$ lsblk
NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
xvda    202:0    0    8G  0 disk
└─xvda1 202:1    0    8G  0 part /
xvdb    202:16   0 15.3G  0 disk
└─xvdb1 202:17   0    4G  0 part [SWAP]
xvdc    202:32   0 15.3G  0 disk

再起動後もSwap領域がマウントされるように/etc/fstabを編集します。

# /etc/fstab
#
LABEL=/     /           ext4    defaults,noatime  1   1
tmpfs       /dev/shm    tmpfs   defaults        0   0
devpts      /dev/pts    devpts  gid=5,mode=620  0   0
sysfs       /sys        sysfs   defaults        0   0
proc        /proc       proc    defaults        0   0
#/dev/xvdb      /media/ephemeral0       auto    defaults,nofail,comment=cloudconfig     0       2
/dev/xvdb1  swap        swap    defaults        0   0

Swap領域を拡張する場合

さきほど4G程度のSwap領域を作成しましたが、Swapが足りなくなって拡張したい場合の方法を紹介します。

$ sudo fdisk /dev/xvdb
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


コマンド (m でヘルプ): p

Disk /dev/xvdb: 16.4 GB, 16380329984 bytes, 31992832 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0xad731616

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/xvdb1            2048     8390655     4194304   82  Linux swap / Solaris

すでに4G程度のSwap用のパーティションが追加されている状態です。 新たにSwap用のパーティション(番号:2)を追加します。サイズは4Gにしました。

コマンド (m でヘルプ): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): p
パーティション番号 (2-4, default 2): 2
最初 sector (8390656-31992831, 初期値 8390656):
初期値 8390656 を使います
Last sector, +sectors or +size{K,M,G} (8390656-31992831, 初期値 31992831): +4G
Partition 2 of type Linux and of size 4 GiB is set

コマンド (m でヘルプ): t
パーティション番号 (1,2, default 2): 2
Hex code (type L to list all codes): 82
Changed type of partition 'Linux' to 'Linux swap / Solaris'

コマンド (m でヘルプ): p

Disk /dev/xvdb: 16.4 GB, 16380329984 bytes, 31992832 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0xad731616

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/xvdb1            2048     8390655     4194304   82  Linux swap / Solaris
/dev/xvdb2         8390656    16779263     4194304   82  Linux swap / Solaris

保存しようとすると、すでに使われているためビジー状態となっています。

コマンド (m でヘルプ): w
パーティションテーブルは変更されました!

ioctl() を呼び出してパーティションテーブルを再読込みします。

WARNING: Re-reading the partition table failed with error 16: デバイスもしくはリソースがビジー状態です.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
ディスクを同期しています。

再起動する手もありますが、稼働中のシステムだと再起動できない場合が多いので、今回はpartxコマンドで強制的にパーティションテーブルを更新させます。

$ sudo partx -a /dev/xvdb
partx: /dev/xvdb: error adding partition 1

$ ls /dev/xvdb*
/dev/xvdb  /dev/xvdb1  /dev/xvdb2

/dev/xvdb2が追加されているのを確認できたらSwap領域を有効化させます。

$ sudo mkswap /dev/xvdb2
スワップ空間バージョン1を設定します、サイズ = 4194300 KiB
ラベルはありません, UUID=2b9c221f-591a-4826-b506-e72077d33ab6
$ sudo swapon /dev/xvdb2

# 確認
$ free
             total       used       free     shared    buffers     cached
Mem:       3858732     149316    3709416         80       8472      67424
-/+ buffers/cache:      73420    3785312
Swap:      8388600          0    8388600

Swap領域が増えていれるのが確認できます。 最後に/etc/fstabに追記して永続化しておきます。

# /etc/fstab
#
LABEL=/     /           ext4    defaults,noatime  1   1
tmpfs       /dev/shm    tmpfs   defaults        0   0
devpts      /dev/pts    devpts  gid=5,mode=620  0   0
sysfs       /sys        sysfs   defaults        0   0
proc        /proc       proc    defaults        0   0
#/dev/xvdb      /media/ephemeral0       auto    defaults,nofail,comment=cloudconfig     0       2
/dev/xvdb1  swap        swap    defaults        0   0
/dev/xvdb2  swap        swap    defaults        0   0

ファイルを使用する場合

初期状態に戻しておきます。

$ df
ファイルシス   1K-blocks    使用   使用可 使用% マウント位置
/dev/xvda1       8123812 1113820  6909744   14% /
devtmpfs         1920168      68  1920100    1% /dev
tmpfs            1929364       0  1929364    0% /dev/shm
/dev/xvdb       15613852   39196 14774836    1% /media/ephemeral0

ddコマンドでSwap領域用ファイル(4G)を作成します。

$ sudo dd if=/dev/zero of=/media/ephemeral0/swapfile bs=1M count=4096
4096+0 レコード入力
4096+0 レコード出力
4294967296 バイト (4.3 GB) コピーされました、 19.9231 秒、 216 MB/秒

Swap領域を有効化させます。

$ sudo mkswap /media/ephemeral0/swapfile
スワップ空間バージョン1を設定します、サイズ = 4194300 KiB
ラベルはありません, UUID=7d9bb073-5ea9-461e-a5f3-e68bc3ed98f8
$ sudo swapon /media/ephemeral0/swapfile
swapon: /media/ephemeral0/swapfile: 安全でない権限 0644 を持ちます。 0600 がお勧めです。
$ sudo chmod 600 /media/ephemeral0/swapfile

# 確認
$ free
             total       used       free     shared    buffers     cached
Mem:       3858732    3749756     108976         72      13088    3565612
-/+ buffers/cache:     171056    3687676
Swap:      4194300          0    4194300

Swap領域ができているのが確認できます。

/etc/fstabを編集してSwap領域を永続化させます。

# /etc/fstab
#
LABEL=/     /           ext4    defaults,noatime  1   1
tmpfs       /dev/shm    tmpfs   defaults        0   0
devpts      /dev/pts    devpts  gid=5,mode=620  0   0
sysfs       /sys        sysfs   defaults        0   0
proc        /proc       proc    defaults        0   0
/dev/xvdb       /media/ephemeral0       auto    defaults,nofail,comment=cloudconfig     0       2
/media/ephemeral0/swapfile  swap   swap    defaults   0 0

Swap領域を拡張する場合

新しくSwap用ファイル(/media/ephemeral0/swapfile1)を追加して有効化させれば良いです。

$ sudo dd if=/dev/zero of=/media/ephemeral0/swapfile1 bs=1M count=4096
4096+0 レコード入力
4096+0 レコード出力
4294967296 バイト (4.3 GB) コピーされました、 17.343 秒、 248 MB/秒
$ sudo mkswap /media/ephemeral0/swapfile1
スワップ空間バージョン1を設定します、サイズ = 4194300 KiB
ラベルはありません, UUID=eb113bba-cade-4e42-b97d-a449a0eab1e2
$ sudo swapon /media/ephemeral0/swapfile1
swapon: /media/ephemeral0/swapfile1: 安全でない権限 0644 を持ちます。 0600 がお勧めです。
$ sudo chmod 600 /media/ephemeral0/swapfile1

# 確認
$ free
             total       used       free     shared    buffers     cached
Mem:       3858732    3776992      81740         72      17148    3585632
-/+ buffers/cache:     174212    3684520
Swap:      8388600          0    8388600

/etc/fstabに追記して永続化するのも忘れずに行います。

# /etc/fstab
#
LABEL=/     /           ext4    defaults,noatime  1   1
tmpfs       /dev/shm    tmpfs   defaults        0   0
devpts      /dev/pts    devpts  gid=5,mode=620  0   0
sysfs       /sys        sysfs   defaults        0   0
proc        /proc       proc    defaults        0   0
/dev/xvdb       /media/ephemeral0       auto    defaults,nofail,comment=cloudconfig     0       2
/media/ephemeral0/swapfile  swap   swap    defaults   0 0
/media/ephemeral0/swapfile1  swap   swap    defaults   0 0