LonghornのバックアップをS3に取る

ハードは壊れるという気持ち

家の自作PCの電源が急に壊れて起動しなくなり、ハードはいつか壊れるなという気持ちが高まった。

おうちK8sのPersistentVolumeのバックアップはもうちょいあとでいいかな〜と思ってたけどこのままだと絶対壊れるまでバックアップ取らないので強い気持ちでやっていく。


慣れてるのでS3に取っていこうと思う。


Longhornにおけるバックアップ設定の準備

https://longhorn.io/docs/1.8.1/snapshots-and-backups/backup-and-restore/set-backup-target/

バックアップのドキュメントはこれ。


https://longhorn.io/docs/1.8.1/concepts/#3-backups-and-secondary-storage

バックアップ自体の思想を見ると、その前にスナップショットの概念を抑えておくといいっぽい。

データを差分スナップショットとして小分けに持ってて、ある時点でのデータはいくつかのスナップショットに分散されて持たれているっぽい。そしてそれによって冗長性であったりfailoverであったりrollbackなども効率的にできているっぽいな。

対してバックアップの方はこのスナップショットをその時点の状態で平滑化して保持する感じになるっぽい。


何も設定していない状態だとdefaultのバックアップが設定されているらしい。何も明示的に設定したわけではないのでErrorになってら。


Set up AWS S3 Backupstore

https://longhorn.io/docs/1.8.1/snapshots-and-backups/backup-and-restore/set-backup-target/#set-up-aws-s3-backupstore


まずはバケットを作る。命名でlonghornのバックアップであるとわかるようになっていれば良いかな。public accessはもちろん不要。

Kubernetes上のPersistentVolumeの一つ一つに対してというよりはlonghorn全体としてバックアップストアとして利用するバケットなので特定のPersistentVolume名とかを含める必要はない。


次にIAM Userを作る。Policy作成時に許可するResourceは以下の通り。

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "GrantLonghornBackupstoreAccess0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::<your-bucket-name>",
"arn:aws:s3:::<your-bucket-name>/*"
]
}
]
}


認証方針はACCESS_KEYとSECRET_KEYを用いる方針を取る。

SealedSecretを利用するため以下のようにsecretをdry-runで作成する。

kubectl create secret generic longhorn-backup-aws-secret --dry-run=client \
--from-literal=AWS_ACCESS_KEY_ID=<your-aws-access-key-id> \
--from-literal=AWS_SECRET_ACCESS_KEY=<your-aws-secret-access-key> \
-n longhorn-system -o yaml > longhorn-backup-aws-secret.yaml
kubeseal --namespace longhorn-system -f longhorn-backup-aws-secret.yaml -w longhorn-backup-aws-sealed-secret.yaml --controller-name sealed-secrets-app --controller-namespace sealed-secrets


あとはlonghornのUI上で設定することでbackupを取るための準備は完了。ErrorになっていたバックアップステータスがAvailableになっていればOK。


バックアップの取得

https://longhorn.io/docs/1.8.1/snapshots-and-backups/backup-and-restore/create-a-backup/

バックアップにもIncremental BackupとFull Backupがあるっぽい。大したデータ量じゃないから都度Full Backupでも良い気がするけどスケジューリングとかどうしよう。


一旦UI経由でFull Backupをとることはできた。


https://longhorn.io/docs/1.8.1/snapshots-and-backups/scheduling-backups-and-snapshots/

Jobのような仕組みで自動で定期的にバックアップを取るにはCRDにしたがってRecurringJobを定義する必要がある模様。


https://github.com/longhorn/longhorn/blob/d471229c5ed117ef040fd34b6ec66f23535ec522/chart/templates/crds.yaml#L2304-L2310

CRDを読むに、parametersでfull-backup-intervalを設定するとfullbackupもとってくれるようになるっぽい。

バックアップ全体は二週間保持して、一週間に一回はfull backupをとるようにした。

(当初この時点でのyamlも載せていたがrecurring jobのCRDに沿っていないものになっていたようなので中略)


https://longhorn.io/docs/1.8.1/snapshots-and-backups/scheduling-backups-and-snapshots/#with-storageclass-parameters

どのPVCがどのJobでバックアップが取られるかということに関しては、StorageClassに設定するグループで制御できる。

StorageClass側に特に設定を行わなければPVCはdefault groupに属するため上記でカバーできている。


...と思ってクラスタにapplyしたがlonghornのUI上にRecurringJobが現れてこない...?少し様子見する。

kubectl get recurringjobs -A
NAMESPACE NAME GROUPS TASK CRON RETAIN CONCURRENCY AGE LABELS
longhorn-system full-backup-recurring-job ["default"] backup 0 0 * * * 14 1 77m

みたいに表示はされているから問題ないのかな。Web UI上で確認できるRecurringJobはWeb UI上で設定したものだけなのかも。

...と思ったが一向にbackupは取られないのでlonghornをupdateする。


longhornのupdate

https://github.com/longhorn/longhorn?tab=readme-ov-file#releases

https://longhorn.io/docs/1.8.1/deploy/upgrade/

ここでversionの一覧を見ることができる。1.8.0→1.8.1にupdateする。


https://longhorn.io/docs/1.8.1/deploy/upgrade/longhorn-manager/#upgrade-with-helm

helmを使っているのでここを参考にupgradeを行う。ArgoCDで管理されているのでChart.yamlでのversionを変えてpushするだけでOK

dependencies:
- name: longhorn
version: 1.8.1
repository: https://charts.longhorn.io

壊れているっぽかったrecurring-jobを消さないと延々とlonghorn-managerがhealthyにならなかったのでそのあたりは無理やり調整した。


apiVersion: longhorn.io/v1beta2
kind: RecurringJob
metadata:
name: full-backup-recurring-job
namespace: longhorn-system
spec:
name: full-backup-recurring-job
task: backup
retain: 14
concurrency: 1
cron: 0 0 * * *
parameters:
full-backup-interval: "6"
groups:
- default
labels: {}

最終的にUI経由で作成したrecurring-jobを-o yamlで吐き出してからArgoCDで管理するスタイルに変更。無事Web UIからも確認することができた。

当初の問題は壊れたrecurring-jobが一つでも存在しているとWebUIからrecurring-jobリソースが確認できなくなるという理由だったぽい。

Related Articles