動機
WebarenaやさくらのVPSがすごいいい.
自分でもVPSつくりたい.
Webarenaは,KVMでインスタンスが建てられているのか...
KVMにチャレンジするぞ.
ってことで毎回virt-managerで動かすのは面倒なので,完全CLIでインスタンスを建てます.
VPSのようにインスタンスを建てた段階でssh
もできるようにします.
一番下の参考文献のまとめの記事ですので,
そちらもみていただけますと幸いです.
本記事で作成したスクリプトは,Githubに載せています.
注意事項
何をやってもvirsh console vm名
で接続することができませんでした.
なので,初期設定でsshが通るところまでやっています.
動くまで母艦の初期化を2桁くらいしました.
ubuntuの初期設定だけは早いと思うので誰か雇ってください.(Ansibleでやれ)
環境
母艦(ホスト)
- Ubuntu Desktop 18.04.6 LTS
- CPU : intel
- RAM : 16GB
- Ethernet : 有線(esp2s0)
macから母艦にsshをして構築.
Ubuntu Serverでも大丈夫だと思います.
事前準備
VMを構築する下準備を行なっていきます.
ライブラリインストール
kvmに必要なライブラリのインストールです.
$ sudo apt-get install -y qemu-kvm libvirt-bin virtinst bridge-utils cpu-checker libguestfs-tools
そもそも仮想化,kvmができるPCなの?
仮想化の確認
出力が0以上であれば,okです.
$ egrep -c '(vmx|svm)' /proc/cpuinfo
8
kvmの確認
kvm-ok
で確認します.
$ sudo kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used
$ sudo nano /etc/group
で,kvm,libvirt-qemuに自分のユーザ名登録
(usermodでもいい.僕はトラウマがあるので直でいじってます.)
##libvirtdの確認
activeになっていればok
$ sudo systemctl status libvirtd
なっていない場合
$ sudo systemctl start libvirtd
$ sudo systemctl enable libvirtd
をした後に,sudo systemctl status libvirtd
でactiveになっているか確認してください.
ブリッジ接続編
僕はrootユーザでやりました.
別にsudo
でやっても大丈夫です.
以下,全てsudoが必要です.
補足
言語を英語にしているため,消去するものが 'Wired Connection 1'となっています.
日本語では,新規接続1 となります.
# bridge-br0を作成
$ nmcli connection add type bridge ifname br0
Connection 'bridge-br0' (98bfb899-c06d-4421-b2c8-bec80647ac4d) successfully added.
# bridge-br0のスパニングツリーを無効にする
$ nmcli connection modify bridge-br0 bridge.stp no
# スパニングツリーが無効になっているか確認
$ nmcli connection show bridge-br0 | grep bridge.stp
bridge.stp: no
# bridge-br0の設定.IPアドレスは,自分のipを指定(僕の場合だと,enp2s0)
# ssh上で作業しているとここでsshが切れてしまうので,rebootをしてsshを繋ぎ直す
$ nmcli con modify bridge-br0 ipv4.method manual ipv4.address "your_ip_address/xx" ipv4.gateway "your_gateway" ipv4.dns "your_dns" &&reboot
#rebootしたので,sudoつけるかsudo suでrootユーザになってください.
$ nmcli connection add type bridge-slave ifname enp2s0 master bridge-br0
# 不要になった 'Wired connection 1' の削除
$ sudo nmcli connection delete 'Wired connection 1'
Connection 'Wired connection 1' (ced9c7da-9541-39c8-8ced-7b9696bbd0aa) successfully deleted.
# 確認
$ nmcli connection show
NAME UUID TYPE DEVICE
bridge-br0 98bfb899-c06d-4421-b2c8-bec80647ac4d bridge br0
bridge-slave-enp2s0 75c0955b-21d5-486b-a37b-050a08fef62d ethernet enp2s0
virbr0 31854afe-f628-4915-8622-0f1e47188f18 bridge virbr0
Storage Poolの設定
$ sudo virsh pool-list
Name State Autostart
-------------------------------------------
$ sudo groupadd shared
$ sudo nano /etc/group
$ sudo mkdir -p /home/shared/images/
$ sudo chown -R root:shared /home/shared/
$ sudo chmod -R o-rwx /home/shared/
sudo virsh pool-define-as default dir --target /home/shared/images/
$ virsh pool-start default
Pool default started
$ virsh pool-autostart default
Pool default marked as autostarted
$ virsh pool-list
Name State Autostart
-------------------------------------------
default active yes
VM構築編
こちらでは,VMを実際に構築していきます.
virt-builder編
,virt-install編
の2種を別々に詳しく説明していきますが,
別々に実行していくのは,面倒なので一発でVMを構築したい!
のパートで僕が今使っているスクリプトを載せています.
結局どれがいいねん!って方は,一発でVMを構築したい!
のパートをみていただければ良いと思います.
virt-builder編
root(suユーザ)でもsudoでもok
Host名とパスワードが一緒の理由は,
友人にもVMを振る際に毎回Host名を考えるのがめんどうくさい,
既存のVMと重複するとエラーで止まってしまう問題があり,
ランダムにして揃えることでsudoもすぐ使えるようにしています.
(セキュリティが甘々なので後で改善予定です.)
#!/bin/sh
USERNAME=ubuntu
PASSWORD=$(more /dev/urandom | tr -d -c '[:alnum:]' | fold -w 10 | head -1)
sudo virt-builder ubuntu-18.04 \
--format qcow2 \
--hostname $PASSWORD \
--timezone Asia/Tokyo \
--append-line '/etc/default/grub:GRUB_CMDLINE_LINUX="console=ttyS0,115200"' \
--run-command 'update-grub' \
--root-password password:password \
--firstboot-command " \
bash -c 'echo -n > /etc/machine-id' \
dpkg-reconfigure openssh-server; \
useradd -m -G sudo,operator -s /bin/bash $USERNAME; \
echo '$USERNAME:$PASSWORD' | chpasswd; \
chown -R $USERNAME /home/$USERNAME; \
perl -pi -e 's/^%sudo.*$/%sudo ALL=(ALL:ALL) NOPASSWD: ALL/' /etc/sudoers; \
perl -p -i.bak -e 's%https?://(?!security)[^ \t]+%http://jp.archive.ubuntu.com/ubuntu/%g' /etc/apt/sources.list; \
reboot \
" \
-o /home/shared/images/ubuntu_$PASSWORD.qcow2
公開鍵認証をするときは,以下の四行を追加してください.
これは,あからじめ母艦で作成した公開鍵をゲストOSにcopyし,sshする側で秘密鍵を持つことで,鍵認証ができます.
--mkdir /home/$USERNAME/.ssh \
--copy-in $HOME/.ssh/hawaii_vm.pub:/home/$USERNAME/.ssh \
--move /home/$USERNAME/.ssh/Your_key.pub:/home/$USERNAME/.ssh/authorized_keys \
--chmod 0700:/home/$USERNAME/.ssh \
あとは,権限をつけてあげて,実行しましょう.
$ sudo chmod 755 virt_bulid.sh
$ ./virt_build.sh
virt_builder
の中身自体は,読めばわかると思うのですが,
bash -c 'echo -n > /etc/machine-id'
とreboot
って何やってんねんとなりますよね.
ここは,VMを作成するまでは良いが,何台立てても,全て同一のIPをもらってしまう問題がありました.
それの解決になります.
なにやら,IPは,/etc/machine-id のidによって決まっているらしく,
このidが同じだと,同一のIPが振られるそうです.
そのため,echo -n
をすることで,/etc/machine-idを空にして,
再起動(reboot)によってidを新しく作成することで,違うIPをもらっています.
(僕の環境では,どうやってもvirsh console
ができなかったので,直接sshをできるように
ここまで整えています.)
僕の作成した順番でやる場合には,
virt_installの時に,ホスト名が必要であるため,
sudo virsh list
で作成されたイメージの名前を確認しておいてください.
(後半でbuildとinstallを一緒のスクリプトで作成しています.)
virt-install編
出力をみたいときは,最後に-d
をつけてみてください.
#!/bin/sh
echo 'Write Hostname'
read hostname
sudo virt-install \
--name $hostname \
--hvm \
--virt-type kvm \
--ram 2048 \
--vcpus 2 \
--arch x86_64 \
--os-type linux \
--os-variant ubuntu18.04 \
--boot hd \
--disk path=/home/shared/images/ubuntu_$hostname.qcow2 \
--network bridge=br0 \
--graphics none \
--serial pty \
--console pty
virsh list
または,./virt_build.sh
の実行時の出力でホスト名(パスワード)をコピーしてから実行しましょう.
$ sudo chmod 755 virt_installer.sh
$ ./virt_installer.sh
実行時にWrite Hostname と出力が出ると思うので,コピーしたホスト名をペーストしてエンターを押しましょう.
これで,VMのコンソールに飛びます.
(コンソールに飛ばないようにする設定もできますが,sshも通らない,
IPもわからない状態ですので,注意をお願いします.)
ユーザ名:ubuntu
パスワード:ホスト名
でログインできれば大丈夫です.
ログイン後にip addr
でipを確認し,
$ sudo apt update && sudo apt upgrade -y
$ ssh ubuntu@your_hostname.local
or
$ ssh ubuntu@your_ip_address
を実行します.
sudoのパスワードはホスト名です.
sshのバージョンが古いのか,この段階だとsshが通らないので,
aptの更新をしてからsshで接続することできればokです.
お疲れ様でした.
一発でVMを構築したい!
上記の例だと,毎回ホスト名を確認する工程があります.
僕はめんどくさがり屋なので,buildとinstallをまとめることで楽をしました.
単純にシェルスクリプトでまとめただけです.
#!/bin/sh
USERNAME=ubuntu
PASSWORD=$(more /dev/urandom | tr -d -c '[:alnum:]' | fold -w 10 | head -1)
echo 'virt-builder'
sudo virt-builder ubuntu-18.04 \
--format qcow2 \
--hostname $PASSWORD \
--timezone Asia/Tokyo \
--append-line '/etc/default/grub:GRUB_CMDLINE_LINUX="console=ttyS0,115200"' \
--run-command 'update-grub' \
--root-password password:password \
--firstboot-command " \
bash -c 'echo -n > /etc/machine-id' \
dpkg-reconfigure openssh-server; \
useradd -m -G sudo,operator -s /bin/bash $USERNAME; \
echo '$USERNAME:$PASSWORD' | chpasswd; \
chown -R $USERNAME /home/$USERNAME; \
perl -pi -e 's/^%sudo.*$/%sudo ALL=(ALL:ALL) NOPASSWD: ALL/' /etc/sudoers; \
perl -p -i.bak -e 's%https?://(?!security)[^ \t]+%http://jp.archive.ubuntu.com/ubuntu/%g' /etc/apt/sources.list; \
reboot \
" \
-o /home/shared/images/ubuntu_$PASSWORD.qcow2
echo 'virt-install'
sudo virt-install \
--name $PASSWORD \
--hvm \
--virt-type kvm \
--ram 2048 \
--vcpus 2 \
--arch x86_64 \
--os-type linux \
--os-variant ubuntu18.04 \
--boot hd \
--disk path=/home/shared/images/ubuntu_$PASSWORD.qcow2 \
--network bridge=br0 \
--graphics none \
--serial pty \
--console pty
$ sudo chmod 755 make_vm.sh
$ ./make_vm.sh
でコンソールまで接続できます.
$ sudo apt update && sudo apt upgrade -y
ログイン確認後にaptの更新を行った後,
ip addr
でIP確認を行い,sshが通っていることが確認できれば,完了です.
VMを破壊するとき
$ sudo virsh destroy VM_name
$ sudo virsh undefine VM_name
問題点
僕がこれをやっている段階でどうしても解決できなかった2点を挙げます.
原因等ありましたら教えていただけますととても嬉しいです.
二回目のコンソール接続ができない
virt_installの時点でのコンソールの接続ができるのですが,一度コンソールからexitして,
virsh console
で入り直そうとすると動きません.
なぜでしょうか.解決策を教えていただけると助かります.
参考
https://knqyf263.hatenablog.com/entry/2014/01/13/200509
ゲストOSのipを母艦から見れない問題
直接物理NICからIPをもらっているためsudo virsh net-dhcp-leases
では,IPを確認できません.
なので,コンソール上で一回IPの確認,sshの疎通が確認できないと使用できません.
同じように構築した場合は気をつけてください.
さいごに
ここまでご覧いただき,ありがとうございます.
以上で,KVMを用いてubuntu18のVMを立てることができました.
今後は,ubuntu18のサポートが終わってしまうので,
母艦をubuntu20,VMもubuntu20にしてやってみようと思います.
次回もよろしくお願いします.
参考文献
ほぼ以下のサイトのまとめです.
こちらもみていただけますと幸いです.