コンテナ実行基盤「Kubernetes」「Nomad」の基本 クラスタの構成方式やデプロイの仕組み:コンテナ実行基盤「Nomad」をKubernetesと比較検証(1)
コンテナオーケストレーションツールとして知られる「Kubernetes」とHashiCorpが提供する「Nomad」を比較検証する本連載。第1回はKubernetesとNomadの基本をおさらいします。
昨今、ビジネスアプリケーションをモノリシックからマイクロサービスの形に変化させることに注目が集まっています。アプリケーションを機能単位に分割し、マイクロサービスとして実装したものを組み合わせることで、機能ごとの役割や要件に応じて言語やミドルウェアを変更できます。また機能ごとに責任を分担させられるためアプリケーションをシンプルに保ちやすくなります。
運用面ではアプリケーションを停止させることなく、機能ごとのアップデートが可能となります。またアップデートの一部をリリースする「カナリアリリース」でABテストを実施できます。マイクロサービスで実装しアプリケーションは冗長化も進んでおり、可用性が高い設計になっています。
ではマイクロサービスはどのような実行基盤上に構築するとよいのでしょうか?
実行基盤を考える上で重要なことは、障害が発生するリソース単位を見極めることです。アプリケーションはOSの機能を利用するため、1つのアプリケーションに1つのOSが必要です。OSは1つのコンピュータあるいは仮想化された実行基盤(以降、VM)で実行されています。オンプレミスでもクラウドでもハードウェアが存在しており、ハードウェアに障害が発生すればそのハードウェア上のアプリケーションに影響を与えます。運が悪ければサービスに影響が出てしまうでしょう。
複数のVMに対して同じ機能を持ったアプリケーションを実行することで冗長化は確保できます。しかしアプリケーションを分散して配置するためには以下のような複数の課題があります。
- リソースに最適なアロケーション
- ログ管理
- スケールイン/アウト
- ネットワーク管理
- 設定変更
- オペレーション(再起動など)
- バージョンアップ
- モニタリング
これらを手作業で実施するのは困難を極めますが、幸いにもこうした作業の負荷を減らす製品が幾つか出てきています。ユーザーが任意のワークロードを実行できる基盤を提供し、コンピュートリソースにクラスタという論理構成を構築、スケジューラが適切なアロケーションを実施して、アプリケーションやネットワークの管理を実行できます。その具体的な製品として知られるのがOSS(Open Source Software)のコンテナオーケストレーションツールである「Kubernetes」ですが、他にも存在します。そのソリューションの一つが「Nomad」です。
本連載ではHashiCorpのNomadの機能をKubernetesと比較、検証してNomadの可能性を紹介していきます。
Kubernetesとは
Kubernetesは、CNCF(Cloud Native Computing Foundation)を中心に開発されているコンテナオーケストレーションツールです。標準仕様が定められており、ベンダーやコミュニティーが開発したコンポーネントを組み合わせることでマイクロサービスのワークロードを実現します。Kubernetes自身も一部マイクロサービスで提供されており、標準仕様に準拠しているコンポーネントを組み合わせることができます。
事実上、コンテナオーケストレーションのデファクトスタンダードであり広く世に知られています。開発も活発に行われておりメジャーバージョンがリリースされてからおよそ四半期に一度マイナーバージョンがリリースされています。
公式ドキュメントも充実しており、最近では日本語化もかなり進んでいます。また企業やコミュニティー、個人による情報発信が活発に行われておりプラクティスやTipsを探しやすい状況です。
標準仕様により多様化
Kubernetesは以下のような標準仕様があるため、さまざまな企業やコミュニティーが多数のディストリビューションを発表しています。
- OCI(Open Container Initiative)が策定している標準仕様
- Runtime Specification
- Image Format Specification
- Distribution Specification
- コンテナインタフェース
- CRI(Container Runtime Interface)
- CNI(Container Network Interface)
- CSI(Container Storage Interface)
利用する観点ではディストリビューションの長所や短所を洗い出して比較したいところです。いずれのディストリビューションもKubernetesのアーキテクチャは変わりませんのでコアを押さえておきましょう。実装は複雑ですが概念はさほど複雑ではありません。
コンポーネントは大きく分けてコントロールプレーンとノードコンポーネントがあります。
- コントロールプレーン
- APIサーバ
- etcd
- スケジューラ
- コントローラー
- ノードコンポーネント
- エージェント
- ネットワークプロキシ
- コンテナランタイム
ざっくりまとめるとこれらのコンポーネントは次の2つを実現しています。
- マニフェストをワークロードに適用する
- ワークロードを実行し続ける
Kubernetesでアプリケーションをデプロイする仕組み
YAMLかJSONで記述したマニフェストを利用してリソースを割り当てます。Kubernetesにおいては「Helm」というパッケージマネジャーが開発、提供されており、企業やコミュニティーが提供するChartやオリジナルのChartを作成、利用すれば、複雑なアプリケーションを簡単にデプロイできるようになります。
Kubernetes APIがマニフェストを受け取りetcdにマニフェストで与えられた仕様をステートとして保存、スケジューラは新しいステートと実際のステートを比較して同じステートになるようにコントローラーに要求します。コントローラーはスケジューラから指定されたリソースの構築を試みます。
マニフェスト
マニフェストにはワークロードを構成するリソースの情報を記述します。
- apiVersion:利用するAPIメジャーバージョンを指定します。v1のように指定しますが、新しい機能を利用する場合はv1alpha1やv1beta1という風に指定します
- kind:デプロイするリソースの種類を指定します。Deployment、ConfigMap、CronJob、Serviceなど指定します
- metadata:デプロイするリソースの属性を指定します。ラベル、名前、名前空間などを指定します
- spec:デプロイするリソースの仕様を指定します。リソースごとに指定する内容は異なります。DeploymentならPodの数、アップデート方法、デプロイするイメージなどが含まれます
マネージドサービス
このように、Kubernetesを構成するコンポーネントは複数存在するため、利用するツールや環境の特性に合わせたクラスタ構成をすることになります。OS選定と設定、必要なソフトウェアのインストール、CRI/CNI/CSIの選定、クラスタ構築などを実施しなければなりません。構築、運用を考えるとクラスタのために1チーム必要になるほどの労力がかかるでしょう。
そこでKubernetesクラスタの構築、運用をユーザーに変わって実行するマネージドサービスがあります。マネージドサービスを利用することでクラスタ構築やメンテナンス作業を軽減して、ユーザーはワークロードに注力できるようになります。
Nomadとは
NomadはHashiCorpが提供するプロダクトの一つで、シンプル、軽量でハイパフォーマンスなジョブオーケストレーターです。1つのワークフローで複数のデータセンターにジョブをデプロイできます。2015年から開発が始まっておりOSS版とEnterprise版が存在します。HashiCorp社が提供するConsulとVaultの連携を含めほとんどの機能がOSSで提供されています。
シンプル、軽量
Nomad単体ではジョブのオーケストレーション機能に特化しています。シークレット管理、サービスディスカバリ、サービスメッシュの機能はHashiCorpが提供する「Consul」や「Vault」を連携させることで利用可能です。また1バイナリで提供されているため、インストールとアップグレードが容易です。
クラスタリング
Nomadクラスタを構成する方法は3つあります。
- Manually:Nomadにクラスタリングの設定を記述する方法です
- Cloud Auto-Join:Amazon Web Services(AWS)、Microsoft Azure、Google Cloud Platform(GCP)のAPIを利用してVMのメタデータから得た情報を基にクラスタリングする方法です
- Consul:事前に構築されたConsulクラスタの情報を基にクラスタリングする方法です。クラスタリングにConsulを利用する場合はConsulのサービスディスカバリがNomad ServerとClientをサービスとして検知してくれます。またサービスメッシュやMulti-Regionクラスタを構築する際にもConsulインテグレーションが必要となってきます。特に障壁がなければConsulを利用するのがお勧めです
さまざまな実行基盤をサポート
Task Driverを指定することによりコンテナ以外のワークロードを実行可能です。Isolated Fork/Exec Driver以外は全てPluginとして実装されており、ホストに実行基盤ライブラリをインストールすることでさまざまなワークロードを実行できます。
- Docker:Dockerを使ってコンテナを実行します。複数のruntimeをサポートしておりGPU用のruntimeも利用できます
- Raw Fork/Exec:ホストに対してそのままワークロードを実行できる機能です。セキュリティの観点では推奨できませんが、ポイントを押さえれば効率的なオペレーションが実現できるかもしれません
- Isolated Fork/Exec:ホストに対してそのままワークロードを実行できる機能です。Raw Fork/Execとの違いは名前空間で隔離された空間でコマンドを実行できることです。アプリケーションのテストやデバッグなどに使えます
- Java:任意の.jarファイルを実行することが可能なDriverです。もちろんJava実行環境を含むコンテナイメージを作成すればDockerコンテナとして実行することは可能です。しかし.jarファイルのみで実行可能なJava Driverを利用すればポータビリティーは高くなります
- QEMU:QEMUを使ってVMを実行します。環境の移行を始めるときに分離できないワークロードをそのまま実行したい場合などに使えます
- Podman:Podmanを使ってコンテナを実行します。組み込みプラグインではないため、PodmanやDriverをインストールする必要があります
NomadがサポートしているDriverの他にコミュニティーがサポートしているDriverがありますが、気になる方は公式ドキュメントを読んでみてください。ここでは筆者が気になるものだけピックアップします。
- containerd:containerdを使ってコンテナを実行します。containerdがインストールされていればホストにDockerをインストールする必要はありません。runtimeはrunc(v1またはv2)が選択可能です。
Nomadでアプリケーションをデプロイする仕組み
HCL(HashiCorp Configuration Language:HashiCorp構成言語)かJSONで記述したJobを渡してリソースを割り当てます。人が割り当てるJobはHCLで記述し、システムがJobを割り当てるユースケースではJSONを使うようにするとよいでしょう。
スケジューラは渡されたJobと現在のワークロードを比較して、現在のワークロードを渡されたワークロードと同じ状態になるように振る舞います。
Jobはワークロードを構成するために必要な「Stanza」で構成されています。ワークロードの論理構成単位を階層化して管理するために次の3つのStanzaを定義します。
- Job:任意のワークロードを実行する論理的な単位を定義します。複数のGroupを定義することができます。NomadクラスタはRegionとDatacenterで管理されており、Job名はRegion内でユニークである必要があります
- Group:複数のTaskをGroupに定義することができ、Taskリソースの共有に関する定義をします。Group内のTaskは同じClientに割り当てられます
- Task:Jobを構成する最小の単位です。アプリケーションやコマンドを定義します
次回からはKubernetesの環境構築を通じて構築のポイントとコンポーネント、エコシステムを詳しく解説する予定です。お楽しみに。
筆者紹介:
守永宏明
grasys R&D Lead Engineer
組み込み系IT企業、金融関係のオンライントレードシステム開発企業を経て、ソーシャルゲーム開発・運営会社へ入社。ゲームプログラマ、開発推進メンバーとして経験を積み、2015年2月にgrasysへ参画。Google Cloudでのさまざまなインフラ環境の構築/運用、監視プログラムの設計/開発経験を持つ。最近は社内システムの選定/インテグレーション、全体効率化などにフォーカスした活動を続けている。
Google Cloud / AWS / Azureを中心に技術情報を発信中
Copyright © ITmedia, Inc. All Rights Reserved.