はじめに
こんにちは。SRE部の巣立(@ksudate)です。
ZOZOTOWNのマイクロサービス基盤では、GitHub Actionsを利用したCDパイプラインを構築しています。しかし、管理するマイクロサービスが増えるにつれて運用負荷が高まりつつありました。
本記事では、ZOZOTOWNのマイクロサービス基盤のCDパイプラインが抱える課題と、それらをFlux2でどのように解決したのかを紹介します。また、Flux2の導入にあたり工夫したポイントを紹介します。
Flux2の導入背景
マイクロサービス基盤のCI/CDパイプラインが抱える課題とこれまでの対策
マイクロサービス基盤では、アプリケーションのソースコードとKubernetesマニフェストを別々のリポジトリで管理しています。また、マニフェストを管理するリポジトリは複数のアプリケーションのマニフェストを含んでいます。
それぞれのリポジトリ上で稼働するCI/CDパイプラインは以下のような構成になっていました。
アプリケーションリポジトリではECRへImageがPushされます。PushされたImageをクラスタへ反映するにはインフラリポジトリのマニフェストを更新します。そのため、KubernetesクラスタへのデプロイはインフラリポジトリのGitHub Actionsから実行されます。GitHub ActionsによるCI/CDパイプラインで実行するkubectl diffとkubectl applyは全てのマイクロサービスに対して実行します。そのため、マイクロサービスが増えるとCI/CDが完了するまでの時間も増えていく構成となります。
CI/CDパイプラインではKubernetesクラスタへデプロイするJobだけでなくCloudFormationやTerraformを利用したデプロイを行うJobも同じワークフローで管理しています。そのため、CloudFormation・Terraformに対する変更の場合でも毎回kubectl diffとkubectl applyが実行されます。
そこでpaths-filterを利用することにしました。paths-filterを使うことでPull Requestに含まれる変更内容によって実行するJobを制御できるようになります。例えば、Kubernetesマニフェストに変更があった場合のみkubectl diffとkubectl applyを実行するといったことが可能になります。
paths-filterによりCI/CDの高速化に成功したのですが、依然としてkubectl diffとkubectl applyの長期化は解決しない状況でした。そのため、paths-filterを利用してマニフェストに変更があったマイクロサービスに対してkubectl diffとkubectl applyを実行する構成を考えました。しかし、この方法では条件分岐が増えることでワークフローが複雑になったり、マイクロサービスが増えるたびにJobが肥大化したりといくつか問題がありました。
そこで候補として上がったのがFlux2です。
Flux2とは?
Flux2はGitリポジトリで宣言された状態とクラスタの状態を同期するGitOpsツールの1つです。類似のOSSとしてArgoCDが挙げられます。Flux2ではKustomizeで組み立てられたマニフェストをクラスタへ同期できます。そのため、Kustomizeを利用してマイクロサービスごとにマニフェストを生成し同期することが可能になります。
今回、ArgoCDではなくFlux2を採用したのは既にマイクロサービス基盤で利用しているFlaggerがFlux2と同じFlux Projectに所属しているため親和性が高いことを期待しました。Flaggerについては近日テックブログで公開する予定です。
Flux2によるGitOpsの実現
ここでは、Flux2のアーキテクチャと仕組みについて簡単に解説します。
Flux2はGitOps Toolkitと呼ばれるいくつかのコンポーネントにより動作します。
Source Controllerでは、Git、S3などからアーティファクトという形で外部ソースを取得します。アーティファクトはGitコミットのハッシュ値つまり、リビジョン番号を持ち、アーティファクトが更新されるとリビジョン番号も更新されます。
Kustomize Controllerでは、Source Controllerが取得したアーティファクトを元にクラスタへマニフェストを適用します。クラスタへ適用する間隔はCustom Resourceの設定により可能ですが、リビジョン番号が更新された場合は設定に関係なくクラスタへ適用されます。また、アーティファクトからマニフェストを生成する際には、kustomize buildを使用します。
その他Flux2が提供する機能について詳しくは公式ドキュメントをご覧ください。
Flux2の同期の設定は、Custom Resourceにより設定できます。ここでは、GitRepositoryとKustomizationの2つのCustom Resourceについて簡単に紹介します。
GitRepositoryでは、Source ControllerがGitリポジトリからソースを取得する際の設定を書きます。これを各マイクロサービス毎に作成しています。同じNamespaceに複数のGitRepositoryを配置できるため、複数のマイクロサービスが配置されている場合でも問題なく動作します。
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
name: flux-system
namespace: flux-system
spec:
interval: 1m0s
ref:
branch: master
secretRef:
name: zozo-flux-system-secrets-202206141800
url: https://github.com/stefanprodan/podinfo
KustomizationではKustomize Controllerがマニフェストをクラスタへ適用する際の設定を書きます。KustomizationもGitRepository同様にマイクロサービス毎に作成しています。なお、検証作業等のためにクラスタへの適用を一時的に停止したい場合は、spec.suspendをtrueにします。
続きはこちら