【AWS】RHELのEBSを交換してみた

Qiita初投稿です。

EBSをスナップショットから復元してアタッチしたらうまく起動しなかった！とか、EBS縮小するのにコピーってどうするの？とか、EBS絡みのネタが頻繁に発生しました。

起動失敗した件はUUIDの重複が原因でしたが、そもそもUUIDって何？というレベルでしたので、一度自分でインスタンス間でEBS交換を検証してみました。

そしたらまあハマるハマる…
その度に調べて色々と知識をつけることができ、なんとか成功したので検証手順、あとハマった箇所も一部の切り分け情報を残してメモとして共有します。

#環境

・作業用インスタンス（work）

```ruby:AmazonLinux2
[ec2-user@work ~]$ cat /etc/system-release
Amazon Linux release 2 (Karoo)
```

・コピー元インスタンス（source）
・コピー先EBS（dest)

```ruby:RHEL
[ec2-user@source ~]$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.7 (Maipo)
[ec2-user@dest ~]$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.7 (Maipo)
```

すべてt2.microです。
それでも自腹検証なのでヒヤヒヤしている自分が情けないｗ
作業用インスタンスとコピー系のディストリビューションを変えてますが、Amazon Linux2同士でもうまく行きました。

#前提

・EBS（dest）について、BIOSパーティションを持つEBSをコピー用として作成しておく必要があります。
具体的には同一ディストリビューションのAMIから希望サイズのEBSで作成し、インスタンスだけ削除します。

#手順

##1.ルートボリュームデタッチ

sourceインスタンスを停止し、ルートボリュームをデタッチします。
この前にルートデバイス名（今回は/dev/sda1）を控えます。

##2.EBSアタッチ

workインスタンスにsourceとdestの各EBSをアタッチします。
（dest用EBSは既にデタッチされている前提です）
/dev/sdf source
/dev/sdg dest

```ruby:
[ec2-user@work ~]$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk
└─xvda1 202:1    0   8G  0 part /
xvdf    202:80   0  10G  0 disk
├─xvdf1 202:81   0   1M  0 part
└─xvdf2 202:82   0  10G  0 part
xvdg    202:96   0  10G  0 disk
├─xvdg1 202:97   0   1M  0 part
└─xvdg2 202:98   0  10G  0 part
[ec2-user@work ~]$ sudo parted -l
モデル: Xen Virtual Block Device (xvd)
ディスク /dev/xvda: 8590MB
セクタサイズ (論理/物理): 512B/512B
パーティションテーブル: gpt
ディスクフラグ:
番号  開始    終了    サイズ  ファイルシステム  名前                 フラグ
128   1049kB  2097kB  1049kB                    BIOS Boot Partition  bios_grub
1    2097kB  8590MB  8588MB  xfs               Linux

モデル: Xen Virtual Block Device (xvd)
ディスク /dev/xvdf: 10.7GB
セクタサイズ (論理/物理): 512B/512B
パーティションテーブル: gpt
ディスクフラグ: pmbr_boot
番号  開始    終了    サイズ  ファイルシステム  名前  フラグ
1    1049kB  2097kB  1049kB                          bios_grub
2    2097kB  10.7GB  10.7GB  xfs

モデル: Xen Virtual Block Device (xvd)
ディスク /dev/xvdg: 10.7GB
セクタサイズ (論理/物理): 512B/512B
パーティションテーブル: gpt
ディスクフラグ: pmbr_boot
番号  開始    終了    サイズ  ファイルシステム  名前  フラグ
1    1049kB  2097kB  1049kB                          bios_grub
2    2097kB  10.7GB  10.7GB  xfs

[ec2-user@work ~]$
```

##3.マウントポイント作成

マウントポイントを作成します。
/mnt/old source
/mnt/new dest

```ruby:
[ec2-user@work ~]$ sudo mkdir -p /mnt/new /mnt/old
[ec2-user@work ~]$
[ec2-user@work ~]$ ll /mnt/
合計 0
drwxr-xr-x 2 root root 6 12月 22 00:59 new
drwxr-xr-x 2 root root 6 12月 22 00:59 old
[ec2-user@work ~]$
```

##4.sourceマウント

source→oldにマウントします。

```ruby:
[ec2-user@work ~]$ sudo mount /dev/xvdf2 /mnt/old/
[ec2-user@work ~]$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk
└─xvda1 202:1    0   8G  0 part /
xvdf    202:80   0  10G  0 disk
├─xvdf1 202:81   0   1M  0 part
└─xvdf2 202:82   0  10G  0 part /mnt/old
xvdg    202:96   0  10G  0 disk
├─xvdg1 202:97   0   1M  0 part
└─xvdg2 202:98   0  10G  0 part
[ec2-user@work ~]$
```

（蛇足）UUIDの重複

この段階でnewをマウントすると失敗します。
dmesgよりUUIDの重複が原因と分かります。
mountコマンドに-o nouuidオプションを付けるとマウントできます。

```ruby:
[ec2-user@work ~]$ sudo mount /dev/xvdg2 /mnt/new/
mount: /mnt/new: wrong fs type, bad option, bad superblock on /dev/xvdg2, missing codepage or helper program, or other error.
[ec2-user@work ~]$
[ec2-user@work ~]$ dmesg | tail
（略）
[  559.915967] XFS (xvdg2): Filesystem has duplicate UUID 4f462461-aef2-46ee-a16e-8548d8f7fbf7 - can't mount
[ec2-user@work ~]$

[ec2-user@work ~]$ sudo mount -t xfs -o nouuid /dev/xvdg2 /mnt/new/
[ec2-user@work ~]$
[ec2-user@work ~]$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk
└─xvda1 202:1    0   8G  0 part /
xvdf    202:80   0  10G  0 disk
├─xvdf1 202:81   0   1M  0 part
└─xvdf2 202:82   0  10G  0 part /mnt/old
xvdg    202:96   0  10G  0 disk
├─xvdg1 202:97   0   1M  0 part
└─xvdg2 202:98   0  10G  0 part /mnt/new
[ec2-user@work ~]$
```

マウントしたままだと以下フォーマット失敗しますので、アンマウントします。

##5.destフォーマット

EBS（dest）の「パーティション部分」をフォーマットします。
対象を/xvdgにしてしまうとBIOS設定も消えますので注意しましょう。
-fつける必要があり、確認は表示されないので要注意。

```ruby:
[ec2-user@work ~]$ sudo mkfs -t xfs -f /dev/xvdg2
meta-data=/dev/xvdg2             isize=512    agcount=4, agsize=655231 blks
        =                       sectsz=512   attr=2, projid32bit=1
        =                       crc=1        finobt=1, sparse=0
data     =                       bsize=4096   blocks=2620923, imaxpct=25
        =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
        =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
[ec2-user@work ~]$
[ec2-user@work ~]$ sudo parted -l
モデル: Xen Virtual Block Device (xvd)
ディスク /dev/xvda: 8590MB
セクタサイズ (論理/物理): 512B/512B
パーティションテーブル: gpt
ディスクフラグ:
番号  開始    終了    サイズ  ファイルシステム  名前                 フラグ
128   1049kB  2097kB  1049kB                    BIOS Boot Partition  bios_grub
1    2097kB  8590MB  8588MB  xfs               Linux

モデル: Xen Virtual Block Device (xvd)
ディスク /dev/xvdf: 10.7GB
セクタサイズ (論理/物理): 512B/512B
パーティションテーブル: gpt
ディスクフラグ: pmbr_boot
番号  開始    終了    サイズ  ファイルシステム  名前  フラグ
1    1049kB  2097kB  1049kB                          bios_grub
2    2097kB  10.7GB  10.7GB  xfs

モデル: Xen Virtual Block Device (xvd)
ディスク /dev/xvdg: 10.7GB
セクタサイズ (論理/物理): 512B/512B
パーティションテーブル: gpt
ディスクフラグ: pmbr_boot
番号  開始    終了    サイズ  ファイルシステム  名前  フラグ
1    1049kB  2097kB  1049kB                          bios_grub
2    2097kB  10.7GB  10.7GB  xfs

[ec2-user@work ~]$
```

##6.destマウント

EBS（dest）を/mnt/newにマウントします。

```ruby:
[ec2-user@work ~]$ sudo mount /dev/xvdg2 /mnt/new
[ec2-user@work ~]$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk
└─xvda1 202:1    0   8G  0 part /
xvdf    202:80   0  10G  0 disk
├─xvdf1 202:81   0   1M  0 part
└─xvdf2 202:82   0  10G  0 part /mnt/old
xvdg    202:96   0  10G  0 disk
├─xvdg1 202:97   0   1M  0 part
└─xvdg2 202:98   0  10G  0 part /mnt/new
```

##7.データ同期

データ同期します。
進捗見たくてvオプションつけました。
そんなにsyncする量も無いんですけど、一応。

```ruby:
[ec2-user@work ~]$ sudo rsync -axv /mnt/old/ /mnt/new/
[ec2-user@work ~]$ ll /mnt/new/
合計 16
lrwxrwxrwx  1 root root    7  9月 23  2019 bin -> usr/bin
dr-xr-xr-x  5 root root 4096  9月 23  2019 boot
drwxr-xr-x  2 root root    6  9月 23  2019 data
drwxr-xr-x  2 root root    6  9月 23  2019 dev
drwxr-xr-x 76 root root 8192 12月 22 00:56 etc
drwxr-xr-x  3 root root   22 12月 22 00:50 home
lrwxrwxrwx  1 root root    7  9月 23  2019 lib -> usr/lib
lrwxrwxrwx  1 root root    9  9月 23  2019 lib64 -> usr/lib64
drwxr-xr-x  2 root root    6 12月 14  2017 media
drwxr-xr-x  2 root root    6 12月 14  2017 mnt
drwxr-xr-x  2 root root    6 12月 14  2017 opt
drwxr-xr-x  2 root root    6  9月 23  2019 proc
dr-xr-x---  3 root root  149 12月 22 00:50 root
drwxr-xr-x  2 root root    6  9月 23  2019 run
lrwxrwxrwx  1 root root    8  9月 23  2019 sbin -> usr/sbin
drwxr-xr-x  2 root root    6 12月 14  2017 srv
drwxr-xr-x  2 root root    6  9月 23  2019 sys
drwxrwxrwt  7 root root  156 12月 22 00:56 tmp
drwxr-xr-x 13 root root  155  9月 23  2019 usr
drwxr-xr-x 19 root root  267 12月 22 00:50 var
[ec2-user@work ~]$
```

##8.マウントポイント移動

dev,proc,sysディレクトリをマウントポイントに移動します。
なぜかsudoでは実行できなかったのでroot昇格。

```ruby:
[ec2-user@work ~]$ sudo for i in dev proc sys run; do mount -o bind /$i /mnt/new/$i; done
-bash: 予期しないトークン `do' 周辺に構文エラーがあります
[ec2-user@work ~]$
[ec2-user@work ~]$ sudo su -
[root@work ~]#
[root@work ~]# for i in dev proc sys run; do mount -o bind /$i /mnt/new/$i; done
[root@work ~]#
```

##9.ルートディレクトリ変更

ルートディレクトリを変更します。

```ruby:
[root@work ~]# chroot /mnt/new/
[root@work /]#
```

##10.grub,dracut

grubとdracutに設定反映します。

```ruby:
[root@work /]# sudo grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.10.0-1062.1.2.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-1062.1.2.el7.x86_64.img
Found linux image: /boot/vmlinuz-0-rescue-026767dbe06a4910a5ce3bd0def903c0
Found initrd image: /boot/initramfs-0-rescue-026767dbe06a4910a5ce3bd0def903c0.img
done
[root@work /]#
[root@work /]# sudo dracut -f -vvvvv
Kernel version 4.14.203-156.332.amzn2.x86_64 has no module directory /lib/modules/4.14.203-156.332.amzn2.x86_64
Executing: /sbin/dracut -f -vvvvv
dracut module 'modsign' will not be installed, because command 'keyctl' could not be found!
（中略）
*** Creating initramfs image file '/boot/initramfs-4.14.203-156.332.amzn2.x86_64.img' done ***
[root@work /]#
```

##11.イメージ確認

/bootにカーネルイメージがあることを確認します。
今回だとinitramfs-3.10.0-1062.1.2.el7.x86_64.imgとvmlinuz-3.10.0-1062.1.2.el7.x86_64が対象です。

```ruby:
[root@work /]# ll /boot
total 125408
-rw-r--r-- 1 root root   152980 Sep 16  2019 config-3.10.0-1062.1.2.el7.x86_64
drwxr-xr-x 3 root root       17 Sep 23  2019 efi
drwxr-xr-x 2 root root       39 Sep 23  2019 grub
drwx------ 5 root root       97 Dec 22 01:21 grub2
-rw------- 1 root root 45168431 Sep 23  2019 initramfs-0-rescue-026767dbe06a4910a5ce3bd0def903c0.img
-rw------- 1 root root 44680626 Sep 23  2019 initramfs-3.10.0-1062.1.2.el7.x86_64.img
-rw------- 1 root root 21013940 Dec 22 01:22 initramfs-4.14.203-156.332.amzn2.x86_64.img
-rw-r--r-- 1 root root   318717 Sep 16  2019 symvers-3.10.0-1062.1.2.el7.x86_64.gz
-rw------- 1 root root  3595191 Sep 16  2019 System.map-3.10.0-1062.1.2.el7.x86_64
-rwxr-xr-x 1 root root  6734128 Sep 23  2019 vmlinuz-0-rescue-026767dbe06a4910a5ce3bd0def903c0
-rwxr-xr-x 1 root root  6734128 Sep 16  2019 vmlinuz-3.10.0-1062.1.2.el7.x86_64
[root@work /]#
```

##12.マウントポイント戻し

chrootを終了して環境戻しします。

```ruby:
[root@work /]# exit
exit
[root@work ~]# for i in dev proc sys run; do sudo umount /mnt/new/$i; done
[root@work ~]#
[root@work ~]# exit
logout
[ec2-user@work ~]$
```

##13.destアンマウント

EBS（dest）をworkインスタンスからアンマウントします。

```ruby:
[ec2-user@work ~]$ sudo umount /mnt/new/
[ec2-user@work ~]$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk
└─xvda1 202:1    0   8G  0 part /
xvdf    202:80   0  10G  0 disk
├─xvdf1 202:81   0   1M  0 part
└─xvdf2 202:82   0  10G  0 part /mnt/old
xvdg    202:96   0  10G  0 disk
├─xvdg1 202:97   0   1M  0 part
└─xvdg2 202:98   0  10G  0 part
[ec2-user@work ~]$
```

##14.destディスクをsourceインスタンスにアタッチ

sourceインスタンスにEBS（dest）を/dev/sda1にアタッチします。
結果のみ。

```
[ec2-user@work ~]$ aws ec2 describe-instances --instance-id i-00e91cb092ed7d1f6 --query "Reservations[].Instances[].{BlockDeviceMappings:BlockDeviceMappings,Tags:Tags}"
[
   {
       "BlockDeviceMappings": [
           {
               "DeviceName": "/dev/sda1",
               "Ebs": {
                   "Status": "attached",
                   "DeleteOnTermination": false,
                   "VolumeId": "vol-0a3b39a154a8b8896",
                   "AttachTime": "2020-12-22T01:29:38.000Z"
               }
           }
       ],
       "Tags": [
           {
               "Value": "source",
               "Key": "Name"
           }
       ]
   }
]
[ec2-user@work ~]$ aws ec2 describe-volumes --volume-id vol-0a3b39a154a8b8896 --query "Volumes[].{Attachments:Attachments,Tags:Tags}"
[
   {
       "Attachments": [
           {
               "AttachTime": "2020-12-22T01:29:38.000Z",
               "InstanceId": "i-00e91cb092ed7d1f6",
               "VolumeId": "vol-0a3b39a154a8b8896",
               "State": "attached",
               "DeleteOnTermination": false,
               "Device": "/dev/sda1"
           }
       ],
       "Tags": [
           {
               "Value": "dest",
               "Key": "Name"
           }
       ]
   }
]
[ec2-user@work ~]$
```

##15.起動確認（失敗）

起動確認すると、SSHログインに失敗しました。

```ruby:
$ ssh -i /test/test-keypair.pem ec2-user@13.114.120.218
The authenticity of host '13.114.120.218 (13.114.120.218)' can't be established.
ECDSA key fingerprint is SHA256:ssx/2oK2MT+NGeyeYaDKRFuCfv601ZEbPhxKu21vF/8.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '13.114.120.218' (ECDSA) to the list of known hosts.
Last login: Tue Dec 22 00:54:07 2020 from m106073023097.v4.enabler.ne.jp
/bin/bash: Permission denied
Connection to 13.114.120.218 closed.
```

SSHコマンドの-vオプションでログを出力してみます。
SSH自体は通ってるっぽい。
（IP変わっているのはEIPを付与せずに何度か停止したりしたからです）

```ruby:
$ ssh -i /test/test-keypair.pem ec2-user@13.115.247.170 -v
OpenSSH_7.9p1, LibreSSL 2.7.3
debug1: Reading configuration data /etc/ssh/ssh_config
（中略）
debug1: Trying private key: /test/test-keypair.pem
debug1: Authentication succeeded (publickey).
Authenticated to 13.115.247.170 ([13.115.247.170]:22).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: pledge: network
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
debug1: Sending environment.
debug1: Sending env LANG = ja_JP.UTF-8
Last login: Tue Dec 22 00:54:07 2020 from m106073023097.v4.enabler.ne.jp
/bin/bash: Permission denied
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: client_input_channel_req: channel 0 rtype eow@openssh.com reply 0
debug1: channel 0: free: client-session, nchannels 1
Connection to 13.115.247.170 closed.
Transferred: sent 2720, received 2596 bytes, in 0.2 seconds
Bytes per second: sent 11847.6, received 11307.5
debug1: Exit status 1
$
```

以下フォーラムからSELinuxが怪しいと判断しました。
https://forums.aws.amazon.com/thread.jspa?threadID=34431

有効化されていたので、無効化します。

```ruby:
[root@work ~]# cat /mnt/new/etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

[root@work ~]#
[root@work ~]# vi /mnt/new/etc/selinux/config
[root@work ~]#
[root@work ~]# cat /mnt/new/etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

[root@work ~]#
```

##16.起動確認（成功）

ログイン成功です！
destディスクからsourceのホスト名が表示されました。

```ruby:
$ ssh -i /test/test-keypair.pem ec2-user@18.181.96.233
The authenticity of host '18.181.96.233 (18.181.96.233)' can't be established.
ECDSA key fingerprint is SHA256:ssx/2oK2MT+NGeyeYaDKRFuCfv601ZEbPhxKu21vF/8.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '18.181.96.233' (ECDSA) to the list of known hosts.
Last login: Tue Dec 22 00:54:07 2020 from m106073023097.v4.enabler.ne.jp
[ec2-user@source ~]$
```

##参考記事

https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/selinux_users_and_administrators_guide/sect-security-enhanced_linux-working_with_selinux-changing_selinux_modes

https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-linux-fix-permission-denied-errors/

https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-linux-kernel-panic-unable-mount/

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-using-volumes.html