こんにちは。ロコガイドでサービスのインフラを担当している@m_doiです。今回は、Webサービスのインフラについて命令型(imperative)や宣言型(declarative)といったキーワードを取り上げつつ、Webサービスのインフラがどのように現在のコンテナ技術やオーケストレーションツールによる基盤に進んできたのかを、私の見てきた範囲で振り返ってみたいと思います。
Infrastructure as Code の進展
昨今、Webサービスのインフラを構築・運用するというタスクにおいて、様々な自動化や効率化が進んできました。これまでは
- 設計に基づいて人間がサーバを設置し
- ネットワークを設定し
- サービスに必要なミドルウェアをセットアップし
- 提供したいサービスをデプロイし
- ハードウェアが壊れたら交換する
- キャパシティが足りなくなってきたら増設する
といったことがインフラの主なタスクでした。
最近はそれらのタスクのうち
- ソフトウェアで実行できる部分はソフトウェアで実行する。
- ソフトウェアで実行できるようにした上で、自動で対応できる処理は自動化する。
というアプローチで、タスクの省力化が進められてきました。また、ソフトウェア化できない物理的な作業も、ある程度の部分まではアウトソースすることで、省力化を進めていたように思います。
そのなかでも、
- サーバ/ネットワークの仮想化やコンテナを実現するOSの要素技術の進歩
- そのような技術に立脚したソフトウェアでコントロールできるインフラを提供するベンダーの登場
といったことにより、一気にソフトウェアでコントロール可能なインフラ(Infrastructure as Code, IaC)が進展しました。このようなIaCの進展とともに、ソフトウェア的な発想である命令型や宣言型のインフラといったような考え方が出てきましたが、それぞれどういうものなのでしょうか?
命令型
あるべき状態に向かって、手順を踏んで構築するようなインフラを命令型と呼んでいます。命令型はプリミティブな処理を積み重ねて、実現したい状態に持っていくインフラです。代表的なものとしては、人間が手順書に従って OS の設定をして、ミドルウェアのインストールを行い、設定を展開し、それを必要な台数用意する、というのも命令型だと思いますし、そのような構築に必要な処理が順に書かれているようなシェルスクリプトを実行する、といったやり方も命令型だと思います。
宣言型
対して宣言型では、命令型と同様にまずは人間がこういうインフラであってほしいという状態を定義します。例えば、ロードバランサが1台あって、その下にアプリケーションサーバが10台あって、それらが参照する DB が1台ある、というような定義です。命令型との違いとして、インフラ全体を制御する仕組みがあるという前提があり、その仕組みに上述のような定義を入力すると、人間が介入しなくてもシステムが自動的にその状態を維持します。代表的なものとしては、Amazon ECSやKubernetesが挙げられます。
インフラ潮流の変化
それでは、これまでのインフラ潮流の変化を振り返ってみます。
命令型前期
クラウド登場以前のインフラ運用では
- データセンターにサーバを用意する
- ネットワークを適切に設定する
- ロードバランサやアプリケーションサーバ、データベースサーバ等役割に応じて、サーバをセットアップする
- OSの設定
- ミドルウェアの設定
- ソフトウェアをデプロイする
などの作業を、手順書に従って人間が行っていました。規模が大きくなってくると、その辺りの作業をシェルスクリプトであったり、軽量なプログラミング言語で自動化したりしていましたが、実行されるコマンドなどはほとんど変わっていませんでした。未セットアップのサーバに対して、基本的な命令を積み重ねて目的の状態にしていくという命令型の基本パターンです。また投入したサーバが故障すると、人間が新しいサーバを同様の手順で構築して投入していました。スケールアウト作業なども同様です。つまり、インフラのあるべき姿からのズレを修正するのは人間の仕事でした。
命令型後期
Chef などの構成管理ツールが登場し手順書に基づいて実施していたような作業はコード化され、サーバ仮想化技術も進歩してソフトウェア制御可能なパブリッククラウドが登場し、インフラの構築・運用に関する殆どの制御をAPIを経由してソフトウェアで行うことができるようになりました。コード化された部分に関しては、ソフトウェア開発と同じようなプロセスでレビュー/継続的インテグレーション/継続的デリバリーを行い、トレーサビリティのある高品質な運用ができるようになりました。この頃から、直接データセンターに行って作業するというようなことは無くなっています。また、コード化されたことにより、障害時の対応の自動化も自分たちで APIやサーバ仮想化の技術を組み合わせることで実現可能になっていきました。
宣言型の進展
サーバ仮想化の技術でサーバのポータビリティは上がったものの、より軽量で展開が高速でオーバヘッドも少なくしたいという流れがあり、Linuxカーネルの開発が進み現在のコンテナ技術が出てき始めました。そのデファクトとしてDockerがあり、運用者が扱うサーバは仮想化から、徐々にコンテナ化に進んで行きました。その流れで、コンテナ技術を軸にして宣言的にインフラをコントロールする基盤として、AWSがAmazon ECSを提供し始め、Googleの技術を軸にしたOSSとしてKubernetesも登場しました。
両者はいずれも、インフラをあらかじめ定義した状態に維持し続ける中央のコントロールプレーンがあり、個別のサーバにコントロールプレーンの指示を受けるエージェントを配置して宣言型のインフラを実現するアーキテクチャでした。Amazon ECSのTask DefinitionやECS Serviceの定義、Kubernetesのmanifest等を見れば、宣言型のイメージが付きやすいのかなと思います。あのような入力を受けて、コントロールプレーンがその状態を維持し、その状態からずれるようなイベントが発生したらコントロールプレーンが元に戻す というような動きをします。
宣言型のコントロールプレーンがインフラの状態管理を行うことによって何が良くなったのでしょうか?私は障害対応やスケールイン/アウトなどの運用がとても省力化されたと思います。それまでは人間のオペレーションなりプリミティブなソフトウェアの制御で、障害時のサーバの復旧やサーバのスケールアウト等を行っていました。 例えば、スケールアウトを実施したい場合は
- アプリケーションサーバを構築する。
- 構築したサーバが適切に動作しているか確認する。
- 構築したサーバをロードバランサにセットする。
- 上記のタスクを必要な回数実施する。
といった作業を人間が実施していました。
これらの作業は宣言型インフラのコントロールプレーンによって自動的に行われるようになり、障害時のサーバの減少は自動的にカバーされ、スケールイン/アウトの動作も入力した定義を少し変更することで簡単に行えるようになりました。また、スケジュールに従ってスケールアウトを実行する、モニタリングツールの値に応じてスケールアウトを実行する、といったような自動運用もよりシンプルに実現できるようになりました。これらの作業はこれまでの命令形のプリミティブな作業の積み重ねよりも簡単な作業になりました。
ロコガイドのインフラ
長々と語りましたが、このようなインフラの潮流を受けて、ロコガイドのインフラがいまどうなっているのかという話を簡単にしたいと思います。
ロコガイドでは、宣言型と命令型が共存していますが、
- 状態を(データストアのような)外部に置いて自身では持たない。
- サービスの負荷に応じて頻繁にスケールイン/スケールアウト/スケールアップなどのオペレーションが発生しがちである。
という特性を持つインフラが宣言型に適していると考えており、以下のような構成になっています。
- アプリケーションサーバは頻繁なスケールイン/アウトの操作が要求されるので、宣言型の Amazon ECSを利用している。
- アプリケーションが利用するデータストアにはRDSやAurora、ElastiCache 等のマネージドなサービスを利用している。
- Terraformを始めとしたツールを採用し、宣言的な記述でインフラをコード化している。
- データストアの他、メールサーバのようなサーバ内に状態を持つようなものはEC2でホストし、そのEC2構築には構成管理ツールのItamaeを、AMIのゴールデンイメージの構成管理にPackerを利用している。
全体としては上述したポイントに従って、宣言型にすると運用しやすくなる部分に宣言型を適用し、マネージドサービスに寄せられる部分は寄せていき、一部は命令型で旧来 のサーバ構築を行いつつ、各種ツールを使って構成管理の省力化を図っているという状況です。まだまだ構成の工夫やパブリックラウドの機能、その他OSSのツールを使って楽にすることができる部分はたくさんあるので、改善を進めています。
まとめ
昨今見かけるようになってきた宣言型と命令型のインフラという考え方について、これまでに自分が見てきたインフラを振り返りながらどういうものか考えてみました。 両者はどちらかを使わなければいけないというものではなく、新しく出てきたスタイルに名前を付けて分類したらこのようになるというもので、この世界にソフトウェア的な発想が入ってきたのもIaCが大きく進んだ証だと思いました。 その上で、インフラの特性によっては宣言型を取り入れるととても運用が楽になる部分はあると思っています。ぜひみんなで楽をしていきましょう!