GitOpsとは?これがあなたが探していた技術的な入門です

Table of Contents

GitOpsとは?これがあなたが探していた技術的な入門です

システムアプローチGitOps がロードマップを提供することで、クラウド ネイティブ システムの構築と展開が急速に解決済みの問題になりつつあるという印象を受けるのは難しくありません。

このアプローチは、構成をコードとして記述する(configuration-as-code)という考え方に基づいています。つまり、すべての構成状態を宣言的に記述し(例:Helm Charts や Terraform テンプレートで指定)、これらのファイルをコードリポジトリ(例:GitHub)に保存し、このリポジトリをクラウドネイティブシステムの構築とデプロイにおける唯一の信頼できる情報源として扱います。Python ファイルにパッチを適用したり、構成ファイルを更新したりしても、リポジトリは完全に自動化された CI/CD パイプラインをトリガーします。

典型的なCI/CDパイプラインの図

典型的な継続的インテグレーション/継続的デプロイメントパイプラインの図

このモデルを用いてクラウドネイティブシステムを構築した経験(例えば、5G対応エッジクラウドのAether)から、このGitOpsモデルの威力は明らかです。設定状態の管理という厄介な問題に対して、分かりやすいアプローチを提供してくれるからです。しかし、一見分かりやすいソリューションには、それだけではありません。他の方も指摘しているように、GitOpsは万能薬ではありません。

私たちの経験上、この結論に至るには少なくとも3つの考慮事項があります。いずれも、クラウドネイティブシステムの運用に必要なすべての状態を、リポジトリベースのメカニズムで完全に管理できるかどうかという問題にかかっています。

まず考慮すべき点は、ソフトウェアを開発する人と、そのソフトウェアを用いてシステムを構築・運用する人の違いを認識する必要があるということです。DevOps(最もシンプルな定義では)は、両者に区別があってはならないことを示唆しています。しかし実際には、開発者は運用者から遠く離れていることが多く、より正確に言えば、他者が最終的にそのソフトウェアをどのように使用するかという設計上の決定から遠く離れています。例えば、ソフトウェアは通常、特定のユースケースを念頭に置いて実装されますが、後に他のソフトウェアと統合され、独自の抽象化と機能、そしてそれに応じた独自の構成状態を持つ全く新しいクラウドアプリが構築されます。(これはAetherにも当てはまります。Software Defined Mobile Coreは、もともとグローバルセルラーネットワークでの使用を目的として実装されましたが、現在では企業におけるプライベート4G/5Gのサポートに再利用されています。)

このような状態を独自の Git リポジトリで管理できるのは事実ですが、プル リクエストによる構成管理の考え方は単純化しすぎています。低レベル (実装中心) の変数と高レベル (アプリケーション中心) の変数の両方があります。言い換えると、ベース ソフトウェア上で 1 つ以上の抽象化レイヤーが実行されているのが一般的です。制限的には、この状態を変更したいのはエンド ユーザー (Aether のエンタープライズ ユーザーなど) である可能性もあり、これはきめ細かいアクセス制御が必要になる可能性が高いことを意味します。これにより、GitOps がこのような状態を管理する方法として不適格になるわけではありませんが、すべての状態が同じように作成されるわけではない可能性が浮上します。つまり、さまざまなスキル セットを持つさまざまな人々によって、さまざまなタイミングでさまざまな構成状態変数にアクセスされ、最も重要なこととして、さまざまなレベルの権限が必要になるということです。

すべてのコンポーネントに、それらが使用する構成パラメータの権威あるソースではないという前提を組み込むことは、良い出発点です。

2つ目の考慮事項は、構成状態の発生源に関するものです。例えば、クラスターにまとめられたサーバーに割り当てられるアドレスは、組織の在庫システムから発生する可能性があります。あるいは、Aetherのような5Gサービスの場合のように、モバイルデバイスにはグローバル加入者データベースで管理される一意の識別子が割り当てられています。一般的に、システムは複数の(時には外部の)構成状態ソースを扱う必要があり、どのコピーが信頼できるもので、どのコピーが派生的なものかを判断することは本質的に困難です。唯一の正解はありませんが、このような状況では、構成状態の信頼できるコピーを、その状態を単独で使用する場合とは別に維持する必要がある可能性が高くなります。すべてのコンポーネントにおいて、それらが使用する構成パラメータの信頼できるソースではないという前提を組み込むことが、良い出発点となります。「唯一の真実のソース」という考え方自体は魅力的ですが、実際の導入で見られる複雑さの一部を見落としています。

3つ目の考慮事項は、この状態がどのくらいの頻度で変化するか、そしてそれによってコンテナセットの再起動、あるいは場合によっては再デプロイが必要になる可能性があるかということです。「一度設定する」構成パラメータであれば確かにこれは理にかなっています。しかし、「実行時に設定可能な」制御変数の場合はどうでしょうか?頻繁に変更される可能性のあるシステムパラメータを更新する最も費用対効果の高い方法は何でしょうか?繰り返しになりますが、すべての状態が同じように作成されるわけではなく、構成状態変数は連続体である可能性が示唆されます。

これら3つの考慮事項は、ビルド時の構成状態と実行時制御状態の違いを示しています。しかしながら、このような状態をどのように管理するかという問題には、唯一の正解は存在しないことを強調しておきます。「構成」と「制御」の間に明確な線引きをすることは、非常に困難です。GitOpsが推奨するリポジトリベースのメカニズムと、代替となる実行時制御はどちらも価値を提供しますが、クラウドを適切に運用するために維持管理する必要がある特定の情報に対して、どちらがより適しているかが問題となります。

実行時状態と構成状態

構成状態は十分に明確に定義されていますが、ランタイム状態とはどういう意味でしょうか。一般的に、ランタイム状態はより動的です。Kubernetes を例にとると、構成は YAML ファイルで宣言されますが、ランタイム状態は、ポッドの障害などのイベントに迅速に対応する必要があるコントローラーによって処理されます。障害後に新しいポッドを起動することが GitOps のプルリクエストによって処理されるとは誰も想像しませんが、実行するポッドの数を宣言する YAML ファイルは、GitOps フレームワークに適した構成状態の例です。この例では、構成とランタイム状態の違いはかなり明白ですが、実際にはそれらはより連続的になる可能性があります。

実行時状態を維持するには、適切な制御メカニズムが必要です(前述の例のように)。私たちはAether向けにそのような制御メカニズムを構築しています(こちらで説明)。詳細は省きますが、中心的な考え方は、仮想デバイス(いわゆるソフトウェアサービス)に再ターゲットされたネットワークデバイス構成マイクロサービスを活用することです。このようなメカニズムには、いくつかの優れた特性があります。(1) 宣言型仕様言語としてYANGを使用しているため、データモデルの定義と操作のための豊富なツールセットが付属しています。(2) バージョン管理をサポートしているため、状態の変更をロールフォワードおよびロールバックできます。(3) データの永続化方法に依存しませんが、通常はクラウドネイティブのキー/値ストアと組み合わせて使用​​されます。(4) ロールベースアクセス制御(RBAC)をサポートしているため、プリンシパルごとに異なる制御/構成パラメータの可視性と制御を付与できます。

YANGデータモデルから自動生成できる制御APIは、より動的なランタイム制御状態を管理するように設計されていることに加え、私たちの環境において2つの利点をもたらしました。(1) RBACは最小権限の原則をサポートするのに役立ちます。(2) 早期のパラメータ検証とセキュリティチェックを実装する機会を提供します(これにより、ユーザーに近い場所でエラーを検出し、より意味のあるエラーメッセージを生成できます)。効果的なデータモデルは非常に重要であることが証明されており、この点については今後改めて取り上げます。

では、最適なメカニズムは一つだけあるのでしょうか? ほぼ確実に両方が必要であり、ケースバイケースで判断されます。ランタイム制御は一部のパラメータの正式な状態を維持し、コードリポジトリは他のパラメータの正式な状態を維持します。どちらがどちらであるかを明確にすることで、各バックエンドコンポーネントがどの「設定パス」に対応する必要があるかを把握できる必要があります。 このことから得られる重要な教訓は何でしょうか? 状態管理が簡単だと言った人は誰もいないということです。そして、そうでないと主張する人には注意が必要です!®

Discover More