"Articles are my own, not views of my employer"

就活や転職に役立てるためTips投稿や競プロwriteupを行いプレゼンスを高める自分用備忘録です

リモートからOSをインストールする

概要

通常,OSをインストールするにはCDやUSB等のメディアを直接PCに接続し,その場で設定を行う. もちろん,インストール途中のPCにはSSHできないためリモートからこれらの作業を行うことはできない.

本記事では,すでにSSH接続できる遠隔地のPCに対し,新たにOSをインストールし,デュアルブートの形で設定する方法を解説する.

おおまかな流れとしては以下のとおりである.

  1. 仮想マシンを使って新たにOSをインストールする
  2. 仮想マシンイメージをOSをインストールしたいパーティションに移す
  3. GRUBに登録する
  4. 起動する

背景

ローカル環境をLOCAL,リモートの環境をREMOTE,新たに作成する環境をNEWとする. なお,本記事とは直接関係ないが,中間ノードMIDが存在し,REMOTEはMID経由でしかアクセスできない. MID->REMOTEのアクセスは,mDNSを用いてIPアドレスの解決を行うことで実現している.

いま,REMOTEにSSHでき,システムが稼働中であるとする. REMOTEに存在する外部ストレージに新たにOSをインストールし,それを起動し,アクセスしたいとする. (同一ストレージデバイスの異なるパーティションに対しても今回は未検証だが,同一手順でできると思われる.この際はresize2fsで稼働中のファイルシステムを縮小し,新たなOS用の領域を確保する必要がある.) 現在稼働中のOSは/dev/sdaにあり,新たにインストールするOSは/dev/sdb1にインストールするとする.

実際の手順

仮想マシンのインストール

まずはREMOTE内でKVMを使って新たに仮想マシンを作成する. このとき,作成する仮想マシンのストレージ容量はあまり大きくならないように(例:8GB)する.

この例ではUbuntu16をインストールする.

REMOTE$ sudo virt-install \
--connect=qemu:///system \
-n ubuntu16 \
-r 1024 \
--disk path=new.img,size=8,format=raw \
--vcpus=1 \
--os-type linux \
--network network=default \
--nographics \
--extra-args='console=tty0 console=ttyS0,115200n8' \
--location http://ftp.jaist.ac.jp/pub/Linux/ubuntu/dists/xenial/main/installer-amd64/

ここで作成したOSが,新たに(仮想マシン上ではないく,ネイティブに)インストールするOSとなる. 注意点としては,

  1. swapを作成せずプライマリパーティションをひとつだけ作成する
  2. LVMを使わない

である.

なお,仮想マシンの保存先としてファイルを指定しているが,これを/dev/sdb1としてはいけない. インストール中に分かると思うが,仮想マシンでは仮想ストレージを作成するためにこれを直接起動することはできないからである.

インストールできたらシャットダウンする.

(オプション)シリアルコンソールを有効化する

Ubuntu16の場合はコンソール接続がそのままではできないので,インストール後に直接イメージファイルを編集して,コンソール接続できるようにする必要がある.

以下の記事に詳しい.

Ubuntu 16.04 LTS : KVM : 仮想マシン作成#1 : Server World

仮想マシンをセットアップ

仮想マシンを起動し,セットアップを行う.

SSHサーバのセットアップ

NEW$ sudo apt install openssh-server

.ssh/authorized_keysに公開鍵を登録する. なお,仮想マシンIPアドレスは,

REMOTE$ virsh net-dhcp-leases default

で分かる.

(オプション)mDNSの設定

MIDからhostname.localでアクセスできるようにmDNSの設定を行う.

NEW$ sudo apt install avahi-daemon

自動シャットダウンスクリプトを仕込む

後ほどNEWを仮想マシンを経由せずに起動することになる. この際,ネットワークにエラーが発生した場合SSHで接続できず,手出しができなくなってしまう. そのため一定時間で自動的にシャットダウンするスクリプトを仕込む. 直接NEWにアクセスできなくとも,WOLを利用してMIDからREMOTEを起動することはできるのである.

/etc/rc.localにスクリプトを作成し,置いておく. 例えば10分後に自動でシャットダウンをする動作を記述. もちろん,無事にSSHできた場合はこのプロセスを殺す.

ネットワークの設定

OSごと異なる環境に移すことになるのでネットワークにも不調が出る(出た). 今回の問題は/etc/network/interfacesの記述が間違っていたことだった.

現在,

NEW$ cat /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto ens2
iface ens2 inet dhcp

となっているものを,

NEW$ cat /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eno1
iface eno1 inet dhcp

と変更する.

なお,"eno1"の見つけ方であるが,これは何度か起動,自動シャットダウンを繰り返して見つけることになる. 具体的には件のシャットダウンスクリプト内部に,dmesgをダンプして保存する処理を仕込み,シャットダウンする. その後REMOTEが起動したら,NEWのパーティションをマウントし,ダンプされたファイルを確認する.

dmesg中の以下のような箇所を発見する.

[    9.136448] e1000e 0000:00:19.0 eth0: registered PHC clock
[    9.136450] e1000e 0000:00:19.0 eth0: (PCI Express:2.5GT/s:Width x1) XX:XX:XX:XX:XX:XX
[    9.136452] e1000e 0000:00:19.0 eth0: Intel(R) PRO/1000 Network Connection
[    9.136478] e1000e 0000:00:19.0 eth0: MAC: 11, PHY: 12, PBA No: FFFFFF-0FF
[    9.136923] e1000e 0000:00:19.0 eno1: renamed from eth0

eth0が何にrenameされているか調べれば良い.

外部ストレージ(/dev/sdb)のセットアップ

fdisk等を使い,パーティション/dev/sdb1を作成する.

後から行う強引な方法のために/dev/sdb1をゼロ埋めで初期化する.

REMOTE$ sudo dd if=/dev/zero of=/dev/sdb1

仮想マシンの中身を外部ストレージに移す

まず新たに作成した仮想マシンを起動する.

先程作成した外部ストレージを仮想マシンにアタッチする.

REMOTE$ virsh attach-disk ubuntu16 /dev/sdb1 vdc --live

/dev/sda1の中身をddで外部ストレージにコピーする(!)

NEW$ sudo dd if=/dev/sda1 of=/dev/sdb1

NEWをシャットダウン.

ファイルシステムを直す.

NEWはもともと8GBのディスクに作られていたのでこのままではおかしなことになる. そこでfsckとresizeでファイルシステムを修正する.

REMOTE$ sudo e2fsck -f /dev/sdb1
REMOTE$ sudo resize2fs /dev/sdb2

GRUBをアップデート

新たに作成したOSをGRUBに登録する.

REMOTE$ sudo grub-mkdevicemap
REMOTE$ sudo update-grub

リブート

NEWを起動するようにgrub-rebootを使い調整する. 表示方法は前の記事を参照のこと.

その後rebootし,無事起動してくれることを祈る.