GitOps とは何か?
GitOps とは?
GitOps は、2017 年に Weaveworks Inc. が初めて使用した用語で、プロジェクトにおける DevOps の実践方法の 1 つである。その中でも、クラウドネイティブアプリケーションを対象とした継続的デプロイ (Continuous Deployment) に焦点を当てている。言葉から分かるように、アプリケーションのデプロイと運用に関わるすべての要素をコード化し、Git で管理 (Operation) することを意味する。
出典: Weaveworks
GitOps は、バージョン管理、協業、コンプライアンス、CI/CD など、アプリケーション開発で使われる DevOps のベストプラクティスをインフラ自動化に適用した運用フレームワークである。
「インフラとアプリケーションを含むシステム全体のコードを Git で管理する」という考え方と方法が GitOps の本質である。GitOps は Git バージョン管理システムを使用して、IaC (Infrastructure as Code) などのインフラ構成ファイルを管理する。
ここでいうインフラは一般的に Kubernetes を前提としている。簡単に言えば、GitOps は Kubernetes Manifest ファイルを Git で管理し、デプロイ時にも Git に保存された Manifest を使ってクラスタへデプロイする一連の過程を意味する。
GitOps の原則
すべてのシステムは宣言的に宣言されなければならない。
- 「宣言的 (declarative)」とは、命令の集合ではなく事実 (fact) の集合として構成されていることを保証するという意味である。
- Kubernetes の manifest はすべて宣言的に作成されており、これを Git で管理すれば、versioning などの Git の利点に加えて SSOT (single source of truth) を持つことができる。
システムの状態は Git のバージョンに従う。
- Git に保存された Kubernetes manifest を基準にシステムへデプロイされるため、以前のバージョンのシステムをデプロイしたい場合は
git revertのようなコマンドを使用すればよい。
承認された変更は自動的にシステムへ適用される。
- 一度宣言された manifest が Git に登録され管理され始めたら、変更が発生するたびに自動的にシステムへ適用される必要があり、クラスタへデプロイするたびに資格情報を必要としてはならない。
デプロイに失敗した場合、ユーザーへ警告しなければならない。
- システム状態が宣言され、バージョン管理下に維持されているとき、デプロイに失敗した場合はユーザーへ警告できるシステムを用意する必要がある。
GitOps の利点
GitOps を使用する利点は、大きく次の 4 つに分けられる。
生産性
- Git が変更されると、リポジトリの IaC 設定が変更され、Kubernetes クラスタの更新や機能管理を Git を通じて実行できる。
- 運用からデプロイまで Git で行うことができ、本番環境の状態を Git 上の IaC と比較し、一致しない場合は検出・修正することもできる。
安定性
- GitOps ワークフローを導入すると、外部から行われた Kubernetes クラスタへの変更監査ログを自動的に検索できる。
- これにより、「誰が、いつ、何をしたか」がログに残るため、問題解決が容易になる。
信頼性
- 手動によるインフラ管理では、コマンドミスなどが起こり得るが、GitOps ではそのようなミスが起こりにくい。ロールバックなどの運用も Git を通じて管理するため、安定して再現性のある運用が可能である。
セキュリティ
- CI/CD ツールを利用したデプロイは、基本的に
kubectlからクラスタへ Push してデプロイするため、クラスタ外部に資格情報を公開しなければならない場合があり、セキュリティ上望ましくないことがある。 - GitOps は CI と CD を分離して管理するため、Pull を使用してクラスタを変更し、資格情報を外部へ公開せずにデプロイできる。そのためセキュリティリスクを減らせる。
GitOps Workflow
次は Weaveworks の公式ブログで紹介された GitOps パイプラインの図である。

この図から分かるように、CI と CD はどちらも Git でコードを管理しているが、CI と CD の機能は分離されている。
GitOps Repository
GitOps Pipeline を設計するときは、一般的に Application コードの Repository と、インフラ環境構成のための Repository の 2 つで構成することが推奨される。

出典: https://www.gitops.tech/#push-based-deployments
- Application Repository (Git Code)
- Application ソースコードとデプロイ用 Manifest ファイルを含む。
- インフラ環境構成用 Repository (Git Config)
- デプロイ環境に関するすべての Manifest が、どのバージョンでどのように構成されているかを含む。
GitOps デプロイ戦略
GitOps には Push 方式のパイプラインと Pull 方式のパイプラインという 2 種類のデプロイ戦略がある。違いは、リポジトリ内のマニフェストとデプロイ環境の状態を一致させる方法である。一般的にはセキュリティ面で Pull 方式のデプロイ戦略が比較的安全な方法とされ、好まれている。
最近使われる多くの CI/CD ツールは Push ベースモデルを使用する。Push ベースのパイプラインは、コードが CI システムから始まり、一連のスクリプトを通じて kubectl を直接使用し、変更を Kubernetes クラスタへ Push できることを意味する。
CI システムのデプロイ機能を使用したり、コマンドラインで手動実行したりしたくない理由は、資格情報がクラスタ外部に露出する可能性があるためである。CI/CD スクリプトとコマンドラインは保護できるが、クラスタの信頼ドメイン外部で作業していることになる。これは一般的に良い方法ではなく、CI システムが本番環境への外部侵入経路になる可能性があるためである。
Push Pipeline
Push 方式のパイプラインは、Git Repo にある Manifest ファイルが変更されたときにデプロイパイプラインを実行する構造である。

出典: https://www.gitops.tech/#push-based-deployments
デプロイ環境の数に影響されず、接続情報を追加または修正するだけで簡単にデプロイ環境を追加・変更できる。アーキテクチャが簡単なため、多くの場所で使用される。
一般的に Push パイプラインはクラスタ外部の CI に読み書き権限が存在し、セキュリティ情報が外部へ露出する可能性があるという短所がある。

出典: https://www.weave.works/technologies/gitops/#a-diy-gitops-pipeline
Pull based Pipeline
デプロイ対象クラスタに配置された別のオペレーターがデプロイ役割を代行する構造である。
出典: https://www.gitops.tech/#pull-based-deployments
このオペレーターは Git Repo の Manifest とデプロイ環境を継続的に比較し、差異が発生した場合、Git Repo の Manifest を基準にクラスタを維持する。
Pull 方式のパイプラインでは、GitOps ツールがイメージを取得し、資格情報はクラスタ内部に保管されるため、セキュリティ情報を外部へ露出せずに実行できる。

図: https://www.weave.works/technologies/gitops/#a-diy-gitops-pipeline
GitOps ツール
現在よく使われるツールは 3 つである。

Argo CD
- Argo CD では分かりやすい GUI を提供する。
- 手動 Sync など、すべての操作を GUI から実行できる。
- 関連サイト
Flux CD
- GitOps を提唱した Weaveworks 社のツールで、構成が簡単で軽量だが GUI は提供しない。
- 関連サイト
- ソースコード: https://github.com/fluxcd/flux2
- 関連ドキュメント: https://fluxcd.io/flux/
Jenkins X
- 有名な Jenkins から派生したツールで、このツールでは CI/CD に対応したパイプライン自体を構築できる。
- Argo CD、Flux CD は CD のみ可能である。
- 自由度は高いが、その分アーキテクチャが複雑なため学習コストも高い。
- 関連サイト
- ソースコード: https://github.com/jenkins-x/jx-cli
- 関連ドキュメント: https://jenkins-x.io/v3/about/