Kubernetesバックアップツール
Veleroとちょっとした苦労話
2021/3/12 村田 一平
注意事項
2
• 以下のバージョンで話をします。
Velero, Restic:1.4.3, 1.5.3
Velero Plugin for vSphere (vSphere Plugin): 1.0.2
※ほとんど出てきません
• ログなどは見やすさを優先して一部加工している箇所もあります
• 開発が活発なため、実際に触る際は公式サイトもご参照お願いします
https://velero.io/docs/
Who are you?
3
村田 一平 (Murata Ippei)
• デグー飼ってます。
• メダカ、オトシンクルス、
クーリーローチ、ヤマトヌマエビ、飼ってます。
• TL: 41(あとイーブイ1進化でTL42)
Agenda
● セッションの内容説明
● Kubernetesのバックアップ
● Veleroとは
● Veleroの仕組み
● Veleroの機能
● Veleroで苦労したこと
● 最後に
4
Agenda
● セッションの内容説明
● Kubernetesのバックアップ
● Veleroとは
● Veleroの仕組み
● Veleroの機能
● Veleroで苦労したこと
● 最後に
5
セッションの内容説明
6
● 発表の目的:Veleroを知らない人に知ってもらう
 K8sのバックアップツールの紹介
 バックアップ以外のでの活用方法
 使う際の注意事項
 Veleroのすごく細かい話
 バックアップソフトの比較
 Veleroの運用事例
こういう内容はあります この辺はないです
Agenda
● セッションの内容説明
● Kubernetesのバックアップ
● Veleroとは
● Veleroの仕組み
● Veleroの機能
● Veleroで苦労したこと
● 最後に
7
Kuberneteのバックアップ
Kubernetesにバックアップは必要?
8
Kubernetesなら
自動復旧するし
とりあえず後回しで
TerraformとAnsibleで
すぐ作り直せるよ
Kuberneteのバックアップ
Spotifyの事例:2018年にやらかした話
9
KubeCon + CloudNativeCon Europe 2019
• 手動で誤って本番クラスタの削除を実行
(1回目)
• Terraformのスクリプトミスで
本番クラスタ消失(2回目)
• k8sへの移行途中で段階的移行を
取っていたので、サービス影響はなし
• 障害発生以降はTerraformで構築後
Ark(現Velero)でバックアップを実施
Agenda
● セッションの内容説明
● Kubernetesのバックアップ
● Veleroとは
● Veleroの仕組み
● Veleroの機能
● Veleroで苦労したこと
● 最後に
10
Veleroとは
11
● Heptio (K8sのFounderが立ち上げた会社)
が開発したKubernetes用バックアップOSS
● Kubernetesのリソース・オブジェクト
(PVやCRD含む)をバックアップ
● 現在はVMwareを中心に開発
'17/8
v0.3.0(Initial)
'19/5
v1.0.0
'21/1
v1.5.3(Latest)
Veleroの特徴
12
• マルチクラウドサポート
• PV、CRDを含めたバックアップ
• Namespace単位でのバックアップ
• プラグインによる拡張が可能
Veleroのユースケース
 障害対策としてバックアップ・リストア
 クラスタのマイグレーション
(オンプレミス ⇔ パブリッククラウド)
 クラスタの複製
13
バックアップ・リストア
こんな時に
 クラスタアップデート後に問題があった場合
 誤って主要なリソース・オブジェクトを削除
14
Kubernetesの環境構築は簡単
||
Kubernetesの環境を壊すのも簡単
マイグレーション
15
こんな時に
 AWSで作成した開発環境を
オンプレの検証環境に移行
 オンプレがリソース不足なので
一時的にAWSに移行
※環境依存のオブジェクト・リソースは
別途再作成する必要あり
クラスタの複製
こんな時に
• 開発者ごとにFluentbit, Prometheus, Harbor導入・設定済みの
クラスタを用意したい
• アップデート前に今のクラスタと同等構成で事前検証したい
16
Master Node
Worker Node
Worker Node
Worker Node
Master Node
Worker Node
Worker Node
Worker Node
Master Node
Worker Node
Worker Node
Worker Node
Agenda
● セッションの内容説明
● Kubernetesのバックアップ
● Veleroとは
● Veleroの仕組み
● Veleroの機能
● Veleroで苦労したこと
● 最後に
17
Veleroの構成
18
Master Node
Worker Node
Worker Node
Worker Node
CRD
backups
restores schedules
backupstoragelocations
volumesnapshotlocations
podvolumerestores
podvolumebacdkups resticrepositories
downloadrequests serverstatusrequests
deletebackuprequests
Velero + Restic Plugin(PV取得用プラグイン)導入時
Veleroの構成
19
Master Node
Worker Node
Worker Node
Worker Node
CRD
backups
restores schedules
backupstoragelocations
volumesnapshotlocations
podvolumerestores
podvolumebacdkups resticrepositories
downloadrequests serverstatusrequests
deletebackuprequests
Velero + Restic Plugin(PV取得用プラグイン)導入時
■構成はシンプル
• 司令塔となるDeployment
• 各Nodeに紐づくPVを吸い上げる
DaemonSet
(※Restic導入時)
Veleroの構成
20
Master Node
Worker Node
Worker Node
Worker Node
CRD
backups
restores schedules
backupstoragelocations
volumesnapshotlocations
podvolumerestores
podvolumebacdkups resticrepositories
downloadrequests serverstatusrequests
deletebackuprequests
Velero + Restic Plugin(PV取得用プラグイン)導入時
■CRDは多様
• ほとんどの機能・操作をCRDで実現
→ 操作の状況をkubectlでも確認可能
(veleroコマンドの方が使えないこと多々)
→ 消費リソースは抑え気味
• KubernetesのAPIで機能を実行
→ 非同期なので動きが読みづらいことも
Veleroの仕組み
21
オペレータ
# velero backup create
Master Node
Worker Node
Worker Node
Worker Node
カスタムリソースの
作成要求
(Kubernetes API)
MinIO
S3
ABS
GCS
etc
カスタムリソースの
作成要求
(Kubernetes API)
Agenda
● セッションの内容説明
● Kubernetesのバックアップ
● Veleroとは
● Veleroの仕組み
● Veleroの機能
● Veleroで苦労したこと
● 最後に
22
Backup/Restore
23
対象を絞ってのバックアップ・リストア
バックアップの例:
• Namespace
• Resource
• Label
• クラスタースコープ ※
velero restore create <backup-name> --include-namespaces <namespace1>,<namespace2>
velero restore create <backup-name> --include-resources deployments,configmaps
velero backup create <backup-name> --selector <key>=<value>
velero restore create <backup-name> --include-cluster-resources=false
※Namespaceと紐付かないもの。 PVやStorageClassなど。
kubectl api-resources でNAMSPACEDがfalseになっているリソース。
Backup/Restore
24
バックアップの内容はdescribe --detailsで確認可能
$ velero describe backup <backupname> --details
:(省略)
Resource List:
addons.cluster.x-k8s.io/v1alpha3/ClusterResourceSet:
- default/dummyworkload-cni-antrea
- default/dummyworkload-csi
- default/dummyworkload-default-storage-class
- default/dummyworkload-tkg-metadata
addons.cluster.x-k8s.io/v1alpha3/ClusterResourceSetBinding:
- default/dummyworkload
apiextensions.k8s.io/v1/CustomResourceDefinition:
- apps.kappctrl.k14s.io
- certificaterequests.cert-manager.io
:(省略)
バックアップ前後処理の実行
25
バックアップ前後に任意のコマンドが実行可能
kubectl annotate pod -n nginx-example -l app=nginx ¥
pre.hook.backup.velero.io/command='["/sbin/fsfreeze", "--freeze", "/var/log/nginx"]' ¥
pre.hook.backup.velero.io/container=fsfreeze ¥
post.hook.backup.velero.io/command='["/sbin/fsfreeze", "--unfreeze", "/var/log/nginx"]' ¥
post.hook.backup.velero.io/container=fsfreeze
※注意点
• コンテナ内にコマンドがない場合、コマンドが実行できるコンテナをPodに入れる必要あり
• fsfreezeなどボリューム操作を伴う場合はvolumeを共有する必要あり
• コマンドによっては強力な権限(privileged: true)が必要になる場合あり
ファイルシステムの静止化などで活用可能
リストア前後処理の実行
26
リストア前の処理についてはinitコンテナを立ち上げることで実施
$ kubectl annotate pod -n <POD_NAMESPACE> <POD_NAME> 
init.hook.restore.velero.io/container-name=restore-hook 
init.hook.restore.velero.io/container-image=alpine:latest 
init.hook.restore.velero.io/command='["/bin/ash", "-c", "date"]'
※注意点
• リストア前の処理はv1.4.x以前だと未対応。v1.5以降を使う必要あり
リストア後の処理指定はバックアップ時と同様
小ネタ1
進捗はveleroコマンドではなくPodから確認する
27
• バックアップの細かい進捗状況はveleroコマンドから確認不可
• PluginによってはVeleroの完了と非同期でバックアップを実行する ※後述、要注意
$ kubectl logs -n velero deploy/velero -f
:(省略)
time="2021-02-26T02:52:54Z" level=info msg="Processing item" backup=velero/cndo1151 logSource="pkg/backu
time="2021-02-26T02:52:54Z" level=info msg="Backing up item" backup=velero/cndo1151 logSource="pkg/backu
time="2021-02-26T02:52:54Z" level=info msg="Backed up 779 items out of an estimated total of 785 (estimate
$ velero restore logs testbk
Logs for restore "testbk" are not available until it's finished processing.
小ネタ2
veleroコマンドにない機能はKubernetesリソースから操作
(原則的には非推奨)
例)
28
Usage:
velero snapshot-location [command]
Available Commands:
create Create a volume snapshot location
get Get snapshot locations
Deleteが提供されていない
$ velero get snapshot-locations
NAME PROVIDER
default aws
vsl-vsphere velero.io/vsphere
$ kubectl delete volumesnapshotlocations.velero.io -n velero vsl-vsphere
volumesnapshotlocation.velero.io "vsl-vsphere" deleted
$ velero get snapshot-locations
NAME PROVIDER
default aws
CRDのオブジェクトを消す形で代用可能
小ネタ3
K8sのバージョンが異なるリストアについては保証されていない
Veleroのエンジニアコメント:
29
• k8sの2バージョンサポートのポリシーより、
アップデート直後のAPI互換性は期待している
• ただし、非互換になる問題も出てくると考えている
• 特にk8sクラスタの長期的な保存は今後の課題である
• K8sのVUP前後と定期的なバックアップを推奨する
PV用プラグインがサポートするVeleroのバージョンも注意
例)https://github.com/vmware-tanzu/velero-plugin-for-aws#compatibility
Agenda
● セッションの内容説明
● Kubernetesのバックアップ
● Veleroとは
● Veleroの仕組み
● Veleroの機能
● Veleroで苦労したこと
● 最後に
30
苦労1:あるある話
31
Resticを入れているのに、PVが取得されない
原因:
1. PodのAnnotationに"backup.velero.io/backup-volumes=<volume名>"
を書いている場合、Resticはそのボリュームをバックアップする
2. Annotationは誰も自動では書いてくれない ※1.5.1以降は自動化オプションあり
# mc ls -r minio
[2021-02-24 18:52:05 PST] 29B tkg/backups/fuga/fuga-csi-volumesnapshotcontents.json.gz
[2021-02-24 18:52:05 PST] 29B tkg/backups/fuga/fuga-csi-volumesnapshots.json.gz
:(pluginの下に何も作られない)
苦労1:あるある話
32
回避策:
Annotationでバックアップ対象を指定する
or
--default-volumes-to-restic オプションをつけてインストールしておく
(v1.5.1以降)
kubectl annotate pod testpod backup.velero.io/backup-volumes=testvol
:
volumes:
- name: testvol
persistentVolumeClaim:
claimName: velerotest
containers:
- name: busybox
image: busybox-test:1.29
command: [ "sleep", "365d" ]
:
苦労1:あるある話
33
回避策:
Annotationでバックアップ対象を指定する
or
--default-volumes-to-restic オプションをつけてインストールしておく
(v1.5.1以降)
kubectl annotate pod testpod backup.velero.io/backup-volumes=testvol
:
volumes:
- name: testvol
persistentVolumeClaim:
claimName: velerotest
containers:
- name: busybox
image: busybox-test:1.29
command: [ "sleep", "365d" ]
:
教訓
• ドキュメントは部分的ではなく一通り読む
※ドキュメントがあまり整理されていない
苦労2:オフライン固有
34
オフライン環境で、PV含むリストア時にInProgressで固まる。
kubectl get podすると、リストア対象のPodがInitコンテナを持っていないのに何故かInit処理で死んでいる。
原因:
1. resticプラグイン利用時、PVリストアの際にInitコンテナを作成する
2. Initコンテナのイメージをオフライン環境に持ち込んでいない
3. Initコンテナのイメージの参照先が変更されていない
$ kubectl describe pod -n velerotest testpod
Warning Failed 5m7s (x4 over 6m37s) Error: ErrImagePull
Warning Failed 4m29s (x7 over 6m37s) Error: ImagePullBackOff
Normal BackOff 94s (x19 over 6m37s) Back-off pulling image "velero/velero-restic-restore-helper:v1.4.3"
苦労2:オフライン固有
35
回避策:
• velero-restic-restore-helperを持ち込む
• Configmapを作成してimageのパスを指定する
velero.io/docsの記載より
分かりづらい点:
• 「Air-gapped deployments」のところに
Configmapの話がない
• 「Restic Integration」の箇所には記載があるが、
目的がカスタマイズするためとなっており、
問題と関連付けにくい
• デフォルトのConfigmapもなく、記載箇所を
見つけられなかった場合にimageの指定箇所の
特定が非常に困難
苦労2:オフライン固有
36
回避策:
• velero-restic-restore-helperを持ち込む
• Configmapを作成してimageのパスを指定する
velero.io/docsの記載より
分かりづらい点:
• 「Air-gapped deployments」のところに
Configmapの話がない
• 「Restic Integration」の箇所には記載があるが、
目的がカスタマイズするためとなっており、
問題と関連付けにくい
• デフォルトのConfigmapもなく、記載箇所を
見つけられなかった場合にimageの指定箇所の
特定が非常に困難
教訓
• ドキュメントは部分的ではなく一通り読む
※ドキュメントがあまり整理されていない
苦労3:完了の確認
37
バックアップ実行後、状態がCompletedになったにも関わらず、
プラグイン側は完了せず動き続けているように見える。
この状態でリストアを実行するとPVのリストアに失敗する
$ kubectl logs -n velero ds/datamgr-for-vsphere-plugin -f
:(省略)
msg="Upload ongoing, Part: 84 Bytes Uploaded: 840 MB"
msg="Read returning 10485760, len(p) = 10485760, offset=891289600n"
msg="Upload ongoing, Part: 85 Bytes Uploaded: 850 MB"
msg="Read returning 10485760, len(p) = 10485760, offset=901775360n"
原因:
vSphere Plugin利用時、PVのバックアップはVeleroのバックアップと非同期で実施される
苦労3:完了の確認
38
回避策:
プラグインのログからPVのバックアップの完了を確認してからリストアする
またはCRDの状態から確認する
$ kubectl logs -n velero ds/datamgr-for-vsphere-plugin
:(省略)
msg="Upload status updated from InProgress to Completed"
msg="Upload Completed"
$ kubectl get upload -n velero -o jsonpath={.items[*].status.phase}
Completed
※プラグインによって挙動が違うと考えられるため、利用するプラグインごとに確認すること
苦労3:完了の確認
39
回避策:
プラグインのログからPVのバックアップの完了を確認してからリストアする
またはCRDの状態から確認する
$ kubectl logs -n velero ds/datamgr-for-vsphere-plugin
:(省略)
msg="Upload status updated from InProgress to Completed"
msg="Upload Completed"
$ kubectl get upload -n velero -o jsonpath={.items[*].status.phase}
Completed
※プラグインによって挙動が違うと考えられるため、利用するプラグインごとに確認すること
教訓
• プラグインの扱いが本体と分離している
• Velero本体の挙動だけでなく、プラグインの
挙動を理解した上で利用する
苦労4:本体のバグ
E0105 21:55:15.865928 1 runtime.go:78] Observed a panic: "invalid memory address or nil pointer dereference" (runtime error: invalid memory address or nil pointer dereference) goroutine
551 [running]: k8s.io/apimachinery/pkg/util/runtime.logPanic(0x163e040, 0x26dfda0) /go/pkg/mod/k8s.io/apimachinery@v0.17.9/pkg/util/runtime/runtime.go:74 +0xa3
k8s.io/apimachinery/pkg/util/runtime.HandleCrash(0x0, 0x0, 0x0)
40
CAPIを含むクラスタをリストアすると、 capi-controller-managerがリストア後にpanicする
原因:
1. Veleroはリソースをアルファベット順で復元する
2. CRDによっては、あるリソースのオブジェクトが先に作られていることを前提としている
(今回の場合はClusterResourceSetBindingsはClusterResourceSetsが
先に起動するのを前提としている)
回避策:
Veleroの引数で起動順序を指定する(--restore-resource-priorities)
※このオプションで指定したリソースが優先的にリストア
指定しなかったものはアルファベット順
※v1.6.0で対策予定 参考: https://github.com/kubernetes-sigs/cluster-api/issues/4105
https://github.com/vmware-tanzu/velero/pull/3446
苦労4:本体のバグ
E0105 21:55:15.865928 1 runtime.go:78] Observed a panic: "invalid memory address or nil pointer dereference" (runtime error: invalid memory address or nil
pointer dereference) goroutine 551 [running]: k8s.io/apimachinery/pkg/util/runtime.logPanic(0x163e040, 0x26dfda0)
/go/pkg/mod/k8s.io/apimachinery@v0.17.9/pkg/util/runtime/runtime.go:74 +0xa3 k8s.io/apimachinery/pkg/util/runtime.HandleCrash(0x0, 0x0, 0x0)
41
CAPIを含むクラスタをリストアすると、 capi-controller-managerがリストア後にpanicする
原因:
1. Veleroはリソースをアルファベット順で復元する
2. CRDによっては、あるリソースのオブジェクトが先に作られていることを前提としている
(今回の場合はClusterResourceSetBindingsはClusterResourceSetsが
先に起動するのを前提としている)
回避策:
Veleroの引数で起動順序を指定する(--restore-resource-priorities)
※このオプションで指定したリソースが優先的にリストア
指定しなかったものはアルファベット順
※v1.6.0で対策予定 参考: https://github.com/kubernetes-sigs/cluster-api/issues/4105
https://github.com/vmware-tanzu/velero/pull/3446
教訓
• リコンサイルループで復旧しないリソースもある
• CRD関連の挙動を全て把握するのは困難
→ ユースケースベースでの事前検証は大事
• 怪しいと思ったら中の人に早く聞く
(velero bugコマンド)
苦労5:プラグインのバグ
# mc ls -r minio
[2021-02-23 22:33:58 PST] 0B tkg/plugins/vsphere-astrolabe-repo/ivd/data/ivd:xxxx
[2021-02-23 22:33:59 PST] 3.1KiB tkg/plugins/vsphere-astrolabe-repo/ivd/md/ivd:xxxx
[2021-02-23 22:33:59 PST] 984B tkg/plugins/vsphere-astrolabe-repo/ivd/peinfo/ivd:xxxx
42
PVのバックアップが正常に成功するも、サイズがゼロbyte ※vSphere plugin利用時
原因:
1. PVの要求サイズをテスト用に1MBと小さい値を指定していた
2 . vSphere Pluginが10MB未満のPVはデータを取りに行かない作りになっていた
対策:
PVのサイズを変更(念の為100MB程度に)
苦労5: プラグインのバグ
# mc ls -r minio
[2021-02-23 22:33:58 PST] 0B tkg/plugins/vsphere-astrolabe-repo/ivd/data/ivd:xxxx
[2021-02-23 22:33:59 PST] 3.1KiB tkg/plugins/vsphere-astrolabe-repo/ivd/md/ivd:xxxx
[2021-02-23 22:33:59 PST] 984B tkg/plugins/vsphere-astrolabe-repo/ivd/peinfo/ivd:xxxx
43
PVのバックアップが正常に成功するも、サイズがゼロbyte ※vSphere plugin利用時
原因:
1. PVの要求サイズをテスト用に1MBと小さい値を指定していた
2 . vSphere Pluginが10MB未満のPVはデータを取りに行かない作りになっていた
対策:
PVのサイズを変更(念の為100MB程度に)
教訓
• 仕様として明記されていないものは
テストされていない可能性がある
• 実態にあったケースでテストする
Agenda
● セッションの内容説明
● Kubernetesのバックアップ
● Veleroとは
● Veleroの仕組み
● Veleroの機能
● Veleroで苦労したこと
● 最後に
44
最後に
言いたかったこと
• Kubernetes向けのバックアップソフトを活用しよう!
• Veleroがんばってるよ!
• ハマりどころがちょいちょいあるので、事前検証はしっかりやろう!
• 公式ドキュメントは頑張って隅々まで読もう
• 何か見つけたらvelero bugコマンド
45
ご静聴ありがとうございました
46

KubernetesバックアップツールVeleroとちょっとした苦労話