GitOpsとは?
GitOpsとは?
GitOpsは、2017年にWeaveworks Inc.が初めて使用した用語で、プロジェクトにおけるDevOpsの実践方法の一つである。その中でも、クラウドネイティブアプリケーションを対象とした継続的デプロイ(Continuous Deployment)に焦点を当てている。
言葉から分かるように、GitOpsはアプリケーションのデプロイと運用に関するすべての要素をコード化し、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クラスターへの変更監査ログを自動的に取得できる。
- これにより「誰が、いつ、何をしたか」がログとして残るため、トラブルシューティングが容易になる。
信頼性
- 手作業によるインフラ管理では、コマンドミス(
kubectl applyの向きなど)が起こり得るが、GitOpsではそのようなミスは起こらない。ロールバックなどの運用もGitを通じて管理するため、安定して再現性のあるオペレーションが可能になる。
セキュリティ
- CI/CDツールを利用したデプロイは、基本的に
kubectlでクラスターへPushしてデプロイするため、クラスター外部に資格情報を公開する必要があり、セキュリティ上望ましくない場合がある。CIとCDの機能が分離されていないため、このような構造が必要になる。 - しかし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ファイル(デプロイ構成ファイル、Kubernetes YAMLなど)を含む。
- インフラ環境構成のためのRepository(Git Config)
- デプロイ環境に関するすべてのManifest(モニタリング、サービス、MQなど)が、どのバージョンでどのように構成されているかを含む。
GitOpsのデプロイ戦略
GitOpsには、Push方式のパイプラインとPull方式のパイプラインという2種類のデプロイ戦略がある。この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)に読み書き(RW)権限が存在するため、セキュリティ情報が外部へ露出する可能性があるという欠点がある。

出典: 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/