ベアメタル環境でのサーバ構築のためのツールや管理情報、APIなどを提供するsabakanを試してみましたのでメモを残しておきます。
sabakan
とは
サイボウズさんのインフラ刷新プロジェクトNeco
で用いられている機材管理ツールとのことです。
サーバの構成情報などを保持しておくインベントリ機能とそれらを用いてネットワークブート/プロビジョニングを行う機能を提供してくれます。
データストアとしてはetcdが用いられており、sabakan自体を複数起動して冗長構成にすることもできるようです。
(画像引用元: https://github.com/cybozu-go/sabakan)
使い方としては、サーバのシリアル情報や持たせたい役割を構成情報として投入し、スイッチに繋いだ上でサーバの電源を入れるとアプリケーションがデプロイできる状態になる、という感じなようです。
次にもう少し詳しく機能をみてみます。
sabakanの持つ機能
sabakanのREADMEによると以下のような機能を持っているとのことです。
sabakanの機能(一部抜粋):
- サーバの構成情報のインベントリ / IPアドレスの割り当て管理
- DHCP(UEFI/iPXE HTTPでのネットワークブート用)サービス
- HTTPサービス(OSイメージや任意のアセットの提供)
- サーバのライフサイクル管理用APIの提供
(詳しくはREADMEのFeaturesを参照してください)
サーバのOSにはContainer Linuxを想定しており、Ignitionでプロビジョニングを行うためのjsonを組み立てたりHTTPで配信する機能も持っています。
また、サーバの状態(まだ初期化してないよ、とか動いてるよ、とか退役する/したとか)も保持してます。
参考: sabakan/lifecycle.md at master · cybozu-go/sabakan · GitHub
注意点として、サーバの状態は保持するだけでその変更はAPIなどを用いて外部から行う必要ということがあります。
ヘルスチェックなどを通じて状態を操作するコントローラー的なものは必要に応じて別途用意しないといけないということですね。
類似プロダクト
類似のプロダクトとしてはCoreOSのMatchboxがあります。
Kubernetes環境の構築/管理ツールであるTectonicで足回りの構築に使われているものです。
Matchboxはsabakanと同じくiPXEなどでのネットワークブート、Ignitionによるプロビジョニングに対応しています。
違いとしてはsabakanの方はより物理的なインフラを意識している(ラックの指定とかBMC周りとか)点とサーバの状態管理を行なっている点があります。
Matchboxの方はMetadata APIやTerraformプロバイダーの提供を行なうなど、クラウドを含めより汎用的なインフラ環境上で動かせることを目指しているように感じてます。
どちらも単体で動かすようなものではなく、ビルディングブロックとして他のシステムと協調して動かすものとなっていますので やりたいことに応じて使い分ければ良さそうですね。
sabakanでサーバ構築してみる
概要を押さえたところで早速sabakanを試してみます。
動かし方はGitHub上にGetting startedがありますのでこちらを参考にします。
また、個人的な好みにより今回はさくらのクラウドで動かします。
さくらのクラウドはOSなしでサーバ作成が出来ますしPXEブートも可能なのでsabakanが使えるはずです。
インフラの準備
まずsabakanを動かすためのサーバ/スイッチなどをさくらのクラウド上で作成します。
今回は以下のような構成にします。
構成:
- sabakan用サーバ
- VPCでは
192.168.150.0/24
を用いる
今回はsabakanをDocker上で動かすつもりですので、サーバのOSはContainer LinuxかRancherOSを入れとくのが楽だと思います。
サーバは作成後にスイッチへの接続、スイッチと接続したNIC(eth1)ヘのIPアドレス設定を行なっておきます(今回は192.168.150.1/24
にします)。
sabakanの実行
インフラの準備ができたら早速sabakanを実行してみましょう。
以下はsabakan用サーバにssh接続して作業します。
sabakan用のconfigの作成
まずsabakan用のconfigファイルを用意します。
以下の内容をsabakan.yml
という名前で作成します。
etcd: endpoints: - http://localhost:2379 dhcp-bind: 192.168.150.1:67 advertise-url: http://192.168.150.1:10080
sabakanはconfigファイルだけでなくコマンドラインオプションで各種設定を指定可能ですが、configファイルとコマンドラインオプションを併用した場合はconfigファイルが優先され コマンドラインオプションでの指定が無視されますのでご注意ください(最初気付かずに数分悩みました)。
etcdとsabakanを起動
次にetcdとsabakanをDockerで起動します。
本来は各種オプションをしっかり指定しておくべきだとは思いますが今回はお試しということで色々手を抜いてます。
# etcd $ docker run -d --rm --name etcd --network=host --uts=host quay.io/cybozu/etcd:3.3 # sabakan $ docker run -d --name sabakan --network=host -v $PWD:/work -w /work quay.io/cybozu/sabakan:1.1 -config-file sabakan.yml
ネットブート用の設定類を投入
sabakanが起動したら次にネットブートを行うための各種設定を投入していきます。
sabakanのCLIクライアントsabactl
の準備
sabakanの操作を行うためのCLIクライアントsabactl
を準備しておきます。
今回はdocker exec
でsabakanコンテナ上でsabactlを実行するように以下のエイリアスを利用します。
$ alias sabactl='docker exec -it sabakan sabactl'
IPAM
まずIPアドレスの割り当て定義を投入します。
jsonファイルを作成してsabactl
というsabakanのCLIクライアントを用いて投入します。
以下のファイルをipam.json
という名前で作成してください。
{ "max-nodes-in-rack": 8, "node-ipv4-pool": "192.168.150.0/24", "node-ipv4-range-size": 4, "node-ipv4-range-mask": 24, "node-index-offset": 1, "node-ip-per-node": 1, "bmc-ipv4-pool": "192.2.0.0/24", "bmc-ipv4-offset": "0.0.0.1", "bmc-ipv4-range-size": 1, "bmc-ipv4-range-mask": 24, "bmc-ipv4-gateway-offset": 1 }
作成したら以下のコマンドで投入します。
$ sabactl ipam set -f ipam.json
投入できたかは以下のコマンドで確認できます。
$ sabactl ipam get
ipam.jsonで定義している項目については以下のドキュメントを参照してください。
sabakan/ipam.md at master · cybozu-go/sabakan · GitHub
なお、こちらもとりあえず動けば良いため値は適当にしてます。
DHCPサーバの設定
次にDHCPサーバの設定を投入します。 IPAMと同じくファイルを作ってsabactlで投入します。
以下のファイルをdhcp.json
として作成します。
{ "gateway-offset": 1, }
投入は以下のコマンドです。
$ sabactl dhcp set -f dhcp.json
設定項目についてのドキュメントはこちらです。
sabakan/dhcp.md at master · cybozu-go/sabakan · GitHub
PXEブート用のイメージ
次にPXEブートを行うためのイメージをCoreOSのWebサイトから取得してsabakanに投入します。
イメージはcurlコマンドで以下のように取得します。
$ curl -o kernel -Lf http://stable.release.core-os.net/amd64-usr/current/coreos_production_pxe.vmlinuz $ curl -o initrd.gz -Lf http://stable.release.core-os.net/amd64-usr/current/coreos_production_pxe_image.cpio.gz
取得したらsabactlで投入します。
$ sabactl images upload current kernel initrd.gz
なお、ここで指定しているcurrent
は各イメージにつけるIDで任意の名前をつけれるようになっています。
sabakanは複数のイメージを登録しておくことが出来、PXEブート時に自動的に最新のイメージを利用するという仕組みになっています。
サーバの定義投入〜サーバ起動
ここまででsabakanの準備が整いました。後はサーバの定義を投入した上でサーバの電源を入れるだけです。
ということで早速定義の投入を行なってみます。
サーバのシリアル(ID)を取得
sabakanにサーバの定義情報を登録する際にサーバのシリアルが必要になります。
物理サーバであれば購入時の保証書などに記載されていると思いますのでそれを利用します。
今回はさくらのクラウドで動かしますので、単純にサーバのIDがあればOKです。
こちらの記事にあるように、さくらのクラウドではシリアル番号=IDとなります。
なのでさくらのクラウド上でサーバを作成してIDを控えましょう。
サーバの作成(さくらのクラウド)
さくらのクラウドでサーバ作成を行います。
ここでは以下の条件でサーバ作成してください。
- サーバに接続するディスクはブランクディスクとする
- サーバのNICはスイッチに接続する
作成後すぐに起動
のチェックは外しておく
こんな構成になるはずです。
作成したらサーバのIDを控えましょう。
サーバの定義ファイルを作成
サーバのID(シリアル)が用意できましたので、sabakanに投入するサーバの定義ファイルを作成していきます。
まず以下のファイルをmachines.json
として作成します。
[ { "serial": "先ほど控えたサーバのID", "rack": 0, "role": "test", "bmc": { "type": "IPMI-2.0", "ipv4": "" } } ]
ここでは役割(role
)をtest
としました。後ほどこのロール名を用いてIgnition設定を投入していきます。
また、今回はBMCは利用しませんので空にしています。
投入は以下のコマンドです。
$ sabactl machines create -f machines.json
サーバのプロビジョニング用にIgnition設定
次にこのサーバをプロビジョニングするためのIgnitionの設定を投入します。
プロビジョニングでは本来はディスクへのインストールなどを行うべきところですが、
今回はユーザー名core
、パスワードがpassword
のユーザーを追加するだけとします。
まず以下のファイルをpasswd.yml
という名前で作成します。
users: - name: core passwordHash: "$1$2OsV8nCL$AaaGvkomzT5c/D6zApaMG0" groups: - name: sacloud gid: 10000
次に以下のファイルをignision.yml
という名前で作成します。
passwd: passwd.yml
次にsabactlで投入します。
$ sabactl ignitions set -f ignision.yml test サーバのID
これで準備が整いました。
サーバの電源投入
いよいよプロビジョニングしてみます。サーバの電源をONにしコンソールを眺めましょう。
さくらのクラウド CLI usacloudをご利用の方は以下のコマンドでVNCコンソールを開くことが可能です。
$ usacloud server vnc サーバのID
うまく設定出来ていればiPXEブートされている様子が見えるはずです。
起動したらユーザー名:core
、パスワード:password
でログインしてみましょう。
ログインできれば成功です。
今回はプロビジョニングの設定が適当でしたが、きちんと設定すればすぐにアプリケーションをデプロイできる状態にまで持っていけますね!!
おまけ: sabactlでサーバの状態を変えてみる
前述の通りsabakan自体はサーバの状態を変えることはなく、外部から何らかの形で変えてあげる必要があります。
本来はサーバのプロビジョニングの完了を検知して適切にハンドリングするなどが必要ですが、ここではsabactlで手動で状態を変えてみます。
まず、初期状態ではサーバの状態はuninitialized
になっています。
$ sabactl machines get-state サーバのID uninitialized
状態を変えるにはsabactl machines set-state
を使うようです。
# healthyにする sabactl machines set-state サーバのID healthy # retiringにする sabactl machines set-state サーバのID retiring # retiredにする!? sabactl machines set-state サーバのID retired Error: Bad Request: invalid request: invalid state: retired
retired
にするにはsabactl crypts delete
しなきゃいけないようです。
参考: sabakan/lifecycle.md at master · cybozu-go/sabakan · GitHub
$ sabactl crypts delete --force サーバのID # ちゃんとretiredになってるはず $ sabactl machines get-state サーバのID retired
終わりに
ということで今回はsabakanを試してみました。 周りのコントローラーを工夫すれば色々出来そうですね。
以上です。