CentOS Stream の CentOS 8 を EC2 で使ってみた

2020.06.12

こんにちは、望月です。

最近は CentOS 8 の公式 AMI が来ることを楽しみにしている日々です。
なかなかこないなーと思っていたところ、CentOS Stream で CentOS 8 の EC2 で使えそうなイメージが公開されていたので、公式の CentOS8 がこない寂しさを埋めるため、試してみました。

CentOS Cloud images

CentOS Stream は開発者向けのプラットフォームとなり、Fedora Linux と Red Hat Enterprise Linux の中間に位置するローリングリリースの Linux ディストリビューションとなるようです。
そのため、本番利用などには向かないディストリビューションとなるのでご注意ください。

ja/Manuals/ReleaseNotes/CentOSStream - CentOS Wiki

やってみた

環境

  • MacBook Pro (macOS 10.15.5)
    • Homebrew 2.4.0

イメージの変換

公開されている qcow2 フォーマットを AWS にインポートするために、raw フォーマットへ変換を行い、S3 バケットへコピーを行います。
raw フォーマットへ変換したイメージは 10 GBになるので、容量キツキツな人はご注意ください。

  • 以下URL から CentOS-8-ec2-8.1.1911-20200113.3.x86_64.qcow2 をダウンロードします。

CentOS Cloud images

  • qcow2 フォーマットから raw フォーマットへ変換するために、qemu-img をインストールします。
$ brew install qemu
  • qcow2 フォーマットから raw フォーマットへ変換します。
$ qemu-img convert -f qcow2 ./CentOS-8-ec2-8.1.1911-20200113.3.x86_64.qcow2 -O raw ./CentOS-8-ec2-8.1.1911-20200113.3.x86_64.raw
  • イメージの保存用に S3 バケットを作成し raw フォーマットのイメージを S3 へコピーします。
$ aws s3 cp CentOS-8-ec2-8.1.1911-20200113.3.x86_64.raw s3://<S3 Bucket Name>/

VM Import/Export を利用するための準備

S3 へコピーしたイメージを利用するために VM Import/Export を使います。
VM Import/Export を使うためにはサービスロールの作成が必要となります。

  • trust-policy.json というファイルを作成し、下記ポリシーを記入します。
{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Principal": { "Service": "vmie.amazonaws.com" },
         "Action": "sts:AssumeRole",
         "Condition": {
            "StringEquals":{
               "sts:Externalid": "vmimport"
            }
         }
      }
   ]
}
  • vmimport という名前のロールを作成します。
$ aws iam create-role --role-name vmimport --assume-role-policy-document file://trust-policy.json
  • role-policy.json というファイルを作成し、ポリシーを作成します。
    • json 内の 「S3 Bucket Name」 には、イメージを保存した S3 バケットを指定します。
{
   "Version":"2012-10-17",
   "Statement":[
      {
         "Effect": "Allow",
         "Action": [
            "s3:GetBucketLocation",
            "s3:GetObject",
            "s3:ListBucket" 
         ],
         "Resource": [
            "arn:aws:s3:::<S3 Bucket Name>",
            "arn:aws:s3:::<S3 Bucket Name>/*"
         ]
      },
      {
         "Effect": "Allow",
         "Action": [
            "ec2:ModifySnapshotAttribute",
            "ec2:CopySnapshot",
            "ec2:RegisterImage",
            "ec2:Describe*"
         ],
         "Resource": "*"
      }
   ]
}
  • ポリシーを vmimport IAM ロールに割り当てます。
$aws iam put-role-policy --role-name vmimport --policy-name vmimport --policy-document file://role-policy.json

イメージをインポートし、AMI に変換!しかし……。

S3 にコピーしたイメージをインポートします。結果から言うと失敗した失敗した失敗した……。
変換時に ClientError: Unable to determine kernel version. とエラーが表示され、AMI が作成されることはありませんでした。
悲しいけど、やったことだけ記載しておきます。

  • centosstream8.json というファイルを作成し、下記内容を記入します。
    • json 内の 「S3 Bucket Name」 には、イメージを保存した S3 バケットを指定します。
[
    {
        "Description": "CentOS Stream 8",
        "Format": "raw",
        "UserBucket": {
            "S3Bucket": "<S3 Bucket Name>",
            "S3Key": "CentOS-8-ec2-8.1.1911-20200113.3.x86_64.raw"
        }
    }
]
  • イメージのインポートを行います
$ aws ec2 import-image --description "CentOS Stream 8" --disk-containers file://centosstream8.json
  • タスクを確認したところ、エラーで終了してました……。
$ aws ec2 describe-import-image-tasks

{
    "ImportImageTasks": [
        {
            "Description": "CentOS Stream 8",
            "ImportTaskId": "import-ami-abcdefghijklmnopq",
            "SnapshotDetails": [
                {
                    "Description": "CentOS Stream 8",
                    "DiskImageSize": 10737418240.0,
                    "Format": "RAW",
                    "Status": "completed",
                    "UserBucket": {
                        "S3Bucket": "<S3 Bucket Name>",
                        "S3Key": "CentOS-8-ec2-8.1.1911-20200113.3.x86_64.raw"
                    }
                }
            ],
            "Status": "deleted",
            "StatusMessage": "ClientError: Unable to determine kernel version.",
            "Tags": []
        }
    ]
}

イメージをインポートし、スナップショットに変換

AMI への変換が失敗したので、スナップショットへの変換を試してみました。こちらは無事成功しました。
ちなみに、スナップショットから AMI 作成を行い、EC2 インスタンスを立ち上げてみましたが、うまく起動せず接続できなかったため、先は長い……。

  • イメージのインポートを行います。
    • centosstream8.json は上記で作成したものと同じ内容です。
$ aws ec2 import-snapshot --description "CentOS Stream 8" --disk-container file://centosstream8.json
  • タスクを見て、完了したことを確認します。
$ aws ec2 describe-import-snapshot-tasks

{
    "ImportSnapshotTasks": [
        {
            "Description": "CentOS Stream 8",
            "ImportTaskId": "import-snap-abcdefghijklmnopq",
            "SnapshotTaskDetail": {
                "Description": "CentOS Stream 8",
                "DiskImageSize": 10737418240.0,
                "Format": "RAW",
                "SnapshotId": "snap-abcdefghijklmnopq",
                "Status": "completed",
                "UserBucket": {
                    "S3Bucket": "<S3 Bucket Name>",
                    "S3Key": "CentOS-8-ec2-8.1.1911-20200113.3.x86_64.raw"
                }
            },
            "Tags": []
        }
    ]
}
  • わかりやすいようにスナップショットに名前をつけます。
aws ec2 create-tags --resources snap-abcdefghijklmnopq --tags 'Key="Name",Value="CentOS Stream 8 import"'

initramfs ファイルの再作成

AMI を作成してもうまくいかないし、どうしたらエエんや……。と悩んでいたところ、下記に答えがありました。

0016614: No Centos 8 AMIs - CentOS Bug Tracker

RHEL 8 のインスタンスを立ち上げて、インポートしたスナップショットを 2 個目のボリュームとしてマウント、そこで initramfs ファイルの再作成を行えばいいとのことみたいです。
initramfs ファイルは Linux の起動中に一時的に使われるルートファイルシステムとなります。
これを作り直す必要あるということはそりゃ立ち上がらないよな〜。という気持ちになりました。

  • run-instances_mappings.json というファイルを作成し、下記内容を記入します。
    • 2 個目のボリュームとして、インポートしたスナップショットを指定します。
    • 「SnapshotId」は自身の環境のものを入れてください。
[
  {
    "DeviceName": "/dev/sdb",
    "Ebs": {
      "DeleteOnTermination": false,
      "SnapshotId": "snap-abcdefghijklmnopq",
      "VolumeType": "gp2",
      "Encrypted": false
    }
  }
]
  • RHEL 8 のインスタンスを立ち上げます。
    • subnet-idsecurity-group-ids は自身の環境のものを入れてください。
aws ec2 run-instances --region ap-northeast-1 \
  --image-id ami-07dd14faa8a17fb3e --count 1 \
  --instance-type t3.small --key-name aws-keypair \
  --subnet-id subnet-abcdefghijklmnopq \
  --security-group-ids sg-abcdefghijklmnopq \
  --credit-specification CpuCredits=standard \
  --associate-public-ip-address \
  --tag-specifications 'ResourceType=instance,Tags=[{Key="Name",Value="RH8 temp"}]'
  --block-device-mappings file://run-instances_mappings.json
  • 作成されたインスタンスへログインします
$ ssh ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com

$ cat /etc/redhat-release

Red Hat Enterprise Linux release 8.2 (Ootpa)
  • 2 個目のボリュームが認識されていることを確認し /mnt にマウントします。
$ lsblk

NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
nvme0n1     259:0    0   10G  0 disk
|-nvme0n1p1 259:1    0    1M  0 part
`-nvme0n1p2 259:2    0   10G  0 part /
nvme1n1     259:3    0   10G  0 disk
`-nvme1n1p1 259:4    0  7.8G  0 part

$ sudo mount /dev/nvme1n1p1 /mnt

$ df -h

Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        873M     0  873M   0% /dev
tmpfs           895M     0  895M   0% /dev/shm
tmpfs           895M  8.4M  887M   1% /run
tmpfs           895M     0  895M   0% /sys/fs/cgroup
/dev/nvme0n1p2   10G  1.1G  9.0G  11% /
tmpfs           179M     0  179M   0% /run/user/1000
/dev/nvme1n1p1  7.9G  1.3G  6.6G  16% /mnt
  • chroot に必要なファイルシステムをマウントし initramfs ファイルを再作成します。この辺は Linux レスキューモードでやったことある人も多いかと思います。
    • 前後で initramfs ファイルを確認し、更新されていることを確認します。
$ sudo mount -t proc proc /mnt/proc
$ sudo mount -t tmpfs tmpfs /mnt/run
$ sudo mount -t devtmpfs devtmpfs /mnt/dev
$ sudo mount -t sysfs sysfs /mnt/sys
$ sudo chroot /mnt

# ls -lha /boot/initramfs-4.18.0-147.3.1.el8_1.x86_64.img
-rw-------. 1 root root 38M  6月 11 12:56 /boot/initramfs-4.18.0-147.3.1.el8_1.x86_64.img

# dracut -f /boot/initramfs-4.18.0-147.3.1.el8_1.x86_64.img 4.18.0-147.3.1.el8_1.x86_64

# ls -lha /boot/initramfs-4.18.0-147.3.1.el8_1.x86_64.img
-rw-------. 1 root root 38M  6月 11 15:02 /boot/initramfs-4.18.0-147.3.1.el8_1.x86_64.img

# exit

$ sudo umount /mnt/sys
$ sudo umount /mnt/dev
$ sudo umount /mnt/run
$ sudo umount /mnt/proc
$ sudo umount /mnt

$ sudo shutdown -h now

変更したボリュームから AMI へ変換する

RHEL 8 にマウントした 2 個目のボリュームからスナップショットを作成し、AMI へ変換を行います。

  • ボリュームからスナップショットの作成を行います。
    • 「volume-id」は自身の環境のものを入れてください。
$ aws ec2 create-snapshot --tag-specifications 'ResourceType=snapshot,Tags=[{Key="Name",Value="CentOS Stream 8 snapshot"}]' --volume-id vol-abcdefghijklmnopq

$ aws ec2 describe-snapshots --owner self
  • register-image_mappings.json というファイルを作成し、下記内容を記入します。
    • 「SnapshotId」は自身の環境のものを入れてください。
[
  {
    "DeviceName": "/dev/sda1",
    "Ebs": {
      "DeleteOnTermination": true,
      "SnapshotId": "snap-abcdefghijklmnopq",
      "VolumeSize": 10,
      "VolumeType": "gp2"
    }
  }
]
  • スナップショットから AMI の作成を行います。
aws ec2 register-image \
  --architecture x86_64 \
  --ena-support \
  --name "CentOS Stream 8" \
  --root-device-name /dev/sda1 \
  --virtualization-type hvm \
  --block-device-mapping file://register-image_mappings.json

AMI から EC2 インスタンスを立ち上げる

作成した AMI からインスタンスを作成してみました。

インスタンスのスクリーンショットでログイン画面が表示されたので一安心。とても感動的なスクリーンショットですね。

ログインしてみて、ちょっと確認してみました。
centos ユーザーは作成済みで、SELinux は有効、firewalld はインストールされていない状態です。
ログイン時に cockpit の有効化の方法が表示されていたので、確認しましたが cockpit はデフォルトでインストールされているようでした。
cockpit は Web インターフェイスでサーバーを管理できる仕組みで RHEL 8 でも使うことができます。
cockpit の一機能であるセッション記録ソリューションについて、過去ブログ書いたので気になる方は、ご覧ください。
dnf upgrade してみましたが、問題なくできました!

Red Hat Enterprise Linux 8の新機能「セッション記録ソリューション」を試してみた | Developers.IO

$ ssh centos@ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com
Activate the web console with: systemctl enable --now cockpit.socket

$ dnf upgrade

$ cat /etc/redhat-release
CentOS Linux release 8.1.1911 (Core)

$ uname -a
Linux ip-10-0-0-67.ap-northeast-1.compute.internal 4.18.0-147.8.1.el8_1.x86_64 #1 SMP Thu Apr 9 13:49:54 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

$ id centos
uid=1000(centos) gid=1000(centos) groups=1000(centos),4(adm),10(wheel),190(systemd-journal)

$ getenforce
Enforcing

$ systemctl status firewalld
Unit firewalld.service could not be found.

$ rpm -qa | grep cockpit

cockpit-bridge-196.3-1.el8.x86_64
cockpit-system-196.3-1.el8.noarch
cockpit-ws-196.3-1.el8.x86_64

まとめ

ということで、CentOS 8 (CentOS Stream) を EC2 で利用することができました。
CentOS Stream は開発者向けのプラットフォームとなるため、本番利用は難しいですが試してみたいという熱い思いがあれば、やってみてもいいかもしれません。
はやく、公式の CentOS 8 が来てくれると嬉しいな〜。

参考