Dockerのインフラ管理ツールキット「InfraKit」メモ

**2017/05追記: この記事はInfraKit発表当初に書かれたもので、すでに内容が古くなっています。ご注意ください。**

新しい記事書きました: [Docker/InfraKitのインスタンスプラグインの作り方](http://febc-yamamoto.hatenablog.jp/entry/create-infrakit-instance-plugin)

---

新しいインフラ管理ツールキットとして「InfraKit」というものが発表されました。
早速調べて見たので私見をメモしておきます。

#### 紹介ブログ

https://blog.docker.com/2016/10/introducing-infrakit-an-open-source-toolkit-for-declarative-infrastructure/

**10/5 追記:素晴らしい記事がありました。最初にこちらを読んでおくのがオススメです**
[Dockerが「InfraKit」をオープンソースで公開。Docker用のクラウド環境を自動構築、自動修復
](http://www.publickey1.jp/blog/16/dockerinfrakitdocker.html)

#### ソースコード

https://github.com/docker/infrakit/

#### チュートリアル

https://github.com/docker/infrakit/blob/master/docs/tutorial.md



## 何するもの？

インフラを宣言的に作成/管理するためのツールキット群。
具体的にはAPI群 + APIを実装したプラグイン集となりそうな感じ。
将来的にDocker Engineの一部となるとのことです。

もともとDocker for AWS/Azureから生まれたもので、
プラットフォーム/事業者に依存しないインフラ管理のため、より汎用的に使えるように各部品を切り出していったものと思われます。

## 概念

次のような、`プラグイン`と呼ばれるコンポーネントを用いることでインフラを宣言的に作成/管理します。それぞれのコンポーネントごとに満たすべきインターフェースが定義されています。

 - グループ
 - インスタンス
 - フレーバー

それぞれのコンポーネントは独立したプロセスとして動作し、UNIXドメインソケット or TCPソケットでリッスンし、HTTPでやり取りを行います。プラグインはGo以外の言語でも実装可能とのことです。

### グループ プラグイン

(宣言的な)インフラ設定を保持し、その設定通りにインフラが保たれているか監視し、
必要があれば他のプラグインと協調して宣言した設定の状態へ収束させる役割を持つ。

具体的には以下のインターフェースを満たすもの。

```go:infrakit/spi/group/spi.go
// Plugin defines the functions for a Group plugin.

type Plugin interface {
	// グループの監視開始
	WatchGroup(grp Spec) error

	// グループの監視中止
	UnwatchGroup(id ID) error

	// グループ情報のインスペクト
	InspectGroup(id ID) (Description, error)

	// アップデート内容の出力
	DescribeUpdate(updated Spec) (string, error)

	// アップデート実施
	UpdateGroup(updated Spec) error

	// 実行中のアップデート中断
	StopUpdate(id ID) error

	// グループの除去
	DestroyGroup(id ID) error
}
```

### インスタンス プラグイン

インスタンスの作成/破棄を行う役割。
以下のインターフェースを満たすもの。

```go:infrakit/spi/instance/spi.go

// Plugin is a vendor-agnostic API used to create and manage resources with an infrastructure provider.

type Plugin interface {
	// バリデーション
	Validate(req json.RawMessage) error

	// インスタンスの作成
	Provision(spec Spec) (*ID, error)

	// インスタンスの破棄
	Destroy(instance ID) error

	// インスタンス情報の出力
	DescribeInstances(tags map[string]string) ([]Description, error)
}
```

### フレーバー プラグイン

各インスタンスに、それぞれ固有の設定(フレーバー)を与える & ヘルスチェックを行う役割。

以下のインターフェースを満たすもの。

```go:infrakit/api/flavor/spi.go
// Plugin defines custom behavior for what runs on instances.
type Plugin interface {

	// バリデーション
	Validate(flavorProperties json.RawMessage) (AllocationMethod, error)

	// 各インスタンスへ固有の設定(フレーバー)を投入
	Prepare(flavorProperties json.RawMessage, spec instance.Spec) (instance.Spec, error)

	// ヘルスチェック
	Healthy(inst instance.Description) (bool, error)
}
```

---

以下のようなプラグイン実装が用意されていました。

#### グループプラグイン
 - `infrakit/group` : インスタンス+フレーバーの設定を保持し、ローリングアップデートを実装したグループプラグイン

#### インスタンスプラグイン
 - `infrakit/file` : デバッグ/テスト用。実際のサーバーインスタンス生成の代わりにダミーでローカルファイル生成を行う
 - `infrakit/terraform` : Terraformを用いてインスタンスの生成/破棄を行う
 - `infrakit/vagrant` : vagrantを用いてインスタンスの生成/破棄を行う

#### フレーバープラグイン
  - `vanilla`  : ユーザーデータ(インスタンスの初期化時に利用する)とラベルを保持できるテスト用フレーバー実装。(ヘルスチェックは行なってない)
  - `zookeeper`: よく見てません
  - `swarm`    : DockerのインストールやSwarmクラスタ(SwarmMode)への参加を行う


## で、使えるの？どう使うの？

現状では仕組みを用意しただけで、具体的な実装はこれから進むものと思います。
使い方についてですが、SwarmKitと同じく、ユーザーが直接使うものではなさそうです。
(一応エントリポイントとしてCLIは用意されていますが。)

これからDocker Engineへどう取り込まれるか不明ですが、非常に興味深いプロダクト/プラットフォームになりそうな予感がしています。

PullRequestやIssueがガンガン飛んでいるようですので、
Dockerにコントリビュートするチャンスですね！

**10/5追記**
インスタンスプラグインのサンプル実装をしてみました。
https://github.com/yamamoto-febc/infrakit-plugin-sakuracloud/
さくらのクラウド上にインスタンス構築を行うプラグインです。
実用レベルではないですが、プラグイン作成の参考までに。

以上です。