Open6

中古PCを買って遊んでいるのでその記録

白山風露白山風露

仮想化環境で遊んでみたい。kvmとかk8sとか色んなコンテナランタイムとか。

という訳で中古PCを買うことにした。

購入したのはHP Elitebook X360 1040 G5の『Core™ i7-8650U vPro、メモリ32GB、1TB SSD 搭載 LTEモデル』
要するに最上位モデル。
メーカー希望小売価格は362,780円だが当然中古価格なので送料込み60,850円で購入した。スペックの割には十分安いと思うが、おもちゃにしては高いとも言える。
ネット通販の中古市場をざっと眺めてみた感じ、同等のスペックの物の中では最安に近かったと思う。一つのショップが同じ物をいくつも販売しているようなので、恐らくどこかの企業がまとめて購入してまとめて売ったものではないだろうか。

白山風露白山風露

せっかくなので今まで使ったことのない技術をたくさん使っていきたい。

まずOSはNixOSを使うことにする。どんなOSかはさっぱり分からんがなんか激推ししてる人がいるし。
まあ最悪うまく行かんかったら別のOS入れればいいでしょ、の精神で行く。

Nixはパッケージマネージャの名前ということで、公式のダウンロードページに行くとまずパッケージマネージャのダウンロード方法が書いてある。少し下にNixOSがあるので、ここからISOイメージをダウンロードする。

ちなみにGraphical ISO imageにはGNOME版とPlasma Desktop版があるがここは敢えてMinimal ISO imageを入手した(茨の道を……)

白山風露白山風露

普段使いのPCはWindowsなので、Rufusを入れてUSBにISOを焼く。
購入したPCは起動直後にESCでBIOSメニューが開けるので、ブートオプションを選択してUSBから起動。
rootでログインした状態で起動される。 nixos-help を実行するとマニュアルが表示される(内容はここにあるものと同じ)ので、それを手掛かりにインストールしていくことにする。

Minimal ISO imageを選んだので当然GUIはない。Manual Installationの指示に従っていく。

まずはネットワーク

インストール中にダウンロードを実行するのでネットワークは必須。LANケーブル繋いでもいいんだけどめんどくさいし、Wi-Fiはついているのでそっちを使いたい。
マニュアルに書いてある通り

systemctl start wpa_supplicant

をしてから

wpa_cli

を実行しても、

Could not connect to wpa_supplicant: (nil) - re-trying

というエラーが表示される。悲しい。

iwconfig で表示されるインターフェイスは lowwan0 のみ。LTEモデルなので(カード刺してないけど) wwan0 はそのインターフェイスのはず。つまりWi-Fiのデバイスを認識していない。悲しみ。

これは早速詰んだかと思ったが、再起動してインストールメディアのブートメニューを眺めたらファームウェア更新的なやつがあったので実行。そしたら wlp108s0 という名前でWi-Fiインターフェイスが生えてきた。勝ったな風呂入ってくる。

白山風露白山風露

パーティション作成

今度こそマニュアルの指示通り wpa_cli が起動できたので自宅Wi-FiのSSIDとパスワードを入れていく。特に問題なく接続できたので続いてPartitioning and Formattingの項目に移る。Legacy Bootを選ぶ必要はないので普通にUEFI (GPT)の方をやっていく。

で、最初マニュアルに書いてある通りのコマンドをそのまま実行してしまったのだが、あれよく考えたらUSBからブートしてるけど/dev/sdaってどれ?と思ったら普通にUSBを破壊していた。一度シャットダウンしてRufusでUSBにインストールメディアを焼き直してWi-Fiの設定までやりなおし。 /dev/ の中を眺めてPC内臓ストレージを探す。nvme0n1がいたのでこいつやん、ということでこっちにパーティションを作っていく。もちろん中に入っているWindowsは死にます。

そこから先は特に問題なくフォーマットまで終わらせる。 nvme0n1 に作成したパーティションは nvme0n1p1nvme0n1p2nvme0n1p3 という名前になっているのでそこだけ注意した。

インストール

ここまで来たらようやくインストールという訳で、Installingの節にあることをやっていきます。ルートパーティションを /mnt にマウント。ブートパーティションを /mnt/boot にマウント。
メモリ少なかったら swapon しろと書いてあるけど、32GBもあって足りなくなることないやろガハハ、ということでスキップ(実際別に問題はなかった)。

nixos-generate-config --root /mnt

を叩くと /mnt/etc/configuration.nix が出来上がるので nano /mnt/etc/configuration.nix で編集。最近のミニマル環境みんなnano積んでてどちらかというとvimmerな私は慣れねーって言いながら編集する。気が付いたら:とか入力してて困る。多分vimに染まってなければnanoの方が直感的なんだろうけどね。まあ別にvim入れてもいいんだけど、どうせだから設定は最低限のままでといった感じ。

ここらへん何をどう編集したかあんまり覚えてない。変な設定入れて元に戻したりとかも結構やっているし。
とりあえず最初はほぼデフォルトのままで nixos-install を実行して再起動。で、案の定Wi-Fiが使えないのでまたインストールUSBの方からブートしなおして、

networking.networkmanager.enable = true;

みたいな設定を有効にして nixos-install をやり直すみたいなことをしたと思う。この手順で良かったのかはよく分からないけど nmcli が使えるようになったのでOK。

nmcli device wifi connect <SSID> password <PASSWORD>

でWi-Fiに接続できたので後はインストールUSBのwpa_supplicantに頼らなくてもダウンロードとかできるという訳でインストールUSBはここでお役御免。一応最低限インストールはできたと言ってもいいだろう。

白山風露白山風露

色々初期設定

Wi-Fiより先にやったかもしれないがデフォルトだとキーマップが英字キーボードなので

console.keyMap = "jp106"

に変更。設定反映のためここから先は適宜

nixos-rebuild switch

を挟んでいく。

time.timeZone = "Asia/Tokyo";

も追加。あと普段使いのPCの方で作業したくなったので

users.users.kazatsuyu = {
  createHome = true;
  isNormalUser = true;
  extraGroups = [ "wheel" ];
  group = "users";
  home = "/home/kazatsuyu";
  uid = 1027;
};

こんな感じでユーザーを作って、

services.openssh = {
  enable = true;
  settings.PasswordAuthentication = false;
  settings.KbdInteractiveAuthentication = false;
};

OpenSSHサーバーを動かす。で、

curl https://github.com/kazatsuyu.keys > /home/kazatsuyu/.ssh/authorized_keys

することでGitHubに登録した自分の鍵が使えるようになります。後は適切にパーミッションなどを変更してやればsshでログイン可能に。LAN内のDHCPも弄って固定IPアドレスを振っておけば普段使いのPCから作業ができるようになる。

HP Elitebookのディスプレイは180度回転してタブレットにもなる素敵ディスプレイだけど、ここまで来たらとりあえず不要なので閉じてみたらハングしてしまったので、

services.logind.lidSwitchExternalPower = "ignore";

を追加。画面閉じたままでも動くようになったのでsshで作業しやすくなった。

白山風露白山風露

KVMの構築

ここからはKVM。ぶっちゃけ全然わからんので色々見ながら手探り状態。

boot.kernelModules = [ "kvm-amd" "kvm-intel" ];
boot.extraModprobeConfig = "options kvm_intel nested=1";
virtualisation.libvirtd.enable = true;

とか入れていく。いらん設定もありそう。CPUはIntelだし kvm-amd とかいらんのでは?
よくわからんのでとりあえず書いてある設定コピペしたけど、VMの中でVMを起動するみたいなことしないなら nested=1 も多分いらんな。
まあこの辺は後で見直すことにする。

CLIでKVM関連の操作をするときは virsh というコマンドを使うらしい。とりあえずネットワークが必要っぽいので

virsh net-start default

してみる。この状態で virsh net-list を叩くと

 Name      State    Autostart   Persistent
--------------------------------------------
 default   active   no          yes

という結果が得られるので、これ再起動したら止まってるだろうなという感じである。
案の定だったので常に起動する方法を探す。 configuration.nix に書くとかできないのかなと思ったが無いようなのでググって方法を探して、

virsh net-autostart default

こうしたら AutoStart=yes になったので良し。
とりあえず特に仮想ネットワークを増やす必要に迫られてないのでdefault一個でいいだろう。

で、KVMの上に何を置くかということなのだが、とりあえずk8sがやりたいので関連の情報を探ってたらk3sというやつがあることを知る。エッジコンピューティング用に機能を削った軽量なk8sということで、フルスペックのk8sとどっちが楽なんかは知らないけどそういうコンセプトは好きなのでじゃあとりあえずこれやってみようかな。どんなディストロで動かしてもいいみたいだけどk3s専用ディストロのk3osという物があるらしく、良さそうなのでやってみる。
https://github.com/rancher/k3os/releases/latest からisoをダウンロード。
ググってでてきたここらへんの記述とかを参考にインストールをやっていく。

/var/lib/libvirt/images にVMイメージを置くのが一般的っぽいので、ディレクトリを作成して移動。参考情報そのままファイル名だけ変えて、

qemu-img create -f qcow2 k3os.qcow2 10G

を実行すると無事イメージが出来上がる。

virt-install コマンドが必要らしいがいないので、探してみると virt-manager というパッケージに含まれているらしい。

environment.systemPackages = with pkgs; [
  virt-manager
];

これで virt-install が使えるようになる。
virt-install はオプションが多くてよく分からんので k3os-install という名前でシェルスクリプトを用意して、その中にコマンドを書くことにした。

何回かエラーが出たのでやり直して、最終的にこんな感じに。

k3os-install
#!/bin/sh

virt-install \
    --name k3os \
    --virt-type kvm \
    --disk k3os.qcow2,format=qcow2 \
    --ram 1024 \
    --network network=default \
    --graphics none \
    --cdrom k3os-amd64.iso \
    --console pty,target_type=serial \
    --os-variant generic

virt-installのオプションは色々あって難しいので今後調整する必要はありそうだけどこれでk3osのインストールが始まる。
対話式にいくつか情報を入力していくとすぐにインストールが終わる。クラウドから初期化情報を取得したりGitHubから公開鍵を自動で取ってきてくれたりするらしいけどとりあえずスキップ。NixOSのインストールよりはずっと簡単にインストールが終わった。
勝手に再起動して rauncher というユーザー名とインストール中に入力したパスワードでログインできる。

ログインすると

Welcome to k3OS!

Refer to https://github.com/rancher/k3os for README and issues.

The default mode of k3OS is to run a single node cluster. Use "kubectl"
to access it. The node token in /var/lib/rancher/k3s/server/node-token
can be used to join agents to this server.

というメッセージが表示された。 kubectl コマンドが使えるようになっているので実行してみるとよくあるヘルプが出てくる。とりあえずうまく行ったようだ。次はkubectlを使って何かのコンテナを立てることを目標にする。