vivit で実際に行っている GitOps 手法について

こんにちは。
vivit で SRE をやっている宮本(https://github.com/tatsuro-m)です!

vivit の各プロダクト(hinata media,hinata rental, hinata spot)はバッチ処理等も含めて GKEで稼働しています。

そこで今回は vivit の開発サイクルを支える GitOps についてご紹介します!
以前にも GitOps については書きましたが、変わった部分もあるので再度ご紹介します。 vivit.hatenablog.com

現在のアーキテクチャ

f:id:tatsurom:20211109115122p:plain


利用しているツールをまとめると以下のようになります。

項目 使用ツール
基盤 GKE
マニフェスト管理ツール Kustomize
CI GitHub Actions
CD ArgoCD

順番に解説していきます。
基本的にはプロダクトごとにソースコードを配置するリポジトリは分けており、GitOps のベストプラクティスに従い Kubernetes マニフェスト(Kustomize)は別リポジトリにまとめてあります。

1. ローカルで開発して GitHub に push して PR を作成する
ここは普通だと思います。
この時 CI が走り、該当ブランチの Docker イメージがビルドされ、GCR に自動的に push されます。
Docker イメージのタグには7桁にカットした git のコミットハッシュを使っています。

2. マージする前に検証環境で動作確認したい
いきなり本番にリリースするのは怖いので検証環境にデプロイします。
もちろんここでも GitOps を利用します。

1 で作成したブランチにチェックアウトして、リリースタグを作成します。 リリースタグ作成コマンドは、プロダクトリポジトリの Makefile に用意してあります。

$ make release_tag
カレントブランチは feature/hoge-hoge です。OK? 省略すると y [y|N]: y
環境> 省略するとstg [stg|prod]: stg
サービス> 省略すると全て。カンマ区切りで複数指定可 [serviceA|serviceB]: serviceA,serviceB
名前> 省略するとtatsurom: 
自動マージを有効にしますか?【注意】git tag push のタイミングで処理が自動で始まります。 省略すると N [y|N]: N
このタグでOK? stg/2021/11/09/1203-tatsurom-serviceA,serviceB  省略すると y [y|N]: y
originにPUSHしますか?> [y/N/その他リモート名]: 

作成したタグを GitHub に push すると GitHub Actions がトリガーされ、タグのパースや Docker イメージタグの書き換え、更新PRの作成などが自動で行われます。

30秒ほど待つと以下のような PR がマニフェストファイルを管理しているリポジトリで飛んできます(塗りが多くてすみません🙇)! f:id:tatsurom:20211109121914p:plain

この PR をマージすることによって ArgoCD が反応し、検証環境の pod が新しい Docker イメージでアップデートされます。

3. 動作確認後、本番環境にリリースする
PR が approve されて動作確認もOKなら master にマージします!
この時も先程と同じようにマージコミットに対して Docker イメージの build & push が実行されます。

ローカル環境で最新の master ブランチにチェックアウトして同じようにリリースタグを作成します。

$ make release_tag 
カレントブランチは main です。OK? 省略すると y [y|N]: y
環境> 省略するとstg [stg|prod]: prod
サービス> 省略すると全て。カンマ区切りで複数指定可 [serviceA,|serviceB]: serviceA,serviceB
名前> 省略するとtatsurom: 
自動マージを有効にしますか?【注意】git tag push のタイミングで処理が自動で始まります。 省略すると N [y|N]: N
このタグでOK? prod/2021/11/09/1230-tatsurom-serviceA,serviceB  省略すると y [y|N]: y
originにPUSHしますか?> [y/N/その他リモート名]: 

飛んできた PR をマージして本番リリース完了です 🎉

大まかにこのような流れで GitOps を実現していますが、どうして「常に master ブランチが本番環境にデプロイされている」という構成にしなかったのでしょうか。
タグを作ってPRをマージして。。。という作業が無くなる分、楽で効率的とも言えそうです。

次の章で考えてみます。

GitOps と CIOps の違い

ここまで当たり前に GitOps という言葉を使ってきましたが、 CIOps との違いをおさらいしてみましょう。
こちらの記事 が非常に分かりやすいです。

オペレーション方法 内容
CIOps push 型
CI ツールで CD までやってしまう
GitOps pull 型
CI と CD で別のツールを使う

CIOps は master へのマージ(アクション)に伴って自動的に環境へのデプロイが走るものです。非常にシンプルで分かりやすいです。 つまり、master へのマージをトリガーとして「常に master ブランチが本番環境にデプロイされている」という構成は CIOps だということになります。

GitOps はソースコードを master へマージしたとしても自動デプロイは行われません。マージした際に起動するのは静的解析やテスト、イメージのビルドなど「CI」の部分だけであり、CD には別に明示的なアクションを必要とします。

CIOps の問題点

  • GitHub Actions などの CI ツールにリリースまで行える大きすぎる権限を与えることになる
  • リリース後に不具合が発生してアプリケーションを前の状態に切り戻したい場合、「デプロイだけしたい」のに CI のために長く待たされる
  • 組織規模が大きくなってくると CI/CD 間の責任分界点を作りたくなるが、それができない
  • どの環境にどのイメージがデプロイされているか分かりにくい

などです。
現在の vivit では各プロダクトの担当者がリリース作業まで行っており、 SRE が管理するのは基盤のみですが、このようなデメリットは避けたいです。

「常に master ブランチが本番環境にデプロイされている」という構成にしない理由、CIOps ではなく GitOps で運用している理由は、これらのデメリットを避けるためです。

逆に GitOps のデメリットは初期構築、自動化パイプランの構築(vivit でいうタグ作成の仕組みなど)が大変ということです。
ArgoCD は素晴らしいツールですが、マネージドサービスではないので GKE 上で自前運用が必要です。もちろん性能面で問題があった時には自分たちで対応しなくてはいけません(先日も対応しました 😇)。
設定箇所も割と多いです。

個人開発や小規模で開発を始める場合には CIOps の方が適している場合も多いと思います!

さいごに

今回は vivit で行っている GitOps の紹介と、CIOps と GitOps の違いについて書いてみました。

vivit では一緒に働くエンジニアを大募集しています。
www.wantedly.com

少しでも興味を持って頂いた方は、是非カジュアル面談の応募をお待ちしております!