電脳世界のケーキ屋さん

考えの甘い甘党エンジニアがいろいろ書くブログ

KVM ゲストとして Container-Linux を導入する



はじめに

以前の記事で構築した KVM on Gentoo で色々遊ぼうと思う.
今回は手始めに Container-Linux をゲストとして導入する.

なんで Container Linux のインストールをしようと思ったのかは分からない.
でもKVMで構築する上でハマる落とし穴1つずつにハマっていた感じだったので勉強になった.

Container-Linux の管理や, KVMホストの管理については別記事を用意する.

手順

1.OSイメージのダウンロード

この辺りのリリースノート を確認して,
この辺り から stable image をダウンロードする.
ダウンロードしたらチェックサムを確認して bzcat で展開して適当な場所に置いておく.

2.ファイルシステム作成

以下のコマンドでファイルシステムを作成する.
qcow2形式でベースイメージに CoreOS のイメージを利用したファイルシステムを作成したことになる.
いわゆる差分イメージとして作成され, ベースイメージに対する差分が記録されるイメージとなる.

> sudo qemu-img create -f qcow2 -b /osimage/coreos_production_qemu_image.img container-linux00.qcow2

この時作成するイメージの場所は libvirt のプールに登録されている場所が望ましい.
ちなみに差分を破棄したい場合は同じコマンドを打てば良い(再フォーマットされる).

3.ドメイン設定ファイルの作成

virt-install コマンドによってドメインの設定ファイルを作成する.
普段は virt-install と OS のインストールイメージを用いて, ファイルシステムにOSをインストールする必要がある.

Container OS のイメージはインストールイメージではないため, インストール操作を実施する必要はない.
--import オプションを利用することでインストールプロセスをスキップし, 指定したファイルシステムから起動するような設定をすることが可能となっている.

Container OS では後の手順でドメイン設定ファイルを編集する必要があるため, libvirt に直接登録せずに, XML設定ファイルを出力する動作を指定している(print-xml).
ちなみに, 完全なシミュレーション動作ではないため, ストレージの作成などは行われる点に注意.
必要に応じて --dry-run オプションを付与すると良いと考えられる.

sudo virt-install --connect qemu:///system --virt-type kvm --import \
  --name container-linux00 \
  --ram 2048 --vcpus 2 \
  --os-type linux \
  --disk path=/var/lib/libvirt/images/container-linux00.qcow2,format=qcow2 \
  --nographics --network bridge=privbr \
  --accelerate \
  --print-xml | sudo tee /var/lib/libvirt/container-linux/container-linux00/domain.xml

4.ignitionファイルの作成

公式ドキュメント を参考に Ignition config を作成する.
ネットワークの設定とユーザ設定をしておかないと救い用のないホストとなってしまうため注意.

ネットワーク設定

公式ドキュメント通りに設定しておくのが無難. 静的IPを設定する場合は下記のように記述しておく.

"networkd": {
 "units" : [
 {
  "contents" : "[Match]\nMACAddress=XX:XX:XX:XX:XX:XX\n\n[Network]\nAddress=192.168.101.2/25\nGateway=192.168.101.126\n",
   "name": "10-ens3.network"
 }
 ]
},

[Match] 項で何らかの条件を設定しておかないとループバックインターフェイスにアドレスが付与されて酷い目に会う(経験済み).
前の手順で domain.xml を作成した時点でインターフェイス物理アドレスは分かるので, それを条件に設定しておくと良い.

ユーザパスワードを設定しておきたい

Container OSはデフォルトではユーザに対してのログインを一切許容していない鬼畜仕様である.
公開鍵を登録してSSHログインする方法は幾つか紹介されているのを見かけるが, コンソールログインする設定はなかなか見かけない.
KVMでゲストに対してコンソール接続はできるけどネットワーク疎通が取れないというケースがある.
こういった時にコンソールログインできると便利なので設定しておきたい場合の手順を示す.

passwordHash 項を passwd.users 内のオブジェクトに挿入すれば良い.

抜粋すると以下のような設定となる.

"passwd": {
 "users": [
 {
  "name": "core",
   "passwordHash": "$6$rXw/hoge$60wal<省略>ZAr1",
   "sshAuthorizedKeys": [
    "ssh-ed25519 AAAA<省略>PI6fS alice@Lab_A"
   ]
 }
 ]
},

問題は passwordHash に渡す文字列の作成の仕方である.
これは /etc/shadow 内の暗号化パスワードの表記と全く同じもので, 平文パスワードにソルト値を追加したものをハッシュ化して得られる文字列である.

これを自前で作るのは Perl を使えばワンライナーで作成できる.

# perl -e 'print crypt("password", "\$6\$hogehoge");'

以下の文献を参考にしている.
http://www.unknownengineer.net/entry/2017/08/16/184537
上記のコマンドで得た値をそのまま貼り付ければ, コンソールで接続した際に設定したパスワードで core ユーザにログインできるようになる.

SSHの認証鍵の設定は ssh-keygen によって得られた公開鍵をそのまま貼り付ければ問題ない.
今回は ssh-keygen -t ed25519 の出力を利用した.

5.ドメイン設定ファイルの編集

Container-OS は初回起動自に先の手順で作成した Ignition Config を利用して設定のプロビジョニングを行う.
そのために, 作成した Ignition Config を起動時にゲストのファイルシステムへ転送する必要がある.
qemu はゲスト起動時にファイルを転送する -fwd_cfg オプションがあり, libvirt もこれを利用することができる.

公式ドキュメント通りに下記のコマンドを実行すれば良い.

domain=/var/lib/libvirt/container-linux/container-linux1/domain.xml
ignition_file=/var/lib/libvirt/container-linux/container-linux1/provision.ign

sed -i 's|type="kvm"|type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0"|' "${domain}"
sed -i "/<\/devices>/a <qemu:commandline>\n  <qemu:arg value='-fw_cfg'/>\n  <qemu:arg value='name=opt/com.coreos/config,file=${ignition_file}'/>\n</qemu:commandline>" "${domain}"

1回目の sed によって, ドメインファイルで qemu のオプションを利用できるように設定する.
これを省くと後の libvirt へのドメイン登録時に怒られる.

2回目の sed によって具体的に qemu 実行の際のオプションを設定する.
これにより Ignition Config がゲストの /sys/firmware/qemu_fw_cfg/by_name/opt/com.coreos/config に転送される設定で起動処理が行われる.

-fwd_cfg オプションについての詳しい説明はこの辺りが参考になる.

6.ドメインの登録とゲストの起動及び動作確認

virsh define domain.xml を実行すると libvirt の管理下に置かれる.
virsh start <ドメイン名> で起動可能となる.
ドメイン名は virsh list --allP で確認できる.

起動確認として, 以下を確認すると良いだろう.

  • 設定したアドレスに対して ping が通るか
  • virsh console <ドメイン名> で接続した際にレスポンスがあるか
  • 登録したSSH設定でログイン可能か

いずれかが失敗した場合は Ignition ファイルか ドメイン設定ファイルを再確認する.

ignitionファイルを変更した時

マシンをリセットするだけだと変更は適用されない.
ファイルシステムを作り直すと適用されたのを確認したが, めんどくさい...

既に差分イメージが存在する場合でも下記を実行することでフォーマットされる.

> sudo qemu-img create -f qcow2 -b /osimage/coreos_production_qemu_image.img container-linux00.qcow2

参考文献