はじめに
先日仕事でAnsible
のPlaybook
を作成・テストするためにローカル環境でAmazon Linux 2
の仮想マシン環境を作ったので残しておこうと思います。
Amazon Linux 2をローカルで動かそうと思ったきっかけ
仕事でよくAnsible
を使ってAWSのEC2
向けのコードを書いているのですが、今までは適当なEC2
をスポットインスタンスで作成して動作チェック、もとに戻したい場合は新しくEC2
を作っていました。
ただ、いちいち新しいEC2
を作るのも時間とお金がかかるので、だったらVirtualBox
上でEC2
(Amazon Linux 2
)を実行して、戻したい場合はVirtualBox
のスナップショットでもとに戻せばよいのでは?と思ったのがきっかけです。
環境
今回はVirtualBox
がインストールされているLinux
で仮想マシンを作ってみようと思います。
Windows
で行う場合でも手順はあまり変わりませんが、Windows
のVirtualBox
で行う場合は適宜読み替えてください。
以下、VirtualBox
がインストールされているLinux
ホストマシンの構成。
※OSアップグレードしないとなぁ・・・
構成 | 種別 |
---|---|
OS | Ubuntu 20.04 |
仮想化ソフト | VirtualBox 6.1.40 |
やりかた
そもそもAWSの公式ドキュメントに書いてありました。
上記の公式ドキュメントを参考に以下の流れで進めていきたいと思います。
- Amazon Linux 2 ローカル実行の仕組み
- seed.iso起動イメージの準備
- Amazon Linux 2 VMイメージのダウンロード
- VirtualBox仮想マシンの作成
- SSHでの接続確認
Amazon Linux 2 ローカル実行の仕組み
Amazon Linux 2
をローカルで実行するためには、AWS
でEC2
を作成する場合と同様、初回起動時にcloud-init
を動かし、ネットワーク等の基本設定と追加設定を行わせる必要があるようです。
cloud-init
で必要となるmeta-data
とuser-data
をISO形式でまとめたファイルを初回起動時に読み込ませることでcloud-init
により基本設定が行えるようにしているとのこと。
ファイル名 | 説明 |
---|---|
meta-data | ホスト名やネットワーク設定を記載 |
user-data | EC2作成時に「ユーザデータ」に記載する設定やユーザアカウント設定を記載 |
仕組みとしてはISOファイルを使った自動インストールと同等の仕組みとなるため、Linuxの自動インストールを行ったことがある方はイメージしやすいかと思います。
seed.iso起動イメージの準備
初期設定を行うcloud-init
で必要となるmeta-data
、user-data
の作成と、その2つのファイルをまとめたISOイメージの作成を行います。
meta-dataの作成
ホスト名とネットワーク設定を自分のローカル環境に合わせて行います。
local-hostname: vm_hostname
# eth0 is the default network interface enabled in the image. You can configure static network settings with an entry like the following.
network-interfaces: |
auto eth0
iface eth0 inet static
address 192.168.1.10
network 192.168.1.0
netmask 255.255.255.0
broadcast 192.168.1.255
gateway 192.168.1.254
尚、AWSのドキュメントでは、IPアドレスを固定した上記のようなネットワーク設定が書かれていますが、実際のEC2
の構成になるべく合わせたいのであれば、meta-data
の設定をDHCP用の設定にすることで、EC2
で作成される構成に近い構成になると思います。
但し、DHCPなのでどのアドレスが割り振られるかわからなかったり、ローカルにDHCPサーバが必要となったりするため、よほどの理由がなければIPアドレスを固定したほうが良いかと思います。
SSH公開鍵の作成
今回はAWSでEC2
接続する際に使っている秘密鍵を使いまわしてローカル接続時にも同じ秘密鍵で接続できるようにしたいので、EC2
接続する際に使っている秘密鍵から公開鍵を生成しておきます。
ssh-keygen -y -f [キーペア名].pem
上記コマンドを実行して出力される結果を控えておきます。(以下出力例)
ssh-rsa AAAAB3NzaC1(以下略)==
もし、Windows
でコマンド実行が難しかったり、生成するのが面倒であれば、EC2
の/home/ec2-user/.ssh/authorized_keys
ファイルに記載されている公開鍵情報を控えて使っても問題ありません。
user-dataの作成
user-data
もAWSのドキュメントに記載されている内容を基に作っていきます。
但し、ドキュメントに記載されている内容そのままでは使い勝手が悪いため、以下について追加でuser-data
に盛り込んでおきます。
SSH公開鍵認証の設定
ドキュメントに記載されている設定では黒いコンソール画面からのログインしか許可されず、リモートからのSSHログインができないため、先程出力させた公開鍵の情報を追加し、SSHログインできるようにしておきます。
ssh_authorized_keys
の項目を追加し、後述する設定のように行頭にハイフンとスペースを入力した後、ssh-keygen
コマンドで出力した結果かEC2
のauthorized_keys
ファイルに記載されている公開鍵をそのままコピペすればOKです。
もし複数authorized_keys
を登録したい場合は、改行して同じ書き方で記載すれば複数登録できます。
DNSの設定
ドキュメントに記載されている設定ではDNS
の設定が行われず、yum
等によるパッケージインストールも行えないので、以下のQAを参考にuser-data
に盛り込んでおきます。
設定方法として2つ紹介されていますが、今回は1ファイルの設定だけで済むオプション2の方法を盛り込み、ifcfg-ethX
の修正のみで設定したいと思います。
Amazon Linux 2
はRHEL
ベースですがNetworkManager
が使われておらず、nmcli
コマンドが使えないので/etc/sysconfig/network-scripts/ifcfg-eth0
ファイルに設定を無理やり追加します。
カーネルアップグレード
2023年1月現在、AWSでAmazon Linux 2
のEC2を作成する際、Kernel 4.14
とKernel 5.10
が選択できますが、後述のダウンロードページからダウンロードできるイメージはKernel 4.14
のイメージとなります。
Kernel 5.10
のイメージはダウンロードできないようなので、kernel 4.14
で起動した後、amazon-linux-extras
コマンドでkernel 5.10
をインストールしたいと思います。
Python3インストール
Kernel 4.14
版のAmazon Linux 2
にはPython
の2系バージョンしかインストールされておらず、Ansible
でAmazon Linux 2
の管理対象マシンに接続すると、Python3
がインストールされていないため実行できないと言ったエラーが表示されます。
Kernel 5.10
版のAmazon Linux 2
の場合はPython
の2系バージョン、3系バージョンともにインストールされていますが、前述のようにKernel 4.14
からamazon-linux-extras
でKernel 5.10
をインストールした場合はPython3
はインストールされません。
そのため、Python3
のインストールとpython3
に対するシンボリックリンクの作成を行います。
最終的なuser-data設定
上述した設定を盛り込んだ最終的なuser-data
の設定が以下となります。
#cloud-config
#vim:syntax=yaml
users:
# A user by the name `ec2-user` is created in the image by default.
- default
ssh_authorized_keys:
- ssh-rsa AAAAB3NzaC1(以下略)==
chpasswd:
list: |
ec2-user:[コンソール接続用パスワード]
# In the above line, do not add any spaces after 'ec2-user:'.
runcmd:
- egrep "^PEERDNS=" /etc/sysconfig/network-scripts/ifcfg-eth0 > /dev/null 2>&1 || echo "PEERDNS=yes" >> /etc/sysconfig/network-scripts/ifcfg-eth0
- egrep "^DNS1=" /etc/sysconfig/network-scripts/ifcfg-eth0 > /dev/null 2>&1 || echo "DNS1=8.8.8.8" >> /etc/sysconfig/network-scripts/ifcfg-eth0
- egrep "^DNS2=" /etc/sysconfig/network-scripts/ifcfg-eth0 > /dev/null 2>&1 || echo "DNS2=8.8.4.4" >> /etc/sysconfig/network-scripts/ifcfg-eth0
- systemctl restart network
- amazon-linux-extras install -y kernel-5.10
- amazon-linux-extras install -y python3.8
- cd /usr/bin
- ls python3 > /dev/null 2>&1 || ln -s python3.8 python3
- reboot
runcmd
により、上述した以下の操作を行うよう設定しています。
- 行頭に
PEERDNS=
を含む行がなければPEERDNS=yes
を追加 - 行頭に
DNS1=
を含む行がなければDNS1=8.8.8.8
を追加 - 行頭に
DNS2=
を含む行がなければDNS2=8.8.4.4
を追加 - 次手順でリポジトリアクセスできるようにするためにネットワーク再起動
-
amazon-linux-extras
リポジトリからkernel-5.10
をインストール -
amazon-linux-extras
リポジトリからpython3.8
をインストール - 次手順で
python3
のシンボリックリンク作成を行うので/usr/bin/
に移動 - カレントディレクトリ(
/usr/bin
)にpython3
が存在しなければpython3
のシンボリックリンクを作成 - 新しいカーネルで立ち上げるため再起動
また、コンソール接続を行わないのであればchpasswd
以下の内容は消してしまっても良いですが、SSH接続できなかったときの確認用に設定しておいたほうが良いです。(そもそもテスト目的でガチガチにする必要も無いので)
seed.isoの作成
先程作成したmeta-data
、user-data
を含んだISOファイルを作成します。
最終的にはVirtualBox
でISOイメージを指定して読み込ませるだけなので、名前は任意で問題ありませんが、AWSのドキュメントに沿って今回はseed.iso
という名前で作成します。
ISOイメージの作成はmkisofs
コマンド等でもできますが、AWSのドキュメントではgenisoimage
というコマンドで行っているため、そちらで作成します。
もしコマンドがインストールされていなければパッケージインストーラでインストールしてください。
genisoimage -output seed.iso -volid cidata -joliet -rock user-data meta-data
Amazon Linux 2 VMイメージのダウンロード
Amazon Linux 2
のVMイメージを以下のURLから取得します。
仮想化ソフトごとにディレクトリが分かれているので、今回の場合はvirtualbox
ディレクトリ配下のamzn2-virtualbox-2.0.YYYYMMDD.0-x86_64.xfs.gpt.vdi
をダウンロードします。
尚、ここでダウンロードしたVMイメージがそのままローカル仮想マシンの仮想ディスクとして使われるため、cloud-init
による初期設定がうまく行かなかった場合に備えて、ダウンロード後、別名でバックアップしておくことをお勧めします。
VirtualBox仮想マシンの作成
準備したファイルを使って、LinuxのVirtualBox
でAmazon Linux 2
の仮想マシンを作成していきます。
「新規」より任意の名前、マシンフォルダー、タイプ、バージョンを指定します。
タイプは「Linux」、バージョンは「Red Hat (64-bit)」を指定してください。
ハードディスクは先程ダウンロードしたvdi
ファイルを指定する必要があるため、「すでにある仮想ハードディスクファイルを使用する」にチェックを入れ、右側のフォルダマークを選択します。
以下のようにハードディスク選択画面が表示されるため、「追加」より先程ダウンロードしたイメージパスを選択すると先程の画面に戻るので「作成」を行います。
作成された仮想マシンの「設定」より、「ストレージ」→「ストレージデバイス」→「コントローラー: IDE」の空ディスクから、ディスクマークを選択します。
選択画面より、「仮想光学ディスクの選択/作成」を選択し、先程作成したseed.iso
を選びます。
また、ネットワーク設定もデフォルトだとNAT
となっており、直接接続できないので、「ネットワーク」→「アダプター1」から割り当てを「ブリッジアダプター」にしておきます。
これで設定が完了したので、起動してログイン画面が表示されれば成功です。
SSHでの接続確認
EC2
への接続でも使用しているSSH鍵ファイル(PEMファイル)を使ってローカルのAmazon Linux 2
へも接続できるか確認してみます。
初回接続時、フィンガープリントの登録が聞かれますが、yes
で進みます。
ssh -l ec2-user -i [秘密鍵ファイル] [Amazon Linux 2のIPアドレス]
パスワードが聞かれず接続できれば成功です。
もしSSH接続できなかったりする場合はVirtualBox
のネットワーク設定やローカルのネットワーク設定を見直してみてください。
SSHのプロンプトは表示されるけど接続できない場合はuser-data
ファイルを確認してみてください。
尚、仮想マシンを作り直す場合、vdi
ファイルも新しくする必要があるので、再度ダウンロードするか、予めコピーしておいたvdi
ファイルから戻して再度やり直してください。
VirtualBoxスナップショットの確認
作成した仮想マシンできちんとVirtualBox
のスナップショット機能が使えるか確認してみます。
一旦仮想マシンを電源オフして、「スナップショット」から「作成」で適当なスナップショット名でスナップショットを作成します。
再度仮想マシンを起動させ、適当にファイルを作成した後、シャットダウンして、先程作成したスナップショット名を選択し、「復元」を行います。
改めて仮想マシンを起動させ、先程作成したファイルが無ければスナップショット機能も無事使えることが確認できました。
おわりに
DNS周りの設定は大変でしたが、AWS公式のドキュメントも用意されているため、比較的簡単にローカル環境に仮想マシンを作成できたのではないかと思います。
AWS上の他サービスと連携が必要な場合は今回の手順だけではできませんが、AWS上で動かしているEC2と全く同じとはいかずとも、今回の構築によりEC2
をローカルで実行できるようになったのは大きかったです。
AWS環境で作ったり壊したりするとお金がかかるので、私のようにEC2
に対するAnsible
を作成しているような方はぜひともローカル環境にAmazon Linux 2
の環境を作っておくと良いと思います。