IaCがもたらすインフラ管理のパラダイムシフト ~イミュータブルインフラストラクチャ~
クラウドネイティブNow

中谷 輝

富士通株式会社
ジャパン・グローバルゲートウェイ デリバリーテクノロジー推進統括部

イミュータブルインフラストラクチャ

DevOpsの分野では、イミュータブルインフラストラクチャ(Immutable Infrastructure)という概念が存在します。Immutableとは不変という意味で、一度デプロイされたインフラの状態を変更しないという原則に基づいています。イミュータブルインフラストラクチャでは、新しいバージョンのアプリケーションやシステムの変更が必要な場合には既存のインフラを直接変更するのではなく、新しいインフラを更新した設定値と共に作成します。

インフラリソースをマネジメントコンソールなどで手作業で作成する場合、担当者によっては作業ミスが発生したり、パラメータシートや手順書に記載された設定値と実環境の設定が乖離したりするケースがあります。また、特定の開発ルール等を設けず複数の作業者が手作業でリソースに変更を加える場合、重複するリソースの発生や削除し忘れたリソースの残存、必要なリソースの不足、命名規則に従わないリソースの発生などが起こりえます。このような状況下では実環境の状態を把握することが困難となり、インフラがブラックボックス化する可能性があります。また、実環境の状態が把握出来なければ障害発生時に原因の特定や問題の切り分けが非常に困難となるうえ、発生した障害の台帳管理などの運用工数もかさむこととなります。また、目視でパラメータシートと実環境の全てのリソースを把握するという運用も考えられますが、非効率的です。

このような問題に対し、IaCは有用となります。IaCは同じ操作を何度行っても結果が同じになる性質である冪等性(べきとうせい)があるため、一度設定した環境の再現や新規の環境構築がスムーズに行えます。環境ごとにテンプレートを作成すると、手作業による影響を排除し、環境毎に冪等性のあるリソースの作成を実施できます。これにより問題のある設定値を含む環境があったとしても、同様の環境を適切な設定値と共に新規に作成しなおすことが可能です。また、IaCはGit等でバージョン管理が可能であるため、問題が発生した際のロールバックや問題の発生源の特定も容易です。
実環境の状態の把握という意味でも、IaCではインフラの設定がコードとして宣言的に記述されるため、環境の状態が一目で把握できます。手動の場合はリソース毎の作成者を把握するのは困難ですが、バージョン管理を行えば変更履歴が記録されるため、環境のブラックボックス化を防ぐことができます。また、Terraformのステートファイルに代表されるようにIaCツールには現状のインフラの状態を管理する機構が備わっているので、コード実行時にローカルの環境と実環境の差分を検出することも容易です。

さらに、IaCはCI/CDと組み合わせることで、手作業によるヒューマンエラーを防ぐことができます。CI/CDパイプライン経由でIaCのコードをデプロイする場合、基本的に手動での操作は行わず、ソースコードのリポジトリへのpushやプルリクエストを契機に自動でデプロイが実行されます。本番環境のリソース作成時にはマネジメントコンソール上からの手作業の操作を制限し、CDパイプラインからのデプロイのみに限定する、といった運用ルールをチームで設けておけば、人手を介さないインフラの実現が可能となります。ただし、IaCを使えば自動的にイミュータブルなインフラが実現可能なわけではないので、自分達のチームで開発・運用ルールを設けたり、適切なCI/CDパイプラインの設計を行ったりする必要があります。

GitOps

GitOpsとはGitリポジトリを信頼できる唯一の情報源として使用し、インフラとアプリケーションのコードの構成管理を行う手法です。主にKubernetesを使用したアプリケーション開発におけるCI/CDの文脈で使用されます。
Kubernetesでは必要なリソースをマニフェストファイルというYAML形式のファイルで定義することが出来ます。マニフェストファイルにはPod、Service、Ingress、ConfigMapなどのKubernetesクラスタの構築に必要なリソースの設定値が記述されます。このマニフェストファイルをGit上で管理することにより、これまで説明したようなIaCやCI/CDのプラクティスをKubernetesにも適用することが可能となります。GitOpsではPush型とPull型と呼ばれるパイプラインが存在します。

Push型のパイプライン

KubernetesのリソースをCI/CDパイプライン経由でデプロイする場合、以下のようなパイプラインの処理が考えられます。

  • アプリケーションのソースコードやDockerfileからDockerイメージをビルド
  • ビルドしたDockerイメージをコンテナレジストリにpush
  • ビルドしたイメージを基にマニフェストファイルを更新
  • kubectl applyコマンド実行によりマニフェストファイルに定義したリソースをデプロイ

このようなパイプラインはPush型のパイプラインと呼ばれ、比較的シンプルに実装することが可能です。しかし、Push型のパイプラインにはいくつか問題点があります。 まず、このパイプラインでは処理内容が順方向に伝播し、CIの処理の過程でデプロイまで行われるので、適用した環境の状態を元に戻すといったことは想定されていません。特に、アプリケーションとKubernetesのマニフェストファイルを同一のリポジトリで管理している場合、障害発生時にはアプリケーションのコードをrevertした後に再度CIの処理を実行する必要があり、ややロールバックの処理が冗長と言えます。また、マニフェストファイルへの軽微な変更でも同様にCIの処理を実施する必要があるため、利便性に欠けます。加えて、コミット履歴にアプリケーションとマニフェストファイルのものが両方含まれるので、変更点の追跡も難しくなります。
その他、Push型のパイプラインではKubernetesリソースをデプロイする際にCIツールにクラスタの認証情報を渡す必要があります。そのため、CIツールにセキュリティ脆弱性が発生した場合、Kubernetesクラスタ内の情報漏洩が発生する危険性をはらんでいます。

Pull型のパイプライン

Push型のパイプラインもGitOpsの定義自体には従っていますが、GitOpsという用語が使用される場合、Pull型のパイプラインを示すケースが一般的です。Pull型のパイプラインではPush型とは対照的に、CIとCDの処理でパイプラインが分割されます。Pull型のパイプラインを実現するツールで有名なものにはArgo CDやFlux CDなどがあます。

Pull型のパイプラインではGitOpsツールがクラスタの一部となり、現在のインフラの状態とGitリポジトリの状態を定期的に比較します。これらの状態に差分が発生した場合、GitOpsツールがGitHub等からWebhookを受け取り、Gitリポジトリ上に格納されたマニフェストファイルをクラスタにデプロイします。これにより、インフラの状態とGitリポジトリの状態を常に同期させることが可能となります。Push型のパイプラインではリソースのデプロイは手続き的にコマンドを実行するだけでしたが、Pull型のパイプラインはより宣言的なアプローチと言えます。また、Pull型ではKubernetesクラスタ自体が自律的に自らの状態を更新するので、CIのパイプラインでは後続の処理を気にする必要がありません。ちなみに、Argo CDではImage Updaterを使用するとコンテナレジストリ内の変更が随時確認され、マニフェストファイル内のイメージタグの更新自体もArgo CD自身が実行してくれます。このように、Pull型のパイプラインではCIとCDの処理の担当が分かれるため、開発チームとSREやインフラチーム等で責任分界点を設けることも可能となります。加えて、Pull型のパイプラインではPush型のように認証情報をクラスタ外部に保存する必要が無いため、セキュリティの観点でも有用です。更に、障害時もrevertなどによりマニフェストファイルのコミット履歴のみを取り消せばロールバックが可能となります。

Argo CD

  • 出典
    Argo CD. "Declarative GitOps CD for Kubernetes". 2023. https://argo-cd.readthedocs.io/en/stable/. (参照 2024-02-08).

関連情報

当社が提供するDX実現の課題にお応えするハイブリットITサービスの詳細は下記ページをご覧ください。

本コンテンツに関するお問い合わせ

お電話でのお問い合わせ

富士通コンタクトライン(総合窓口)

0120-933-200

受付時間:9時~12時および13時~17時30分
(土曜日・日曜日・祝日・当社指定の休業日を除く)

Webでのお問い合わせ

当社はセキュリティ保護の観点からSSL技術を使用しております。

ページの先頭へ