サーバの大量構築をした事がある学生を80人養成した
この記事はwhywaitaアドベントカレンダー21日目の記事です。 タイトルは言い過ぎかもしれません。
2年ぶりの参加です。前回は雑すぎてごめんよ (参考)
ICTトラブルシューティングコンテストという参加者も運営も学生が行うインフラ系のコンテストがあります。学生は本戦の問題作成および競技ネットワーク等の設計で忙しいので予選問題はお手伝いをしてる社会人(僕含め)で作りました。9問出題されましたが、この記事はそのうちの1問の紹介です。
ここでサーバを100台構築させる問題を出題させ、何かしらの構築を効率化できる手法を用いたチームが25チーム中16チームいて、1チーム5名なので80人の学生がサーバの大量構築をしたことがあるということになります。(難易度は別として)
問題
問題文は長いのでこちらに貼っておきます。伏せる内容もないので全文公開です。
内容を簡単に言うと、
- sshして、nginxをインストールしてもらうまでのチュートリアル
- 同じサーバでnginxに固定のJSONを返すための設定を投入してもらう (問 1-1)
- 同様な構成で100台構築してもらう (問 1-2)
となっていてチュートリアル的にnginxをインストールしつつ、ちょこっと設定等を変えてもらい、それを100台のサーバに対して展開してもらうという問題構成です。 問1として出題したので、Linuxのサーバにsshしてパッケージをインストールするという操作にあまり慣れていない学生でも点数を取れる難易度を目指しました。結果、0点のチームは居ませんでした!
学生のうちに大量のサーバにsshして構築する経験をした学生は居ないだろうという想像のもと、100台構築してもらうことにしました。100台というのはきりがよかったのと、手動でコマンドを打つのは諦めたくなるくらいにしたかったという意図があります。 何かしらの方法で構築を効率化/自動化できたチームは高得点で、手動でやっていたチームは10台くらい構築して時間の無駄だと思ったのか、諦めた形跡がありました。
出題環境
予備も含めるとサーバを3,200ホスト用意しなければなりません。予選環境としてさくらインターネット様にさくらのクラウドを提供して頂いたのですが、流石にこれだけのために3,200ホストを実際に建てるわけにはいきません。ただ大量のホストは欲しい…そこでLXDです!!Dockerじゃないです。LXDですよ。 LXDはLinux Containerを使ってコンテナの中でinitプロセスが立ち上がり、普通のサーバマシンのように振る舞います。Dockerがアプリケーションコンテナであれば、LXDはシステムコンテナです。
Linux Containers - LXD - イントロダクション
LXDで大量のホスト(コンテナ)を運用する上でいろいろつまづきましたがそれは別記事で紹介します。当初はCPU36コア, メモリ224GBの仮想マシンの上で1,500ホスト(コンテナ)稼働させるのにチャレンジするつもりで構築していましたが、本番を見据えた構成でホストを生成していったところ、1,300コンテナあたりでcgroupが壊れてしまいました。各ホストには1CPU, メモリ256MBの環境となるように制限を掛けていたのですが、途中から新しいcgroupが作れなくなりました。ロードアベレージもアイドル状態で600くらいだったのでプロセス数が異常に増えている環境だとかなり厳しい状態になるということがわかりました。
ubuntu@s01:~$ sudo mkdir /sys/fs/cgroup/memory/test mkdir: cannot create directory '/sys/fs/cgroup/memory/test': Cannot allocate memory
試しに手動でcgroupを作ってみてもこんな感じで、さらにsyslogを見るとよくわからないエラーが…
Dec 14 05:57:38 s01 kernel: [14972.817859] BUG: unable to handle kernel NULL pointer dereference at (null) Dec 14 05:57:38 s01 kernel: [14972.819204] IP: [< (null)>] (null) Dec 14 05:57:38 s01 kernel: [14972.820514] PGD 0 Dec 14 05:57:38 s01 kernel: [14972.820584] Oops: 0010 [#2] SMP [略] Dec 14 05:57:38 s01 kernel: [14972.836239] Fixing recursive fault but reboot is needed! Dec 14 08:18:02 s01 kernel: [23396.544849] htb: too many events!
徹夜に近い状態で準備をしていたのであきらめてCPU16コア、メモリ196GBの仮想マシンを4台つかって、1台あたり800ホスト(コンテナ)、4台で3200ホスト(コンテナ)ということになります。
4台分の監視は普段業務で使っていて慣れているのでDatadogを使いました。
CPUとメモリとロードアベレージとiowaitとネットワークトラフィックくらいしか監視していませんでしたが。メモリもだいぶ余裕があったのでZFSの重複排除機能をONにしていました。結果は…
ubuntu@s02:~$ sudo zpool list NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT lxd-pool 248G 3.11G 245G - 5% 1% 63.49x ONLINE -
1ホストあたり 256MB x 800ホスト ≒ 200GBのディスク容量消費で見積もっていたのですが、結果的には重複排除が63.49倍効いた結果3.11GBしか消費しませんでした。同じ環境で全員が同じようなことをするので当たり前といえば当たり前ですが、重複排除すごいですね。
CPUとメモリは検証結果からそこまで心配していなくて、ディスクとネットワークを心配していたのですが、実際ネットワークは本番競技中に一瞬ひやっとしました。とあるチームが100台同時に構築するスクリプトを回したようで、一瞬440Mbpsほど帯域を使いました。1Gbpsで張り付いたらどうしようと思っていたのですが、これ以上帯域を使うことはなく、一瞬で落ち着きました。 最終的にトラブルもなく環境を提供できたのは良い経験になりました。
出題してみてどうだったか
無事100台構築できたチームは、1チームを除き、踏み台サーバからシェルスクリプトを使ってsshをして遠隔でコマンドを投入する方式でした。プロビジョニングツールを使うほどの作業内容でもなさそう & コンテストなのでとりあえず動けばいいということでみんなシェルスクリプトかなと想像していました。
一番シンプルだった解答はこんな感じです。
export SSHPASS=password for (( i=2; $i <= 100; i++ )); do target=`printf "teamxx-c%03d" $i` sshpass -e ssh -oStrictHostKeyChecking=no $target 'sudo apt install nginx -y && echo "{\"hostname\": \"`hostname`\"}" | sudo tee /var/www/html/hostname.json' done
ちなみに芸術点があるのではないかという参加者の声を聞きましたが、芸術点とかはなく、機械的に全台に対してリクエストを投げて点数をモニタリングしていました。構築が終わる前に構築が終わったという報告をしてもすぐに分かる状況になっていたということです。(実際にそういうチームがあったかは触れません)常に監視して採点をしていたので、構築完了の報告を受けたらそのホストに入って手順の報告と全く違う構築方法をしていないか調べていました。
1チームだけansibleを使ってplaybookを書いてきちんとプロビジョニングをしているチームがありました。時間がない中ansibleを使ったということは普段から使い慣れていたのでしょう。素晴らしい。
感想
徹夜して急いで作成した問題にしてはいい感じの問題が出題できたのではないかと思っています。 予選なのでトップ層の点差がつかない事は気にしておらず、予選落ちするチームが勉強になる/楽しんで貰える問題を出したいなと思っていました。本戦は順位を決めるための勝負です。優秀なトラコン運営学生が問題と競技ネットワークの設計を練っているので期待です。 競技用ネットワークを設計している学生はこんなことを言っています。
前回はCLOSトポロジやVXLAN、BGP MPLSにチャレンジしていましたね。
www.slideshare.net
今回はどんなネットワークなのでしょうか。クラウドもOpenStackを卒業して自作しているみたいですね。社会人から見ても恐ろしいです。
ということで、予選を突破したチームの皆さんは本戦で日頃の技術研鑽の結果を見せつけて下さい! 予選に落ちてしまったチームはまたの挑戦をお待ちしております!