inductor's blog

nothing but self note :)

CIOpsとGitOpsの話

はじめに

GitOpsという言葉が生まれたのが自分の知る限り2017年頃なのですが、世の中にあるCI/CDの仕組みはまだほとんどがCIOpsもしくは手動のオペレーションによって成り立っていると思っていて、かつては自分もそうだったのですが「Gitで管理されていればGitOpsなんでしょ?」という勘違いを払拭したくてこのエントリーを書いています。

GitOpsとCIOpsは全然違う

まず前提としてGitOpsの明確な定義を知らないという場合、あなたの思う「Gitを契機とした自動デプロイの仕組み」は基本的にはCIOpsです。GitOpsとCIOpsは思ったよりも大きな違いがあって、そもそもGitOpsの必要性が分かっていない場合、自動化によって成立しているデプロイはCIOpsが基本です。

CIOpsとGitOpsの一番の違いは、Push型かPull型かである

CIOpsの場合、例えばGitHub ActionsやCircleCIを使って何らかのソースコードを管理している場合に使われます。Web開発によくある構成でいうとRubyだとかNode.jsで作られたアプリケーションのGitリポジトリにおいてmain(意識が高いのでmasterではない)ブランチでマージが発生した場合に本番やステージングへのデプロイが走る、みたいなのがありますよね。もう少し具体的に書くと

  1. 任意の修正や新機能を含むfeatureブランチがmain向けに作成される(CIでテストやLintが走る)
  2. レビューのプロセスを経てApproveされる
  3. ReviewerまたはReviewee(あるいはBotの自動処理)によってMergeされる(マージ後に本番やらステージングやらへ自動的にデプロイされる)

これは全部CIOpsと呼ばれる処理であって、GitOpsではないという話をしています。わけわからんかもしれませんがこれめっちゃだいじなので大事です(語彙力)。

CIOpsの場合、簡単に言えば git push origin mainのタイミングを契機としてCIが発火するので、つまり「Push型」であることがわかります。一方でGitOpsはPull型で、いくつかの観点においてこれまで多く利用されてきたCIOpsとは違う特性があります。どういうことか見ていきましょう。

CIOpsのメリットは単純さにある

これまで一般的に使われてきた、CIを契機としたデプロイ方法(ここではCIOpsと呼びます)には、その契機による単純性というメリットがあります。

つまり、CIにすべてのフローが集中するので、開発者にとってはデプロイのタイミングが測りやすいわけです。

f:id:inductor:20210924011913p:plain

↑見て分かると思いますが、GitHub Actionsがあらゆるアクションの契機になっていますね!

ここから分かることとしては、いわゆるInfrastructure as Codeだったりテスト駆動開発の恩恵をGitをベースとして有効活用できるというメリットがあります。

インフラ的観点でCIOpsのデメリットを考えてみる

GitOpsはこれと比べて何が違うかというと。コードがPushされるまでは一緒(テストが走るまでは同じ)なのですが、いわゆるデプロイ処理とCIのテストやLintの処理でそれぞれ別の仕組みを使うところにメリットがあります。

小さな組織だとそのメリットを理解するのがそもそも結構難しかったりするわけですが、例えばそれなりの規模でAmazon ECSやKubernetesを使っている場合、以下のようなことを考えたりするわけです。

  1. 開発者がGitHub(GitLab)でなんでもできちゃうのと全く同じ権限でインフラまで面倒みれちゃうとセキュリティ的に問題がある
  2. CI(コード自体のpush)とCD(実際に本番やらで反映される処理)では全く別の組織が管理していて、同じ組織図で管理することができない
  3. Principle of Least Privilegeを遵守したい(つまり、CIとCDで権限を分けたい)

そうなってくると、CIからCDまですべてのRead/Writeの権限がCI側に集中していることが必ずしもメリットとは言えないというスケールが、組織的に発生しうるということを、勘の鋭い人であれば予想できるかと思います。

そこで登場するのがGitOpsという考え方です。

GitOpsのメリット

GitOpsのメリットはもはやシンプルに1つです。CIとCDの責任分界ができることです。

つまり、開発者チームまではCIを担保し、そこから先にいるSREやらインフラやらがCDの面倒を見るという点にあります。

「開発者がリリース管理したい」という気持ちを持つ人もいらっしゃると思いますが、落ち着いて聞いてほしいです。

まず、基盤とアプリケーションには大きな違いがあります。具体的に言うと

  • アプリケーション固有の値やコードそのものは開発チームの責任

  • クラウドのマネージドサービスの使い方はそれぞれの組織によって責任分界点が異なる

  • コンテナよりも上部に位置するKubernetesクラスターや、クラウドそのものの設定変更などは、基盤を見るSREチームが面倒を見たいという組織も多い

こうした事情から、いわゆるInfra as Codeよりも下のレイヤーについてはインフラの面倒をみる基盤チームが管理したいという事情の組織がそれなりにあると思います。今はそうじゃなかったとしても、規模が大きくなるとそうなっていくという組織は実際多いはずです。そうなってきたとき、以下の管理モデルがしっくり来るタイミングが必ず来ます。

f:id:inductor:20210924025627p:plain

つまり、Gitを起点として

  • 「開発者が最低限やりたいCIの処理(テストやLintが回って、終わったらDocker pushまでを行う)」と
  • 「インフラ基盤側でやりたいCDの処理(開発チームが面倒を見終わった単体テストから先のデプロイ処理の面倒を見たい)」

がはっきり二分化されたフローが存在するわけです。

GitOpsの本質は「"Gitに置かれたコードをSSoT(Single Source of Truth)として"CIとCDの責任分界点を明確にする」という点にあるわけですが、実態としては以下のような条件を満たしさえすれば行えるわけです。

  • アプリケーションコードまたは成果物(Dockerイメージだったり、Goなどのコンパイル済バイナリだったり)に対する読み取り権限
  • 各環境に対するデプロイのための権限

CIOpsの場合、CIにすべての権限が集中するわけですから、例えばCircleCIやGitHub Actionsにはすべからずして以下のような権限が必要でした

  • 該当Gitリポジトリへの書き込み/読み取り権限
  • 本場環境やステージング環境への書き込み/読み取り権限
  • (必要に応じて)依存ライブラリへの読み取り権限

書き込みと読み取り同時に権限が必要なため、裏を返せばCIの権限が乗っ取られてしまった場合全部だめになってしまうわけです。他にも、例えばGCPやAWSのVPC内部のリソースへPushする場合には何らかのアクションが必要で、場合によってはCIからサーバーに穴あけをしていた組織もあったかと思います。GitOpsに切り替えると、常に環境からGitリポジトリへのPullが契機になるので、面倒なファイアウォールのルールから開放されやすいというメリットもあります。つまり、Gitリポジトリにアクセスするための権限だけサーバーやCDエンジンが持っていればあとはネットワーク的なincoming trafficやらあれこれまで気にするリスクが大幅に抑えられるという点です。

こうした観点からも、特にセキュリティにうるさい組織についてはGitOpsの導入が推奨されることが分かっていただけると思います。わけのわからんNAT IPで入ってくるCIツールよりは、サーバーの固定の資源を使って git pulやらdocker pullやらをしたほうが、権限的にもネットワーク経路的にも間違いがないと思いませんか?

というわけで、GitOpsを適用したいパターンは実はとてもはっきりしていて、「SREと開発の責任分界点が必要」という場合です。特にモノレポの場合、ブランチ戦略を複雑にするメリットも少ないのでGitOpsは相性がいいと思います。

  • mainブランチにすべてのリソースにおける「Desired state(あるべき姿)」が記述されている
  • 組織によってばらばらのサービス固有なノウハウがなく、基盤全体である程度共通の認識がある
    • そんな高度なものである必要は無くて、Graceful shutdownがちゃんとあってロールバック時に必要な挙動が示されていて、エラーがあったとき正しく分散トレーシングできるとかその程度

コンテナだとかそういう話に限らず、12-Factor Appsに沿っていたら成立しているはずの条件が満たされていれば、理論上はGitOpsによって管理されても問題がないはずであるということが分かると思います。

追記: GitOpsの定義の話についてもうちょっとちゃんと書いておく

CIOpsとGitOpsの話 - inductor's blog

GitOps は WeaveWorks が最初に提唱していて Principle は <a href="https://www.weave.works/technologies/gitops/" target="_blank" rel="noopener nofollow">https://www.weave.works/technologies/gitops/</a> にある。CIOps との違いは &quot;4. Software agents to ensure correctness and alert on divergence&quot; 。本番が変更されても Git 側に追従するかが大きな違いだと思う

2021/09/24 08:11
b.hatena.ne.jp

https://e34.fm/のrrreeeyyyさんが便利ブコメしてくれてたのでこれも貼っておきます。仰るとおりWeaveWorksのPrincipleを読みましょうって話ではあるので、僕が書いてることに違和感を持った人はそっちをちゃんと見たほうが間違いはないかもしれません。大事なのはGitを起点として仕組みでCIとCDを分けるという点。クラウドを使い込んでいくにつれてインフラ運用とアプリ開発の組織のあり方が曖昧になっていたり、あるいは責任分解点がシフトしている組織にとっては、この考え方は少なくとも何かを変えるためのきっかけになると思っています。

www.weave.works

ちょっと長くなりましたが、GitOpsとCIOpsの比較におけるGitOpsの優位性について語ってみました。今日はこのへんで。