⚙️

GitOpsでSingle Source of Truthしよう!〜ArgoCD編〜

はじめに

はじめまして! エンジニアの篠田です。 プロダクトチームでSRE、インフラ、DevOpsなどを主なタスクとする通称、知恵のチームに所属しています。 最近集中したい時に聞いてる音楽第一位は般若心経テクノバージョンです。ちょっとだけ暗唱できるようになってきた今日この頃です笑 さて、弊社プロダクトの継続的デプロイメント(以下、CD)のアーキテクチャにArgoCDを導入しました。 これからArgoCDやその他GitOpsツールの導入を検討しておられる方にとって少しでもご参考になれば幸いです。

この記事で書くこと

  • ArgoCD導入してトイルを削減したぞー!という話
    • トイル
  • 導入の経緯や過程、実際に運用してみて得た学びなどをつらつらと

この記事で書かないこと

  • ArgoCDの具体的な設定方法やコマンド等の技術的なことは本記事では割愛します。
 

前提

GitOpsとは

weaveworks社が提唱した継続的デプロイメントの方法論で、インフラ構成をGitで管理して、Gitへの操作を介してインフラの状態を更新できるようにすれば便利じゃね?という考え方です。 GitOpsはあくまで方法論なので、実際に導入するにはGitOpsを実現するためのツールが必要になります。(ArgoCDFlux, Jenkins Xなど) GitOpsのポイントは次の2点だと思っています。
  1. インフラ構成を宣言的に記述してGit管理する
  1. コードが更新されるとインフラの状態が同期される

ArgoCDとは

KubernetesでGitOpsを実現するためのツールです。 ArgoCDそのものがKubernetesのカスタムリソースとして実装されています。 GitOpsやArgoCDについてはこちらの記事がとてもわかりやすかったので、weaveworks社の原典と併せてオススメです。

GitOps前

GitOps導入前のCDは以下のようになっていました。
  • S3にマニフェストをアップロードしておく(CDで使う)
    • S3とは別に、バージョン管理のためにGitにもpushしている
  • CI/CDパイプラインのCDでS3からマニフェストをダウンロードしてクラスターにapply
  • リソースの状態を変更する場合はそのつどマニフェストをS3にアップロードする必要があり、この部分だけはパイプラインから切り離された手動オペレーション

マニフェストをSingle Source of Truthにしないとヤバい!

インフラやCI/CDなどの基盤システムの開発・運用は一年ほど前まではテックリードの柳がほぼ一人で行っていました。 その後、SRE業務を専任で行う知恵のチームが創設され、CI/CDもチーム運用に移行しました。
一人で運用するにはとても優れたアーキテクチャでしたが、チームで運用しようとするといろいろとつらみが出てきました。 状況が変化したことで求められる特性も変化したんですね。 つらみの源泉は結局のところ、Kubernetesリソースの定義元が一元化されていない点にありました。 例えば、このPodのRequestとLimitの値を変更したいけど、今回の変更とは関係ない部分で既存の定義を上書いちゃわないかな。。みたいな心理的負荷が変更のたびにかかっていました。

GitOpsでSingle Source of Truthしよう!

そこでGitOpsの出番です! GitOpsはインフラ定義をGitに集約して、インフラの実体が定義に同期するという考え方なので、まさに求めていたSingle Source of Truthを実現するにはうってつけです。

ArgoCDはGUIが強い

GitOpsツールはArgoCDにしました。 理由はArgoCDにはGUIダッシュボードがあり、使いやすい&とっつきやすいからです。 他に候補としてはFluxも検討したのですが、FluxにはGUIがないのでArgoCDに決めました。 ダッシュボードを見ればSyncされているかどうか、Syncされていない場合はどのリソースがSyncされていないか等が一目でわかるので運用面でもメリットが大きそうだなーと思いました。 何よりダッシュボードからリアルタイムでリソースが更新されていくのを視覚的に見れるのが楽しかったのが大きいです笑

ArgoCD導入手順

ArgoCD移行、運用開始までは以下のような手順で進めました。
  1. ArgoCDを稼働させる
      • GitOpsリポジトリ作成&環境ごとにブランチ作成(e.g. 本番環境 = prodブランチ、dev環境 = devブランチ)
      • KustomizeテンプレートをHelmチャートに変換してGitOpsリポジトリにチェックイン
      • ArgoCDコントローラー系リソースデプロイ → プロダクトのリソースがデプロイされてSyncになる
  1. CD修正
      • でクラスターにデプロイしている処理をHelmチャートのイメージタグを更新してPR作成&merge するように変更
移行時に一部のCronJobに対応漏れがあり、別件でクラスターを作り直した際にそのCronJobが行方不明になってしまうというミスをやらかしました。。 GitOps移行の際はあらかじめ移行対象リソースを洗い出してチェックリストを作っておくことを強くオススメします!

GitOps後

CDをGitOpsにしたことで、以前まで抱えていた運用上のペインはおおむね解消できたかな〜と思います。
 

よかったこと

  • マニフェストの二重管理を解消できた
  • Single Source of TruthがArgoCDによって担保されたことで、マニフェストを変更するときの心理的負荷が大幅に減った
  • 環境をブランチで分けられるのが構造として綺麗
  • GUIからリソースが更新されていく様子を見るのがとても楽しい

今後の課題

  • Helmチャートのリファクタ
    • GitOps移行にあたって、マニフェストの可読性向上のためにKustomizeからHelmチャートへの移行も行ったのですが、割と自己流でHelmチャート化したので、最適化・リファクタの余地しかないような状態です笑 コマンドで公開されているチャートをダウンロードできるので、先人からベストプラクティスを学びつつ、随時アップデートしていこうと思います。
  • ドキュメント整備
    • GitOpsを導入したことによりCIとCDが以前よりも疎結合になりました。 パイプラインで一気通貫でデプロイまでやっていた頃と比べて、一見すると全体的なアーキテクチャが複雑化したようにも見えるので、しっかりドキュメント化しないといけないなーと思ってます。
  • ロールバックの属人化排除
    • 宣言的な定義をバージョン管理して、実際のリソースの状態が同期されるということは、任意のコミットまで戻せばリソースもその状態に戻ることを意味します。 つまりロールバックが簡単にできるようになります。 実際、コマンドでイメージタグを直接書き換えていた頃に比べて、格段にロールバックしやすくなりました。 とはいえ、それはあくまでCI/CDを運用・管理する側の感覚でしかなく、実際にプロダクト開発を行うエンジニアにとって「簡単に、かつ安全に」ロールバックできるかというと違うので、ロールバックを機能として仕組み化してプロダクトチーム全体が使える形で提供するところまでやりたいです。 もちろんロールバックする機会はめったにないですが、あるときは緊急事態なのでSREがいないとできない状況のままにはしたくないので。

今後やりたいこと

実は今回記事を書くにあたり、改めてArgoCDのドキュメント等を読んでいたのですが、ArgoCDはArgo Projectsという一連の関連するソフトウェア群の1プロジェクトなのだということを知りました。(今さらですが。。) Kubernetesでを実現できるや、Kubernetesネイティブの処理ワークフローを構築できるといった他のArgo一族の存在を知り興奮しています笑 特にが提供するリッチなデプロイ戦略は、ビジネスサイドがより良い判断下すための武器を提供できると思うので、チームの開発ロードマップに組み込もうと密かに画策しています(小声)

最後に

GitOps導入はプロダクト開発を直接的に楽にしたり、ビジネスに直接貢献する類のものではなく、あくまでSREチームのKubernetes周りの開発・運用効率を改善するものでした。 一方で、効率化によって新たに生み出せた時間で、プロダクトの価値向上やビジネス貢献につながるタスクにより多くのリソースを割くことができるようになったという点で価値があると思っています。 トイルとなっているプロセスを改善したり自動化することは長期的に見て効いてくるので、これからもガンガントイル減らしていくぞー!!という気持ちです。 ArgoCDの由来となっているであろうギリシャ神話を題材にした映画『アルゴ探検隊の大冒険』もArgoCDに負けず劣らず傑作なのでおすすめです!笑