これは琉大 Advent Calendar 2020の5日目の記事です。
昨日は未承諾広告※ shangliさんのクラスター計算機を作るときに気をつけたいことでした。
まだまだ琉大アドベントカレンダーは空きがあるので皆さんの参加お待ちしております!!!
学科システム
さて僕たちの学科(琉大情報工・知能情報コース・情報工学専攻)では独自にオンプレ上に構築した学科システムを持っています。学科システムのサーバーの管理はシステム管理チームと呼ばれる学生たちが、自分達自身で行うという方向性です。
現在の学科システムはubuntuベースのサーバーが4台、ファイルサーバーが2台、さくらの専用サーバーが1台という構成になっていて、ubuntuベースの演習用サーバー2つは学生に広く開放しています。
この学科システムでは2015年まではVMWare, 2015年以降はKVMを運用しており、学科サービスや学生演習用・学生が個人で開発するようでVMを動作させることが可能となっています。
KVMの学生ごとの管理
例えばOSの講義では学生がそれぞれVirtualBoxで作成したFedoraのVMイメージを、学科システムにrsyncし、KVMとして動作させる課題が存在します。
学生にはそれぞれKVMの操作コマンドであるvirshの操作権限は与えていますが、いくつか問題点がありました。
virsh define
でXMLを書くのがめんどいvirsh install
が複雑- 人のVMを間違って消してしまう可能性がある
- VNCパスワードを生成するのがめんどう
- qcow2の置き場所は作って欲しい
これらを解決するために、以前の学科システムではie-virsh
というコマンドが存在していました。
これはvirshコマンドのラッパーで、以下の事が可能なコマンドです。
ie-virsh define 01
でテンプレートXMLをもとにVMを構成- qcow2の置き場所も生成
ie-virsh start 01
でusername-01
というVMを起動できるie-virsh list
でvirsh list --all | grep $username
と同じ挙動をするie-virsh destroy 01
でVMを終了できるie-virsh dumpxml 01
でXMLを確認できる
以前のシステムではこのie-virshを利用することで、5個のVMを作成することができ、かつ起動することが出来ていました。このラッパーは他のユーザーのVMは操作できないので安全でもあります。
貸し出しVMサービス
さらにシステム管理チームでは、あらかじめユーザー設定などをすませたVMのテンプレートイメージをもとに、ユーザーの希望に応じてVMを作成する貸し出しVMサービスがありました。
今まではRubyonRailsで実装されたAkatsukiというweb アプリケーション経由で行っていました。
(なおAkatsukiはシステム移行に伴って, Apache + Passengerから Nginx + Dockerで rails s
に切り替えています)
Akatsukiでだいぶ問題はなかったのですが、VM操作にfog-libvirt
を使っているため、テンプレートVMからのコピー時に、VMの差分イメージではなくVMイメージのフルコピーが使われてしまいます。
そのため差分イメージ(backing file)を使うにはRailsアプリケーション側の大規模な修正が必要そうでした。残念ながら現状のシス管メンバーはそこまでRailsの戦力に強いメンバーが揃っているわけではないので、CLIとして実装したいという気持ちになっていました。
ie-virshの再実装
そこでAkatsukiのVM作成的な機能をie-virshに組み込むぞ!!という気持ちになります。
今まで動いていたie-virshの実装はC + Python2という構成であり、python2を現代のサーバーで動かしたくはないので、python3へのリライトが迫られていました。
上記のAkatsukiの機能を c + python3で組み込むのはなかなか手がかかりそうですし、せっかくなので別言語で書き直そうという機運がid:anatofuzの中で高まります。
そこでCに近い言語として興味があったRustを選択し、実装を行いました。
このあたりは作業の副産物です。 anatofuz.hatenablog.com
Rustで書いたie-virsh
実際に実装した結果がこれです
使い勝手
従来のシステムはヘルプがなかったですが、なんとhelp付きです
$ie-virsh ie-virsh 0.1.2 AnaTofuZ <anatofuz@cr.ie.u-ryukyu.ac.jp> USAGE: ie-virsh <SUBCOMMAND> FLAGS: -h, --help Prints help information -V, --version Prints version information SUBCOMMANDS: console connect to the guest console define define (but don't start) a domain from an template XML file define-gdb define the domain in which the gdb port is opened from the template XML file destroy destroy (stop) a domain domiflist list all domain virtual interfaces dominfo domain information dumpxml domain information in XML edit edit XML configuration for a domain help Prints this message or the help of the given subcommand(s) list list domains shutdown gracefully shutdown a domain start start a (previously defined) inactive domain templates show templates vm ttyconsole tty console undefine undefine a domain vncdisplay vncdisplay
かなりのコマンドをサポートしており、今まではdestroy
しかできませんでしたが、shutdown
も出来るようになってます。
list
自分が作ったVMの状況が確認可能です
$ie-virsh list uid: 11464 gid: 1001 name: k198584 Id Name State ------------------------------------------------ - k198584(anatofu-prome.cr) shut off - k198584-centos shut off - k198584-centos2 shut off - k198584-u20 shut off - k198584-ubuntu18 shut off
define
- テンプレートxmlをもとにvmをdefineします
- 名前はなんでも良いですが、prefixにlogin user nameが入る仕様です
- 例えば e155730 が
ie-virsh define anatofuz
とするとe155730-anatofuz
というVMが作られます
start, dumpxmlなど
- vm名を指定する必要がありますが、wrapperなので全部打つ必要がないようにしています
e155730-anatofuz
の場合はie-virsh start anatofuz
でOKです
- vm名をフルで打っても問題ないです
- 起動しているvmに対しての操作はidを指定しても問題ないようになっています
テンプレートVMをもとに差分で生成する
ie-virsh templates
とすると、対応しているテンプレート一覧が出ます
$ie-virsh templates uid: 11464 gid: 1001 name: k198584 CentOS-7 CentOS-8 Debian-10 Debian-8 Fedore-25 Ubuntu-16 Ubuntu-18 Ubuntu-20
そしてこれをdefine
のときに-t
オプションで指定すると、VMが差分で生成されます!
+amane+k198584 ie-virsh define dondoko -t Ubuntu-20 uid: 11464 gid: 1001 name: k198584 k198584-dondoko generate xml : /etc/libvirt/qemu/k19/k198584/k198584-dondoko.xml vnc password : DQCyWV2YQ$w(!B#(M0#8jcWO%hnqOj Formatting 'k198584-dondoko.qcow2', fmt=qcow2 size=10737418240 backing_file=/ie-ryukyu/kvm/images/templates/template-Ubuntu-20.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 Domain k198584-dondoko defined from /etc/libvirt/qemu/k19/k198584/k198584-dondoko.xml
実際に確認をしてみます
$ie-virsh list uid: 11464 gid: 1001 name: k198584 Id Name State ------------------------------------------------ - k198584(anatofu-prome.cr) shut off - k198584-centos shut off - k198584-centos2 shut off - k198584-dondoko shut off - k198584-u20 shut off - k198584-ubuntu18 shut off
無事作成されていますね!!!(ちなみにこのあと学科内では、VMをDHCP対象にするためにmacアドレスを登録する必要があります...)
実装について
Rustで最初に書いた本格的なプログラムなので、かなり汚いと思いますが、練習になりましたし何より書いてて楽しかったですね。
CLIの実装はclapを使っています。
なんとなくenumでサブコマンドをパターンマッチしたかったのですが、derive
を使う以外のやり方が解らず、無駄に構造体を量産してしまっています。やり方教えてほしい。
execやseuidのようなUNIXのAPIを叩く必要があり、これにはnixが便利でした。とはいえnixはlibcのラッパーっぽいので、はじめからlibcを叩けばよかったのかもしれません。
実装したいはvscodeのremote edit機能を使って、サーバーに直接sshして書いていました。もともとローカルなmacOSでやっていましたが、linux用のバイナリを吐くためにdockerを起動するのがしんどくなってしまい、直接linuxのバイナリを吐きつつ編集できる方法が欲しかったので、vscode最高!!!みたいになっていました。
というわけで新しいie-virshの紹介でした。みんな使ってみてください。あとプルリクお待ちしております。
明日はxxxxさんです。