Inflatonにおけるサーバープロビジョニングのおはなし
technique
- TOP
- Old Archives
- Inflatonにおけるサーバープロビジョニングのおはなし
序
Inflatonにおけるサーバープロビジョニングに関する質問があったので、記事にしようと思う。
基本的にはこの部分は、私の(=Inflatonの)基本的方針を踏襲したものになっている。 つまり、
- 一般的である、あるいは流行であるということにはとらわれず
- Unixの流儀に従い
- 堅牢で確実なツールと手法で
- 全ての理解が容易であるように
している。
前提
Inflatonにおいては、一般的ではない前提が成り立っている。
まず、「私が前提になっているということ」である。
つまり、私に属人化することは基本的に問題視されない。 それよりも私の能力が発揮できることが優先されるのでやり方は好きに選べる。
もうひとつは、会社自体が少数精鋭になっているということだ。
これを前提に一般的な手法を避けたりもしていて、「IT業界の人間」が直ちに即戦力になるような状況にない。 戦力になるまで、1年くらいは育てて使う方針になっている。
その間賃金が低いとしても、300万円くらいは利益を出さない人のために使うということである。 しかも、まっさらな状態から1年でちゃんとやれるようになるとしたら、つきっきりで教えなくてはならない。 私だとえらいことになってしまうし、全てを教えられるレベルのエンジニアだと年俸600万円は下らないだろう。
これは「1人増えるのが一大イベント」であるからこそできることで、新卒採用があるような会社ではここまでの方法はとれない。
ここまでの前提を以て、他とは違うInflaton styleを可能にしている。
正しい方法
ConoHaの場合、「スタートアップスクリプト」という機能があり、サーバー構成時にスクリプトを実行させることができる。 cloud-config形式とシェルスクリプト形式をサポートしているという。
ConoHaに限らなければ、Chefなどのツールを使うのが一般的である。
もちろん、これらの方法はInflatonでは採用していない。
我々の方法
基本的に
- ドキュメントを書く
- シェルスクリプトを書く
の2点である。
ドキュメントは手順書と言っていいのかはわからないが、基本的に最低限コマンドが打てればこれだけ読んで構築できるレベルの内容になっている。 開発も実務も忙しいのに事業かけもちでドキュメントもちゃんと書いていることについては是非とも褒めまくっていただきたい。
シェルスクリプトのほうは、より正確に表現するならZshバッチになっている。 正直なところ、ドキュメントを読むよりもこちらを読むほうがわかりやすいだろう。
何のために、といったことに関しては、そのサービスを構成するものに関する、内部向け外部向けのドキュメントが存在するため、それを見れば確認できる。
それぞれちゃんとした理由がある。
まず、ドキュメントが揃っている最大の理由は、しばらく触ってないソフトウェアやサービスに関して、私が覚えていられないことと、説明する時間が割けないことだ。
弊社取締役はMimir Yokohamaの生徒さんでもあり、私が書くレベルのドキュメントがあればだいたいは理解できる。 このため、ちゃんとドキュメントがあるだけでも私の負担は確実に減る。そして、ドキュメントがなければ私は開発に戻ってくるのが大変になる。
そして、システム構成に関してはあまり固定化されていない。そもそもコンポーネントの変更をしやすいように設計してあり、サーバー面での変更というのは相当カジュアルに行われている。
もちろん、理由は私が管理しているからであるが、もうひとつの理由としてArch Linuxだからというのもある。 Arch Linuxは普通にバージョンも上がれば、役割を担うソフトウェアが変更されることもある。だから、構築から運用を固定化したところで、固定化したものが自動的に通用しなくなって困るだけなのだ。
ドキュメントに関しては単純に都度アップデートしている形だが、実はシェルスクリプトとドキュメントの2段構成にしている大きな理由として、「サーバー構築手順が次のサーバーで成立する可能性はかなり低い」というのがある。 一番躓くのがパッケージ名の変更である。Archは非常にカジュアルにパッケージ名を変更するので、インストールするパッケージ名の指定がコケる原因になる場合が多い。 加えていえば、サーバーソフトウェアの設定ファイルの項目も、意外と頻繁に変わる。
そこで
- ドキュメントで手順を確認
- そのパートのバッチスクリプトを実行、あるいはドキュメント記載のコマンドをコピペしながら実行
- 躓いた場合は原因を確認し、ドキュメントとスクリプトをアップデート
という形でstep by stepで進めていくと構築できるようになっている。 Inflatonとしてはサーバーを増やすのは年に数えるほどでしかないため、完全自動化するのはメリットよりデメリットのほうが大きい。
サーバーインスタンス増加による増強よりは、新しいことをやるために構成の異なるサーバーを立てる頻度のほうが高い。
だから作業においてコアになることが確定している部分…例えばzsh
,
grml-zsh-config
, zsh-theme-powerlevel9k
,
screen
のインストールと、/etc/zshrc.local
の設定などはそれでひとつのスクリプトにまとめられている。
なので、このスクリプトは使い回しが効く。
Inflatonでサーバーを立てるということは、最近始まったばかりなので稀な話だが、「システムの構築」そのものは数え切れないくらいやっている。 今でも何らかの理由でシステムを作ることは年に10回くらいはあるし、15年とか前だと週イチなんてペースだったので、知識と経験があるし、効率化も進んでいる。 結局のところ「最適解を追い求めている以上、ゴージャスな方法で固定するよりは変更しやすい方法のほうがいい」というのが教訓なのだ。
ここには私の信念、及び流儀も絡む。 私は「完璧たりうる」と思っているし、かつ「完璧と動的である」と思っている。だからこそ、「完璧を追い求めることにこそ意味がある」と信じている。 そのためには「動いた状態」で固定することには意味がないし、「動的な最善」であるArch Linuxなのである。
一例としては、現在Plutoのサーバーではsshd_config(5)のCiphers
は
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com
である。この設定の主たるところはchacha20-poly1305@openssh.com
が外されていることで、外している理由はSSHの処理が比較的重いサービス特性上、サーバー側でAES-NIを使いたいからである。
余談だが、AMDプロセッサはBulldozer以降でAES-NIをサポートしており、IntelはIvy Bridgeまではi3においてAES-NIがサポートされていなかった。 こうしたことを含め、性能の低いデバイスにおいてはAES-NIがなく、計算量の多いAESは重いということになるのだが、コネクションが1本であるクライアントにとっては大した話ではなく、多数のコネクションをさばくサーバー側で軽くすることが優先である。
しかし、この設定ではaes128-ctr
が最初に来ており、今後10年で変更されることを意味している。
つまり常に動的に構成され、動的に変更されるのである。 構成時はむしろ構成変更タイミングでもあると言っていい。
手順スクリプトは
pacman -S grml-zsh-config tmux zsh-completions zsh-syntax-highlighting zsh-theme-powerlevel9k zsh-history-substring-search vim vim-plugins rsync
cat > /etc/zshrc.local <<EOF
setopt vi
autoload -U history-search
#zle -N history-beginning-search-backward-end history-search
#zle -N history-beginning-search-forward-end history-search
bindkey "^P" history-beginning-search-backward
bindkey "^N" history-beginning-search-forward
bindkey "\e[5~" history-beginning-search-backward
bindkey "\e[6~" history-beginning-search-forward
bindkey -M viins "\e[5~" history-beginning-search-backward
bindkey -M viins "\e[6~" history-beginning-search-forward
bindkey -M vicmd "\e[5~" history-beginning-search-backward
bindkey -M vicmd "\e[6~" history-beginning-search-forward
...
EOF
みたいな感じで、普通にコマンドラインの手順のバッチと、catを使ったファイル生成から成り立っているのだが、ステップ中で躓いた場合、Vimでd:2
してそのステップからやり直すようにすれば良い。
dgg
でない理由は、「失敗時にそのステップを終了する」ため、先頭で
TRAPZERR() { exit 48 }
としているからだ。
付して述べるなら、「理解していなくても使える」というのはInflatonとしては嬉しいことではなくて、「理解する前提で育てる」方向だから、 「知悉しやすい、教材としても優れたものにしておく」という考え方になってもいる。
プロビジョニングツールを使うことでディストリビューション間の差異を吸収しやすくなるという面はあるが、 ディストリビューション変更をするような場合は、パッケージに含まれるファイルの詳細を把握しなければ潜在的に危険であると考えているので、そのような吸収をしてもらう必要はない。
同様にプロビジョニングツールを使うことで構成することそのものを容易にする面もあるが、そもそも構成が普通でないので、これも全く役に立たない。 例えば私は個人としては2017年までサーバーにDeleGateを使っていたが、DeleGateを構成することなど誰も考えていないし、そこまで極端ではなくとも常に普通にはない構成になっている。 こうしたことから、定番の構成を容易にする機能というのは助けにならず、こうした機能を理由にツールを選択することもない。
サーバーに依存したツールを使うことも、「サーバーの変更」という選択を難しくさせるので、望ましいとは思えない。