Argo Workflowsを使ったPersistentVolumeの定期バックアップ
こんにちは。
インフラグループKubernetesチームの福田です。
今回はPV(PersistentVolume)の定期バックアップシステムについて紹介したいと思います。
PVのバックアップについて
PVのバックアップといっても色々とありますが、本記事ではスナップショットの取得を意味します。
スナップショットの取得はCSIが対応していれば、external-snapshotterを利用することで、CustomResourceを書くだけで実現できます。
extenal-snapshotterを全く知らない方は以下のAWSの記事が概要を掴む参考になるかと思います。
バックアップシステムの仕組み
概要
システムの概要は以下のようになっています。
- Argo Workflowsが定期的にVolumeSnapshotリソースを作成し、それをGitLabへプッシュする。
- GitLabのCIがマニフェストをバリデーションする。
- Argo CDがマニフェストのあるコードリポジトリの変更を検出して、それをKubernetesにデプロイする。
詳細
定期的に実行する処理
定期的な処理の実行はCronWorkflowで行っています。 単にCronJobとせず、CronWorkflowとした理由は、一度だけの実行や、定期処理の一時停止などがGUIで簡単にできるからです。
VolumeSnapshotリソースの生成
VolumeSnapshotリソースの生成を行うアプリケーションはGolangで実装した自前のコンテナアプリになります。
コンテナアプリは前述したCronWorkflowで実行されます。
世代管理機能
コンテナアプリはVolumeSnapshotマニフェストを生成すると共に、古いVolumeSnapshotマニフェストを削除するローテーション機能を持っています。
何世代分までのVolumeSnapshotマニフェストを維持するかは環境変数で指定可能になっています。
VolumeSnapshotマニフェスト間の新旧の比較はVolumeSnapshotマニフェスト生成時のタイムスタンプを独自のアノテーションに記載し、それを比較することで実現しています。
管理対象フラグ
ローテーション管理の対象とする否かのフラグを表現する独自のアノテーションもあります。
原則、コンテナアプリで生成されたVolumeSnapshotはこのフラグが立っています。
手動で作成したVolumeSnapshotやコンテナアプリによって作成された永続的に残しておきたいスナップショットについては、このフラグを下ろすことでローテーションの管理対象から外れて自動で削除されないようにできます。
生成されるマニフェストのサンプル
apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshot metadata: name: SAMPLE_NAME namespace: SAMPLE_NAMESPACE annotations: snapshot-tools.enigmo.co.jp/rotation: "true" snapshot-tools.enigmo.co.jp/rtime: 12345678 spec: source: persistentVolumeClaimName: SAMPLE_PVC volumeSnapshotClassName: SAMPLE_VSC
snapshot-tools.enigmo.co.jp/rtime
アノテーションはマニフェスト生成時のタイムスタンプを表現している。snapshot-tools.enigmo.co.jp/rotation
アノテーションは世代管理の対象とするか否かのフラグになっている。
コードプッシュ
コンテナアプリはVolumeSnapshotマニフェストを作成、削除するとその変更をプッシュします。 プッシュ時のオプションでMergeRequest(githubでいうPullRequest)を作成し、CIが成功したら自動でMRをマージするようにしています。
CIの実行
MRに対しては手動によるマニフェストのデプロイと同じ条件でCIが周り、問題がなければそれをマージするようになっています。
これにより、システムが生成したマニフェストコードを特別扱いすることなく、統一したポリシー(例えば、フォーマッタやセキュリティチェック等のマニフェストに対するバリデーション)を適用できます。
Argo CDによるデプロイ
masterにマージされた変更を検出し、それをクラスタへ自動で適用するようにauto-syncを有効化しています。
また、世代管理機能によってVolumeSnapshotマニフェストの削除される場合もあるので、auto-pruneも有効化しています。
以下がArgoCD Applicationのサンプルになります。
apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: snapshots spec: generators: - list: elements: - namespace: SAMPLE_NS1 - namespace: SAMPLE_NS2 - namespace: SAMPLE_NS3 template: metadata: name: '{{namespace}}-snapshot' spec: project: SAMPLE-PROJECT source: repoURL: GITLAB_URL targetRevision: master path: SAMPLE_PATH destination: server: K8S_ENDPOINT namespace: '{{namespace}}' syncPolicy: automated: prune: true
純粋なApplicationでなく、ApplicationSetとしている理由は我々は複数ネームスペースの運用をしているためです。 (Argo CDのApplicationは1つのネームスペースしかデプロイ先として指定できない。)
まとめ
Argo Workflowsを使ったPersistentVolumeの定期バックアップシステムについて紹介させていただきました。
実装方法としてオペレータパターンで開発する選択肢もありましが、cronの一時停止やカウントダウンタイマーなどをGUIで管理できる点からArgo WorkflowsのCronWorkflowを利用する実装を選択しました。
今回の記事がKubernetesネイティブな自動化システムの開発の参考になれば幸いです。
エニグモではエンジニアを含む各種ポジションで求人を募集しております。
株式会社エニグモ すべての求人一覧