ECS内で動くDockerコンテナが利用できる容量を増やす

ECSを使ってサーバーサイドの処理をしている時に、容量不足でしっかりデータ処理ができなくなることがあった。
その時とった対策をナレッジ共有として記事にする。


tt2.smallのECSインスタンスでECSクラスターを作成した場合のディスクサイズとブロックデバイス等

```
[root@ip-123-24-1-108 ec2-user]# df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
devtmpfs         988M   84K  988M    1% /dev
tmpfs            997M     0  997M    0% /dev/shm
/dev/xvda1       7.8G  780M  6.9G   10% /
/dev/dm-3        9.8G   52M  9.2G    1% /var/lib/docker/devicemapper/mnt/7fc53535f551d54f33265136b12b8f6e461ec252ebd89de5a929721d6d1cd92f
shm               64M     0   64M    0% /var/lib/docker/containers/7ddf22ce2a14789d1f1cae642fec6a38aa961f943582206df1ecf937edb5c427/mounts/shm

[root@ip-123-24-1-108 ec2-user]# lvs
  LV          VG     Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  docker-pool docker twi-aot--- 21.73g             1.58   0.70

[root@ip-123-24-1-108 ec2-user]# vgs
  VG     #PV #LV #SN Attr   VSize  VFree
  docker   1   1   0 wz--n- 22.00g 228.00m

[root@ip-123-24-1-108 ec2-user]# lsblk
NAME                                                                                         MAJ:MIN   RM  SIZE RO TYPE MOUNTPOINT
xvda                                                                                         202:0      0    8G  0 disk
└─xvda1                                                                                      202:1      0    8G  0 part /
xvdcz                                                                                        202:26368  0   22G  0 disk
└─xvdcz1                                                                                     202:26369  0   22G  0 part
  ├─docker-docker--pool_tdata                                                                253:1      0 21.7G  0 lvm
  │ └─docker-docker--pool                                                                    253:2      0 21.7G  0 lvm
  │   └─docker-202:1-263265-7fc53535f551d54f33265136b12b8f6e461ec252ebd89de5a929721d6d1cd92f 253:3      0   10G  0 dm   /var/lib/docker/devicemapper/mnt/7fc53535f551d54f33265136b12b8f6e461ec252ebd89de5a929721d6d1cd92f
  └─docker-docker--pool_tmeta                                                                253:0      0   24M  0 lvm
    └─docker-docker--pool                                                                    253:2      0 21.7G  0 lvm
      └─docker-202:1-263265-7fc53535f551d54f33265136b12b8f6e461ec252ebd89de5a929721d6d1cd92f 253:3      0   10G  0 dm   /var/lib/docker/devicemapper/mnt/7fc53535f551d54f33265136b12b8f6e461ec252ebd89de5a929721d6d1cd92f

[root@ip-123-24-1-108 ec2-user]# docker info | grep "Data Space"
 Data Space Used: 367.5MB
 Data Space Total: 23.33GB
 Data Space Available: 22.96GB
[root@ip-123-24-1-108 ec2-user]#
```

扱おうとしているデータサイズは大きく見積もって30GB程度。

#コンテナボリュームを任意のサイズに上げるには
まず、上記インスタンスがあるAZと同じ所に必要なサイズのEBSボリュームを作成する。今回のインスタンスは東京リージョンデフォルトVPCのap-northeast-1dに出来たので、ap-northeast-1dに30GBのボリュームを追加する。

```
% aws ec2 create-volume --availability-zone ap-northeast-1d --no-encrypted --size 30 --volume-type gp2
{
    "AvailabilityZone": "ap-northeast-1d",
    "CreateTime": "2018-08-28T12:12:20.000Z",
    "Encrypted": false,
    "Size": 30,
    "SnapshotId": "",
    "State": "creating",
    "VolumeId": "vol-0d132255a5117ade0",
    "Iops": 100,
    "Tags": [],
    "VolumeType": "gp2"
}
```

該当インスタンスにアタッチ。

```
% aws ec2 attach-volume --device /dev/sdf --instance-id i-086260a50aca0ec57 --volume-id vol-0d132255a5117ade0
{
    "AttachTime": "2018-08-28T12:15:03.018Z",
    "Device": "/dev/sdf",
    "InstanceId": "i-086260a50aca0ec57",
    "State": "attaching",
    "VolumeId": "vol-0d132255a5117ade0"
}
```

インスタンスにsshで接続してマウントしていく。
まずはアタッチしたデバイスがどのような名前で認識されてるか確認。

```
[root@ip-123-24-1-108 ec2-user]# lsblk
NAME                                                                                         MAJ:MIN   RM  SIZE RO TYPE MOUNTPOINT
xvda                                                                                         202:0      0    8G  0 disk
└─xvda1                                                                                      202:1      0    8G  0 part /
xvdcz                                                                                        202:26368  0   22G  0 disk
└─xvdcz1                                                                                     202:26369  0   22G  0 part
  ├─docker-docker--pool_tdata                                                                253:1      0 21.7G  0 lvm
  │ └─docker-docker--pool                                                                    253:2      0 21.7G  0 lvm
  │   └─docker-202:1-263265-7fc53535f551d54f33265136b12b8f6e461ec252ebd89de5a929721d6d1cd92f 253:3      0   10G  0 dm   /var/lib/docker/devicemapper/mnt/7fc53535f551d54f33265136b12b8f6e461ec252ebd89de5a929721d6d1cd92f
  └─docker-docker--pool_tmeta                                                                253:0      0   24M  0 lvm
    └─docker-docker--pool                                                                    253:2      0 21.7G  0 lvm
      └─docker-202:1-263265-7fc53535f551d54f33265136b12b8f6e461ec252ebd89de5a929721d6d1cd92f 253:3      0   10G  0 dm   /var/lib/docker/devicemapper/mnt/7fc53535f551d54f33265136b12b8f6e461ec252ebd89de5a929721d6d1cd92f
xvdf                                                                                         202:80     0   30G  0 disk
```

xvdfで30GB分アタッチされてるのがわかる。
次にファイルシステムを確認。作ったばかりなので、dataとなっているはず。

```
[root@ip-123-24-1-108 ec2-user]# file -s /dev/xvdf
/dev/xvdf: data
```

`lsblk`コマンドで出力されるNAMEには、プレフィクスに`/dev`が隠れている。そのため、デバイス名を指定する時は`/dev/xvdf`というようにすることが必要。

dataであることを確認できたので、ext4でフォーマットしていく。

```
[root@ip-123-24-1-108 ec2-user]# mkfs -t ext4 /dev/xvdf
mke2fs 1.42.12 (29-Aug-2014)
Creating filesystem with 7864320 4k blocks and 1966080 inodes
Filesystem UUID: 4ea8d8ed-e80a-4f38-94f3-00ce7b5a8868
Superblock backups stored on blocks:
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
	4096000

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
```
もう一度ファイルシステムを確認するとext4になっていることがわかる。

```
[root@ip-123-24-1-108 ec2-user]# file -s /dev/xvdf
/dev/xvdf: Linux rev 1.0 ext4 filesystem data, UUID=4ea8d8ed-e80a-4f38-94f3-00ce7b5a8868 (extents) (large files) (huge files)
```
マウントするディレクトリを作成し、マウントする。

```
[root@ip-123-24-1-108 ec2-user]# mkdir dcmount
[root@ip-123-24-1-108 ec2-user]# mount /dev/xvdf dcmount/
```
マウント出来たことを確認するために`df`コマンドを入力

```
[root@ip-123-24-1-108 ec2-user]# df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
devtmpfs         988M   88K  988M    1% /dev
tmpfs            997M     0  997M    0% /dev/shm
/dev/xvda1       7.8G  780M  6.9G   10% /
/dev/dm-3        9.8G   52M  9.2G    1% /var/lib/docker/devicemapper/mnt/7fc53535f551d54f33265136b12b8f6e461ec252ebd89de5a929721d6d1cd92f
shm               64M     0   64M    0% /var/lib/docker/containers/7ddf22ce2a14789d1f1cae642fec6a38aa961f943582206df1ecf937edb5c427/mounts/shm
/dev/xvdf         30G   44M   28G    1% /home/ec2-user/dcmount
```
しっかりマウントされていることがわかる。30GBのディスクなので、管理領域として1%程度使われており、実際に使えるのが28GBだとわかる。

これで完了だが、再起動した時にマウントが解除されてしまうので、固定する。
`/etc/fstab`に、このデバイスを、このディレクトリに、このファイルシステムとオプションでマウントする。という事を書き足していく。
なにか間違えた時のためにコピーもしっかりと。
`[root@ip-123-24-1-108 ec2-user]# cp /etc/fstab /etc/fstab.bcup`

```conf:/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
UUID=4ea8d8ed-e80a-4f38-94f3-00ce7b5a8868 /home/ec2-user/dcmount ext4 defaults,nofail 0 2
```
左から順にスペース区切りで
デバイス名 マウントポイント ファイルシステム マウントオプション dumpフラグ fsckがチェックする順序
となっている。デバイス名は`/dev/xvdf`でも可能だが、UUIDで指定することが推奨されている。UUIDは`file -s /dev/xvdf`コマンドで確認できる。
マウントオプション以降はもし分からないならこのままコピーペーストで問題はない。
簡単に説明すると、マウントオプションdefaultsはその名の通りデフォルト設定でasync,auto,dev,exec,nouser,rw,suidと同じ意味になる。
nofailはブート時に読み込み失敗しても起動しろってオプション。
dumpフラグ0は、dumpコマンドのバクアップ対象かどうか、ファイルシステムがext2とext3なら通常1にしておく。
fsckによるチェック順序はその名の通り何番目にチェックするか。困ったら何も考えずに2にしておく。0ならチェックされない。

これでインスタンスの設定は完了。最後にタスク定義の設定をする。
既にあるタスク定義を更新するので、マネジメントコンソールから設定をする。
タスク定義のボリュームを、任意の名前とマウントしたディレクトリのフルパスで定義し、
<img width="222" alt="スクリーンショット 2018-08-28 21.35.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/249725/34b6bcef-c138-70f1-1942-347f29b087ac.png">
コンテナ定義のボリュームを先程定義した名前とDockerコンテナにマウントする任意のディレクトリで選択する。
<img width="1236" alt="スクリーンショット 2018-08-28 21.36.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/249725/626a065e-694f-458d-5d5e-5b2ffac87ce0.png">


以上の手順でDockerコンテナボリュームを任意のサイズに変更できる。