スクーターに乗った女性(イラスト画像の作成元はfreepik、NomadロゴはHashiCorp)
Kubernetesはコンテナオーケストレーションの巨人です。世界中で巨大なデプロイメントを動かしていますが、一筋縄でいくものではありません。
特に小さなチームにおいて、メンテナンスに時間をとられますし習得までの道のりは険しいものです。私たち4人のチームがtrivagoで達成したかったことにおいて、Kubernetesはオーバヘッドがありすぎました。そして別のプロダクトを探した結果、私たちはNomadと恋に落ちたのです。
ウィッシュリスト
私たちのチームは監視やパフォーマンス分析のための典型的なサービスを多く実行していてGoで書かれたメトリクス取得のためのAPIエンドポイントやPrometheusのエクスポーター、LogstashやGollumといったログパーサー、InfluxDBやElasticsearchといったデータベースが挙げられます。私たちはそれらのジョブを実行し続けるシンプルなシステムを必要としていました。
私たちはまずコンテナオーケストレーションの要件を洗い出しました。
- 多数のマシンを横断したサービス群を実行できる
- 実行中サービスの全体把握画面を提供する
- サービス間の疎通を許可する
- サービスが死んだ時に自動でリスタートする
- 小さなチームでも管理可能である
さらに、以下の事項は必ずしも必要ではないもののあれば好ましいものです。
- マシンの能力に応じてタグ付けする(例:I/O負荷の高いサービスのために高速なディスクを用意しているマシンへのラベル付け)
- オーケストレーターに依存せずサービスを実行可能である(例:開発中のサービス実行)
- 設定情報やシークレット情報を共有するための共通の場所がある
- メトリクス計測やログ取得のためのエンドポイントを提供する
Kubernetesが私たちにうまくフィットしなかった理由
Kubernetesを用いてプロトタイプを作ったとき、私たちはサービスを運用するロジックをさらに複雑に階層化し始めていることに気づきました。信頼のおけるロジックの上にです。
例として、KubernetesはConfigMapを使ってサービスに設定を埋め込むことができます。これは複数の設定ファイルをマージする場合やより多くのサービスをpodに追加する場合に、極めて混乱を招きやすいものです。Kubernetesと、さらに言うならhelmでは、関心の分離を保証するために動的に外部設定を注入することができます。しかしこれによって、あなたのプロジェクトとKubernetesの結びつきが強く、暗黙的なものになってしまいます。helmとConfigMapは任意の機能なので、必ずしも使う必要はありません。ただ単に設定をDockerイメージ内にコピーするだけでも良いのです。しかし、そういった道を辿る誘惑が強いことで、後々怪我をすることになりかねない不要な抽象化を構築してしまいがちです。
さらに、Kubernetesエコシステムはまだ急速に進化しています。ベストプラクティスとツール類を最新に保つには、かなりの時間と労力がかかります。Kubectl、minikube、kubeadm、helm、tiller、kops、oc・・・リストはどこまでも続きます。Kubernetesを始めるために全てのツールが必要な訳ではありませんが、どれが必要なのかがわかりづらく、少なくともそれらが何であるかを知らなければなりません。そのため、習得までの道のりは非常に険しいと言えます。
いつKubernetesを使うべきか
trivagoでは実際に、多くのチームがKubernetesを利用し非常に満足していました。インスタンスはGoogleやAmazonによって管理されていましたが、Kubernetesにはそういった能力が備わっています。
Kubernetesは驚くべき機能を備えており、大規模なコンテナオーケストレーションを管理しやすくします。
- きめ細かな権限管理
- カスタムコントローラはロジックからクラスタを作るものです。これは単にKubernetes APIと会話するプログラムです。
- オートスケーリング!Kubernetesはサービスを必要に応じてスケールアップ/ダウンすることができます。Kubernetesはサービスメトリクスを使って、人の手の介入を必要とせずにこれを実現します。
考えるべきはあなたは本当に全ての機能を必要としているかです。こういった抽象化に頼ってただ動かすということは出来ません。あなたは内部で何が動いているかを学ぶ必要があるでしょう。
特に私たちのチームでは、ほとんどのサービスをオンプレミスで動かしており(trivagoのコアインフラと密接に連携するため)、自分たちでKubernetesクラスタを走らせる余裕はありませんでした。そうではなくサービスをリリースしたかったのです。
「電池は含まれておりません」
Nomadはサービスオーケストレーション機能における20%のみを備えますが、これだけで80%の用途には事足りるでしょう。Nomadのできることはデプロイメントの管理のみです。コンテナのロールアウトとエラー発生時の再起動を実現できますが、そのくらいのものです。
Nomadの全体的なポイントはできることが少ないことです。きめ細かな権限管理や高度なネットワークポリシーは出来ませんが、これは設計に基づくものです。それらのコンポーネントはエンタープライズ向けサービスとして提供されるか、もしくは全く提供されません。
Nomadは使いやすさと表現力の高さとの間のちょうどいいところを突いていると思います。小さくて良いですし、サービスにほとんど依存しません。より強いコントロールを求めるのであれば、あなた自身でそういった機能を構築するか他のアプローチを使う必要があるでしょう。Nomadはただのオーケストレーターなのです。
Nomadのもっとも良いところは置き換えが簡単であることです。Nomadが提供する機能はサービスを管理する別のシステムとの結合が容易であるため、ベンダーロックインがほとんどありません。Nomadはクラスターの各マシン上で簡素なシングルバイナリーとして実行される、ただそれだけのものです!
ゆるく組み合わさったコンポーネント群であるNomadのエコシステム
Nomadの真の実力はそのエコシステムの中にあります。NomadはConsul(キーバリューストア)やVault(シークレット管理)のような他のプロダクトととてもうまく連携できますし、連携は完全に任意です。Nomadファイルの中でセクションを設けることで、あなたはそれらのサービスからデータを取得できます。
template {
data = ‹‹EOH
LOG_LEVEL="{{key "service/geo-api/log-verbosity"}}"
API_KEY="{{with secret "secret/geo-api-key"}}{{.Data.value}}{{end}}"
EOH
destination = "secrets/file.env"
env = true
}
ここではConsul上からservice/geo-api-log-verbosity
キーのデータを読み、それをジョブの LOG_LEVEL
環境変数に設定しています。さらにVault上のsecret/geo-api-key
をAPI_KEY
に設定しています。シンプル、かつパワフルですね!
Nomadは非常にシンプルなので、APIを通して簡単に他のサービスと連携させることが出来ます。例えば、ジョブのタグ付けはサービスディスカバリーに利用することができます。trivagoでは、メトリクス計測の必要な全てのサービスにtrv-metrics
というタグを付けています。これによって、PrometheusはConsulを介してサービスを特定し、定期的に /metrics
エンドポイントをスクレイピングすることで新しいデータを取得します。別の例として、Lokiと連携することでログ取得も同じように実現できるでしょう。
他にも拡張性を示す多くの例があります。
- Webhookを使ってJenkinsジョブを起動し、サービス設定の変更時にNomadジョブが再適用されるようにConsulに監視させる
- Cephを使ってNomadに分散ファイルシステムを追加する
- fabioを使ったロードバランシング
これらを通して私たちは組織的にインフラを成長させることができましたし、事前の準備はほとんど必要ありませんでした。
注意しておくこと
完璧なシステムというものはありません。私はオシャレで新しい機能をプロダクション環境ですぐに使わないことをお薦めします。不具合や不足している機能といったものは然るべく存在しており、Kubernetesの場合もそうです。
Kubernetesと比較するとNomadの勢いは遥かに劣っています。Kubernetesはこれまでに約75000のコミットと2000人のコントリビューターがおりましたが、一方のNomadは約14000のコミットと300人のコントリビューターとだけ関わってきました。NomadにとってKubernetesの速さに付いていくことは難しいでしょうけれど、おそらくその必要はありません!Kubernetesと比較して、Nomadの守備範囲ははるかに狭いですし、コミュニティが小さいということはあなたのプルリクストが受け入れられやすいということも意味しています。
総括
覚えておくべきは「ただみんなが使っているからという理由だけでKubernetesを使ってはいけない」ということです。注意深く要件を評価し、どのツールが請求に見合うかを調べましょう。
もしあなたが大規模インフラ上に同一サービス群をデプロイする計画をしているのであれば、Kubernetesという道を選んで良いでしょう。ただ、複雑性や運用コストが増えることを肝に命じてください。そしてこういったコストの一部は、Google Kubernetes EngineやAmazon EKSのようなマネージドKubernetes環境を利用することで省くことができます。
メンテナンスが容易で拡張可能な信頼性のあるオーケストレーターを探しているのであれば、Nomadを試してみてはいかがでしょうか?多くを得られることに驚かれるでしょう。
Kubernetesが車だとすると、Nomadはスクーターです。場合によっては一方が好ましく、場合によってはもう一方が好ましいでしょう。両者はそれぞれの生存権を持っています。
クレジット
記事の原稿をレビューしてくれた、私の素晴らしい同僚たち(Esteban Barrios、Jorge-Luis Betancourt、Simon Brüggen、Arne Claus、Inga Feick、Wolfgang Gassler、Barnabas Kutassy、Perry Manuk、Patrick Pokatilo、Jakub Sacha)に感謝します。
💬コメントはHacker NewsかRedditでどうぞ。