- はじめに
- Veleroのアーキテクチャと動作原理
- インストールと初期設定
- スケジュールバックアップ戦略とRTO/RPO設計
- CSIスナップショット連携の詳細
- クロスクラスタ移行
- マルチリージョンDR戦略
- バックアップツールの比較: Velero vs Kasten K10 vs etcdバックアップ
- バックアップ前後のフック(Hook)活用
- モニタリングと通知の体系
- トラブルシューティングガイド
- 運用上の注意点とベストプラクティス
- DR復旧訓練チェックリスト
- おわりに
- 参考資料

はじめに
Kubernetesクラスタを本番で運用していると、「もしこのクラスタが丸ごと消えたらどうなるのか」という問いに直面します。etcd障害、クラウドリージョン障害、誤ったHelmリリースのロールバック、うっかりによるネームスペース削除など、データ損失を引き起こすシナリオは思っているより多様です。
Velero(旧Heptio Ark)はVMware(現Broadcom)が主導するオープンソースプロジェクトで、Kubernetesリソースとパーシステントボリューム(PV)をバックアップおよび復元するための事実上の標準ツールです。Veleroを活用すると、ネームスペース単位のバックアップ、CSIボリュームスナップショット、クロスクラスタ移行、スケジュールベースの自動バックアップなどを実現できます。
本記事では、Veleroのアーキテクチャから始めて、インストール、スケジュールバックアップの設定、CSIスナップショット連携、マルチリージョンDR戦略、クロスクラスタ移行、そして実際の障害事例ごとの復旧手順まで、運用の現場でそのまま適用できるレベルで扱います。
Veleroのアーキテクチャと動作原理
主要コンポーネント
VeleroはサーバーサイドのコンポーネントとCLIクライアントで構成されます。
- Velero Server (Deployment): クラスタ内でバックアップ/復元の処理をオーケストレーションするコントローラーです。CRD(Custom Resource Definition)ベースで動作し、Backup、Restore、Scheduleなどのリソースを監視して処理します。
- Node Agent (DaemonSet): ファイルシステムバックアップ(FSB)を担当します。以前はResticが使われていましたが、Velero 1.12からKopiaが既定のアップローダーとして採用され、性能と安定性が向上しました。
- BackupStorageLocation (BSL): バックアップデータを保存するオブジェクトストレージの場所を定義します。AWS S3、GCS、Azure Blob Storage、MinIOなどをサポートします。
- VolumeSnapshotLocation (VSL): ボリュームスナップショットを作成するクラウドプロバイダのリージョンを指定します。
- Velero CLI: ユーザーがバックアップ/復元/スケジュールのコマンドを実行するコマンドラインツールです。
バックアップ方式の比較: CSIスナップショット vs ファイルシステムバックアップ
Veleroはパーシステントボリュームのデータをバックアップする2つの方式を提供します。
CSIスナップショット方式: Kubernetes CSI VolumeSnapshot APIを活用して、ストレージプロバイダレベルのスナップショットを作成します。ブロックレベルのスナップショットのため速度が速く、一貫性も高いです。ただしCSIドライバがスナップショットをサポートしている必要があります。
ファイルシステムバックアップ(FSB)方式: Kopia(またはRestic)を使ってPV内のファイルをオブジェクトストレージへ直接アップロードします。ストレージプロバイダに依存せず動作しますが、ファイルレベルのコピーのため大容量ボリュームでは時間がかかります。
| 区分 | CSIスナップショット | ファイルシステムバックアップ(Kopia) |
|---|---|---|
| 速度 | 速い(ブロックレベル) | 遅い(ファイルレベル) |
| ストレージ依存性 | CSIドライバが必須 | 汎用(すべてのPVに対応) |
| 一貫性 | クラッシュ一貫性を保証 | ファイル単位の一貫性 |
| クロスリージョン復元 | 限定的(スナップショットのリージョンに依存) | 容易(オブジェクトストレージベース) |
| リソース負荷 | 低い | 高い(CPU/メモリ) |
| 増分バックアップ | ストレージ依存 | Kopiaが内蔵でサポート |
バックアップの流れの詳細
Veleroがバックアップを実行する順序は次の通りです。
- ユーザーがBackup CRを作成すると、Veleroコントローラーがそれを検知します。
- Kubernetes APIを通じて対象リソース(Deployment、Service、ConfigMap、Secret、CRDなど)を取得し、JSONへシリアライズします。
- シリアライズしたリソースをtarballへ圧縮し、BSL(オブジェクトストレージ)へアップロードします。
- PVが含まれる場合は、選択した方式(CSIスナップショットまたはFSB)でボリュームデータをバックアップします。
- バックアップのメタデータとログもBSLへ保存します。
インストールと初期設定
事前要件
# Velero CLIのインストール(最新の安定版)
curl -fsSL -o velero-v1.15.0-linux-amd64.tar.gz \
https://github.com/vmware-tanzu/velero/releases/download/v1.15.0/velero-v1.15.0-linux-amd64.tar.gz
tar -xvf velero-v1.15.0-linux-amd64.tar.gz
sudo mv velero-v1.15.0-linux-amd64/velero /usr/local/bin/
# バージョン確認
velero version --client-only
# CSIスナップショットを使う場合はCRDのインストールを確認
kubectl get crd | grep volumesnapshot
# volumesnapshotclasses.snapshot.storage.k8s.io
# volumesnapshotcontents.snapshot.storage.k8s.io
# volumesnapshots.snapshot.storage.k8s.io
AWS S3ベースのインストール
最も多く使われるAWS S3を対象にしたインストール例です。
# S3バケットの作成
aws s3api create-bucket \
--bucket velero-backup-prod \
--region ap-northeast-2 \
--create-bucket-configuration LocationConstraint=ap-northeast-2
# IAM認証情報ファイルの作成
cat > credentials-velero <<EOF
[default]
aws_access_key_id=<YOUR_ACCESS_KEY>
aws_secret_access_key=<YOUR_SECRET_KEY>
EOF
# Veleroのインストール(CSIスナップショット + Node Agentを有効化)
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.11.0 \
--bucket velero-backup-prod \
--backup-location-config region=ap-northeast-2 \
--snapshot-location-config region=ap-northeast-2 \
--secret-file ./credentials-velero \
--use-node-agent \
--features EnableCSI \
--wait
# インストールの確認
kubectl get pods -n velero
# NAME READY STATUS RESTARTS AGE
# node-agent-xxxxx 1/1 Running 0 30s
# node-agent-yyyyy 1/1 Running 0 30s
# velero-xxxxxxxxx-zzzzz 1/1 Running 0 30s
Helmチャートを活用したインストール
本番環境では、Helmチャートを活用して宣言的に管理することが推奨されます。
# values-velero.yaml
configuration:
backupStorageLocation:
- name: default
provider: aws
bucket: velero-backup-prod
config:
region: ap-northeast-2
volumeSnapshotLocation:
- name: default
provider: aws
config:
region: ap-northeast-2
features: EnableCSI
defaultVolumesToFsBackup: false
credentials:
useSecret: true
secretContents:
cloud: |
[default]
aws_access_key_id=<YOUR_ACCESS_KEY>
aws_secret_access_key=<YOUR_SECRET_KEY>
initContainers:
- name: velero-plugin-for-aws
image: velero/velero-plugin-for-aws:v1.11.0
volumeMounts:
- mountPath: /target
name: plugins
- name: velero-plugin-for-csi
image: velero/velero-plugin-for-csi:v0.8.0
volumeMounts:
- mountPath: /target
name: plugins
deployNodeAgent: true
nodeAgent:
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: '2'
memory: 2Gi
resources:
requests:
cpu: 500m
memory: 256Mi
limits:
cpu: '1'
memory: 1Gi
schedules:
daily-production:
disabled: false
schedule: '0 2 * * *'
useOwnerReferencesInBackup: false
template:
ttl: '168h'
includedNamespaces:
- production
- staging
snapshotVolumes: true
storageLocation: default
volumeSnapshotLocations:
- default
# Helmでインストール
helm repo add vmware-tanzu https://vmware-tanzu.github.io/helm-charts
helm repo update
helm install velero vmware-tanzu/velero \
--namespace velero \
--create-namespace \
-f values-velero.yaml
スケジュールバックアップ戦略とRTO/RPO設計
RTOとRPOの概念整理
Disaster Recovery戦略の核心は2つの指標にあります。
- RPO (Recovery Point Objective): 許容できる最大のデータ損失量を時間で表したものです。RPOが1時間なら、最大1時間分のデータ損失を許容できるという意味です。
- RTO (Recovery Time Objective): 障害の発生後、サービスを正常な状態へ復旧するまでに許容される最大時間です。
Veleroのバックアップ周期がRPOを決め、復元手順の速度がRTOを決めます。
ワークロード等級別のバックアップ戦略
| ワークロード等級 | RPO目標 | バックアップ周期 | 保存期間 | バックアップ方式 |
|---|---|---|---|---|
| Tier 1(ミッションクリティカル) | 1時間 | 毎時 | 72時間 | CSIスナップショット + FSB |
| Tier 2(業務の中核) | 4時間 | 6時間ごと | 7日 | CSIスナップショット |
| Tier 3(一般) | 24時間 | 1日1回 | 30日 | FSB |
| Tier 4(開発/テスト) | 1週間 | 週1回 | 14日 | FSB |
スケジュールバックアップのYAML例
# Tier 1: ミッションクリティカルなワークロード - 毎時バックアップ
apiVersion: velero.io/v1
kind: Schedule
metadata:
name: tier1-hourly-backup
namespace: velero
spec:
schedule: '0 * * * *'
useOwnerReferencesInBackup: false
template:
ttl: 72h0m0s
includedNamespaces:
- payment
- order-service
snapshotVolumes: true
storageLocation: default
volumeSnapshotLocations:
- default
defaultVolumesToFsBackup: false
metadata:
labels:
backup-tier: 'tier1'
environment: 'production'
---
# Tier 3: 一般ワークロード - 日次バックアップ
apiVersion: velero.io/v1
kind: Schedule
metadata:
name: tier3-daily-backup
namespace: velero
spec:
schedule: '0 2 * * *'
useOwnerReferencesInBackup: false
template:
ttl: 720h0m0s
includedNamespaces:
- monitoring
- logging
- internal-tools
snapshotVolumes: false
defaultVolumesToFsBackup: true
storageLocation: default
metadata:
labels:
backup-tier: 'tier3'
environment: 'production'
賢い保存ポリシー(GFSパターン)
Grandfather-Father-SonパターンをVeleroのスケジュールで実装すると、短期的にはきめ細かい復旧ポイントを維持しつつ、長期的にはストレージコストを削減できます。
# 時間別バックアップ(24時間保存)
velero schedule create hourly-backup \
--schedule="0 * * * *" \
--ttl 24h0m0s \
--include-namespaces production \
--snapshot-volumes
# 日別バックアップ(7日保存)
velero schedule create daily-backup \
--schedule="0 3 * * *" \
--ttl 168h0m0s \
--include-namespaces production,staging \
--snapshot-volumes
# 週別バックアップ(30日保存)
velero schedule create weekly-backup \
--schedule="0 4 * * 0" \
--ttl 720h0m0s \
--snapshot-volumes
# 月別バックアップ(365日保存)
velero schedule create monthly-backup \
--schedule="0 5 1 * *" \
--ttl 8760h0m0s \
--snapshot-volumes
CSIスナップショット連携の詳細
CSIスナップショットコントローラーのインストール
CSIスナップショットを活用するには、クラスタにスナップショットコントローラーとCRDがインストールされている必要があります。
# CSIスナップショットCRDのインストール
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v8.2.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v8.2.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v8.2.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml
# スナップショットコントローラーのインストール
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v8.2.0/deploy/kubernetes/snapshot-controller/rbac-snapshot-controller.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v8.2.0/deploy/kubernetes/snapshot-controller/setup-snapshot-controller.yaml
VolumeSnapshotClassの設定
VeleroがCSIスナップショットを使うには、VolumeSnapshotClassに特定のラベルが必要です。
# AWS EBS CSIドライバ用のVolumeSnapshotClass
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: ebs-csi-snapclass
labels:
velero.io/csi-volumesnapshot-class: 'true'
driver: ebs.csi.aws.com
deletionPolicy: Retain
parameters:
tagSpecification_1: 'velero-backup=true'
velero.io/csi-volumesnapshot-class: "true" ラベルが設定されたVolumeSnapshotClassをVeleroが自動的に検知し、CSIスナップショットの作成に使用します。deletionPolicyをRetainに設定すると、VolumeSnapshotリソースが削除されても実際のスナップショットデータは保存されます。
CSIスナップショットのデータ移動(Data Mover)
CSIスナップショットは基本的にストレージプロバイダ内へローカルに保存されます。クロスリージョンまたはクロスクラウドのDRのためには、スナップショットデータをオブジェクトストレージへ移動する必要があります。Velero 1.12から内蔵のData Moverがこの機能を提供します。
apiVersion: velero.io/v1
kind: Backup
metadata:
name: production-with-datamover
namespace: velero
spec:
includedNamespaces:
- production
snapshotMoveData: true
storageLocation: default
datamover: velero
snapshotVolumes: true
snapshotMoveData: true を指定すると、CSIスナップショットの作成後にそのデータをBSLのオブジェクトストレージへコピーします。これにより、元のスナップショットが特定のリージョンに依存する問題を解決できます。
クロスクラスタ移行
移行アーキテクチャ
Veleroを活用したクロスクラスタ移行の核心は、ソースクラスタとターゲットクラスタが同じBSL(オブジェクトストレージ)を共有することです。ソースクラスタで作成したバックアップへターゲットクラスタがアクセスして復元できます。
移行の流れ:
- ソースクラスタで移行対象ネームスペースのバックアップを作成
- ターゲットクラスタにVeleroをインストール(同一のBSL構成)
- ターゲットクラスタでBSLを同期してバックアップ一覧を確認
- 選択したバックアップから復元を実行
- 復元されたリソースの検証とDNS/Ingressの切り替え
移行の実行手順
# [ソースクラスタ] 移行用バックアップの作成
velero backup create migration-app-v2 \
--include-namespaces app-v2 \
--snapshot-volumes \
--snapshot-move-data \
--wait
# バックアップ状態の確認
velero backup describe migration-app-v2 --details
# [ターゲットクラスタ] BSLの同期(Veleroが同一のS3を参照している必要あり)
# 既定では1分間隔で同期、即時の同期は以下のコマンドで実行
kubectl -n velero patch backupstoragelocation default \
--type merge \
--patch '{"spec":{"accessMode":"ReadOnly"}}'
# しばらくしてからReadWriteへ戻す
kubectl -n velero patch backupstoragelocation default \
--type merge \
--patch '{"spec":{"accessMode":"ReadWrite"}}'
# バックアップ一覧の確認
velero backup get
# [ターゲットクラスタ] 復元の実行
velero restore create migration-restore \
--from-backup migration-app-v2 \
--namespace-mappings app-v2:app-production \
--wait
# 復元結果の確認
velero restore describe migration-restore --details
kubectl get pods -n app-production
ネームスペースのマッピングとリソースのフィルタリング
移行時にネームスペース名の変更や特定リソースの除外が必要になる場合が多いです。
# ネームスペース名を変更して復元
velero restore create --from-backup my-backup \
--namespace-mappings old-namespace:new-namespace
# 特定のリソース種別のみ復元
velero restore create --from-backup my-backup \
--include-resources deployments,services,configmaps,secrets
# 特定のリソース種別を除外して復元
velero restore create --from-backup my-backup \
--exclude-resources storageclasses,persistentvolumes
# ラベルセレクタで特定のリソースのみ復元
velero restore create --from-backup my-backup \
--selector app=frontend
マルチリージョンDR戦略
マルチBSL構成
本番環境では単一のオブジェクトストレージに依存せず、複数のBSLを構成して地理的な二重化を確保する必要があります。
# Primary BSL - ソウルリージョン
apiVersion: velero.io/v1
kind: BackupStorageLocation
metadata:
name: primary-seoul
namespace: velero
spec:
provider: aws
objectStorage:
bucket: velero-backup-ap-northeast-2
prefix: cluster-prod
config:
region: ap-northeast-2
accessMode: ReadWrite
default: true
---
# Secondary BSL - 東京リージョン(DR用)
apiVersion: velero.io/v1
kind: BackupStorageLocation
metadata:
name: secondary-tokyo
namespace: velero
spec:
provider: aws
objectStorage:
bucket: velero-backup-ap-northeast-1
prefix: cluster-prod-dr
config:
region: ap-northeast-1
accessMode: ReadWrite
credential:
name: velero-dr-credentials
key: cloud
# 両方のBSLにバックアップを作成
velero backup create dr-backup-$(date +%Y%m%d) \
--include-namespaces production \
--snapshot-volumes \
--snapshot-move-data \
--storage-location primary-seoul
# DRサイトにも複製バックアップ
velero backup create dr-backup-$(date +%Y%m%d)-replica \
--include-namespaces production \
--snapshot-move-data \
--storage-location secondary-tokyo
S3 Cross-Region Replicationの活用
BSLを二重化する代わりにS3 Cross-Region Replication(CRR)を活用すると、別途のバックアップコマンドなしでも自動的にバックアップデータが他のリージョンへ複製されます。この方式は運用オーバーヘッドが少ないですが、S3 CRRの費用が追加で発生します。DRクラスタでは複製されたバケットをBSLとして指定し、ReadOnlyモードでアクセスします。
DRシナリオ別の復旧手順
シナリオ1: 単一ネームスペース削除からの復旧
# 誤って削除されたネームスペースの確認
kubectl get ns production
# Error from server (NotFound): namespaces "production" not found
# 最新バックアップの確認
velero backup get --selector backup-tier=tier1 | head -5
# ネームスペースの復元
velero restore create ns-recovery-$(date +%s) \
--from-backup tier1-hourly-backup-20260308020000 \
--include-namespaces production \
--wait
# 復元状態の確認
velero restore describe ns-recovery-$(date +%s) --details
シナリオ2: クラスタ全体のDR(リージョン障害)
- DRリージョンに新しいKubernetesクラスタをプロビジョニング
- Veleroのインストール(DR用のBSLを指定)
- 直近のバックアップから全体の復元を実行
- DNSの切り替えとサービスの検証
シナリオ3: 特定リソースのロールバック(誤ったデプロイからの復旧)
# 誤ったDeploymentのみを以前の状態へ復元
velero restore create deployment-rollback \
--from-backup daily-backup-20260307 \
--include-namespaces production \
--include-resources deployments \
--selector app=api-server \
--existing-resource-policy update \
--wait
--existing-resource-policy update オプションは、復元時にすでに存在するリソースをバックアップ時点の状態で上書きします。既定値はnoneで、既存のリソースがあればスキップします。
バックアップツールの比較: Velero vs Kasten K10 vs etcdバックアップ
Kubernetesのバックアップソリューションを選ぶ際は、3つのアプローチの特性を理解することが重要です。
| 区分 | Velero | Kasten K10 | etcdネイティブバックアップ |
|---|---|---|---|
| ライセンス | オープンソース(Apache 2.0) | 商用(無料は5ノードまで) | オープンソース |
| バックアップ範囲 | ネームスペース/リソース単位 | アプリケーション単位 | クラスタ全体(etcdデータ) |
| UI | CLI中心 | Webダッシュボードを内蔵 | CLI (etcdctl) |
| PVバックアップ | CSIスナップショット + FSB | CSIスナップショット + Kanister | 非対応(別途の実装が必要) |
| マルチクラスタ | 共有BSLで手動管理 | 中央コンソールで統合管理 | クラスタごとに独立 |
| 暗号化 | 単一キーベース | 封筒暗号化(マスターキー + DEK) | 非対応 |
| 復元の粒度 | ネームスペース/リソース/ラベル | アプリケーション/コンポーネント | 全体復元のみ可能 |
| DB一貫性バックアップ | フック(Hook)で実装 | 内蔵ブループリントを提供 | etcdのみ一貫性を保証 |
| 適した環境 | 中小規模、コストに敏感 | 大規模エンタープライズ | コントロールプレーンのDR |
| 学習曲線 | 中程度 | 低い(UIを提供) | 高い |
選択ガイド:
- etcdバックアップ: コントロールプレーンのDRには必須ですが、アプリケーションデータ(PV)は保護できません。VeleroやKastenと併用する必要があります。
- Velero: コスト効率が高く柔軟です。コミュニティが活発で、CSIスナップショットとFSBの両方をサポートするため大半のシナリオをカバーします。マルチクラスタの管理は手動で行う必要があります。
- Kasten K10: 大規模エンタープライズで中央管理と規制遵守(Compliance)が必要な場合に適しています。Web UI、中央コンソール、データ暗号化、不変性(Immutability)などの機能が内蔵されていますが、ライセンス費用が高いです。
バックアップ前後のフック(Hook)活用
データベースのように実行中のファイルシステム一貫性が保証されないワークロードは、バックアップ前にクエリ停止(quiesce)の作業が必要です。VeleroのPre/Post Hookを活用すると、これを自動化できます。
apiVersion: velero.io/v1
kind: Backup
metadata:
name: db-consistent-backup
namespace: velero
spec:
includedNamespaces:
- database
snapshotVolumes: true
hooks:
resources:
- name: postgresql-hook
includedNamespaces:
- database
labelSelector:
matchLabels:
app: postgresql
pre:
- exec:
container: postgresql
command:
- /bin/bash
- -c
- 'pg_dump -U postgres -d myapp > /var/lib/postgresql/backup/pre_backup.sql && sync'
onError: Fail
timeout: 120s
post:
- exec:
container: postgresql
command:
- /bin/bash
- -c
- 'rm -f /var/lib/postgresql/backup/pre_backup.sql'
onError: Continue
timeout: 30s
Pre HookでonErrorをFailに設定すると、フックの実行が失敗した場合にバックアップ自体が中断されます。こうすることで、一貫性が保証されないバックアップが作成されるのを防げます。
モニタリングと通知の体系
Prometheusメトリクスの収集
VeleroはデフォルトでPrometheusメトリクスを公開します。ServiceMonitorを構成すると、バックアップ/復元の状態を監視できます。
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: velero
namespace: velero
labels:
app.kubernetes.io/name: velero
spec:
selector:
matchLabels:
app.kubernetes.io/name: velero
namespaceSelector:
matchNames:
- velero
endpoints:
- port: monitoring
interval: 30s
主要な監視メトリクス
- velero_backup_success_total: 成功したバックアップ数
- velero_backup_failure_total: 失敗したバックアップ数
- velero_backup_partial_failure_total: 部分的に失敗したバックアップ数
- velero_backup_duration_seconds: バックアップの所要時間
- velero_restore_success_total: 成功した復元数
- velero_backup_items_total: バックアップされたリソース項目数
Alertmanagerの通知ルール例
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: velero-alerts
namespace: velero
spec:
groups:
- name: velero.rules
rules:
- alert: VeleroBackupFailure
expr: increase(velero_backup_failure_total[1h]) > 0
for: 5m
labels:
severity: critical
annotations:
summary: 'Veleroバックアップの失敗を検知'
description: '直近1時間以内にVeleroのバックアップが失敗しました。即時の確認が必要です。'
- alert: VeleroBackupNotRunning
expr: time() - velero_backup_last_successful_timestamp{schedule!=""} > 86400
for: 10m
labels:
severity: warning
annotations:
summary: 'Veleroのスケジュールバックアップが24時間以上実行されていない'
description: 'スケジュール {{ $labels.schedule }} の最後の成功バックアップが24時間を超えました。'
- alert: VeleroBackupPartialFailure
expr: increase(velero_backup_partial_failure_total[6h]) > 0
for: 5m
labels:
severity: warning
annotations:
summary: 'Veleroバックアップの部分的な失敗を検知'
description: '一部のリソースがバックアップに含まれていません。ボリュームスナップショットまたはフックの実行状態を点検してください。'
トラブルシューティングガイド
障害事例1: バックアップ状態がPartiallyFailed
症状: バックアップは完了しますが、状態がPartiallyFailedと表示されます。
# 詳細な原因の確認
velero backup describe my-backup --details
# ログから具体的なエラーを確認
velero backup logs my-backup | grep -i "error\|warning"
主な原因と解決:
- VolumeSnapshotLocationの未構成: CSIスナップショットを使っているのにVSLが正しく設定されていない場合に発生します。velero snapshot-location get でVSLの状態を確認し、クラウドプロバイダに合ったVSLを作成します。
- Node Agentのタイムアウト: 大容量ボリュームのFSBが既定のタイムアウト(240分)を超えるときに発生します。Node Agent Podのリソースを増やすか、--fs-backup-timeout の値を大きくします。
- Pod Volumeのマウントエラー: PodがRunning状態でない場合はボリュームのバックアップができません。CrashLoopBackOff状態のPodを先に解決する必要があります。
障害事例2: 復元後にPVCがPending状態
症状: 復元は完了しましたが、PVCがPending状態から進みません。
原因: StorageClassがターゲットクラスタに存在しない、または名前が異なる場合に発生します。
# 復元されたPVCの状態確認
kubectl get pvc -n restored-namespace
# StorageClassの確認
kubectl get sc
# ConfigMapでStorageClassをマッピング
kubectl -n velero create configmap change-storage-class-config \
--from-literal=old-storage-class=new-storage-class
# マッピングを適用した復元
velero restore create --from-backup my-backup \
--include-namespaces production
Veleroは、veleroネームスペースに change-storage-class-config というConfigMapがあれば、自動的にStorageClass名をマッピングします。
障害事例3: BSLへアクセスできない
症状: Veleroがオブジェクトストレージへアクセスできず、バックアップが作成されません。
# BSLの状態確認
velero backup-location get
# NAME PROVIDER BUCKET/PREFIX PHASE LAST VALIDATED
# default aws velero-backup-prod/ Unavailable 2026-03-08 00:00:00
# 認証情報の確認
kubectl -n velero get secret cloud-credentials -o jsonpath='{.data.cloud}' | base64 -d
# BSLアクセスの手動テスト
kubectl -n velero exec deploy/velero -- \
aws s3 ls s3://velero-backup-prod/ --region ap-northeast-2
解決: IAM認証情報の期限切れ、バケットポリシーの変更、ネットワークポリシーによるアウトバウンドの遮断などが原因になりえます。IRSA (IAM Roles for Service Accounts) を使うと、認証情報の期限切れ問題を根本的に解決できます。
障害事例4: バージョン不一致エラー
症状: Velero CLIとサーバーのバージョンが一致せず、コマンドの実行が失敗します。
# バージョン確認
velero version
# Client:
# Version: v1.15.0
# Server:
# Version: v1.14.1
# サーバーと同じCLIバージョンで再インストールするか、サーバーをアップグレードします。
クライアントとサーバーのメジャー/マイナーバージョンは必ず一致させる必要があります。パッチバージョンの違いは大半が互換ですが、公式には同一バージョンの使用が推奨されます。
運用上の注意点とベストプラクティス
必ず守るべき原則
-
定期的な復元テスト: バックアップが存在することと、復元ができることは別の問題です。最低でも月1回、テスト用ネームスペースへ実際に復元を行い、バックアップの有効性を検証する必要があります。
-
BSL暗号化の有効化: バックアップデータにはSecretやConfigMapなど機微な情報が含まれます。オブジェクトストレージのサーバーサイド暗号化(SSE)を必ず有効にしてください。
-
RBACの最小権限適用: Velero ServiceAccountに過度な権限を付与しません。バックアップ対象ネームスペースへの読み取り権限と、veleroネームスペースへの書き込み権限のみを付与します。
-
バックアップの不変性(Immutability): S3 Object Lockや同等の機能を活用して、バックアップデータの改ざんおよび削除を防ぎます。ランサムウェア攻撃への防御に必須です。
-
Node Agentのリソース割り当て: 既定のリソース設定では、大容量ボリュームのバックアップ時にOOM Killが発生することがあります。本番ではNode Agentのメモリlimitを最低2Gi以上に設定してください。
避けるべき失敗
- 単一BSLへの依存: オブジェクトストレージ自体に障害が発生すると、バックアップも復元も不可能になります。必ず二重化したBSLまたはCRRを構成します。
- TTLの未設定: 保存期間を設定しないと既定の30日が適用されます。ワークロードの重要度に応じて明示的にTTLを設定する必要があります。
- クラスタ全体バックアップの濫用: すべてのネームスペースを1つのバックアップに含めると、バックアップ時間が長くなり、復元時に不要なリソースまで復元されます。ネームスペースまたはワークロード単位に分離するほうが効率的です。
- CRDのバックアップ漏れ: Custom Resource Definitionをバックアップから除外すると、そのCRDに依存するCR(Custom Resource)が復元時に作成されません。
- バックアップ監視の未構成: バックアップの失敗が検知されないと、DR時に使える有効なバックアップが存在しない可能性があります。
DR復旧訓練チェックリスト
実際の障害時に慌てないためには、定期的なDR復旧訓練が必須です。以下のチェックリストを活用して四半期ごとの訓練を実施してください。
事前準備の段階:
- DR対象のクラスタおよびネームスペースの一覧を確定
- 最新バックアップの存在とCompleted状態を確認
- DRサイトのクラスタ可用性を確認
- Veleroのサーバー/クライアントのバージョン一致を確認
- BSLへアクセス可能かを確認
復元の実行段階:
- テスト用ネームスペースまたはDRクラスタへ復元を実行
- 復元状態がCompletedであることを確認(PartiallyFailedの有無を点検)
- 主要なDeployment/StatefulSetのPodがRunning状態であることを確認
- PVCがBound状態であることとデータの整合性を検証
- Service/Ingressのエンドポイントへアクセスできることを確認
- アプリケーションレベルのHealth Checkを実施
- データベース接続とデータ整合性を検証
事後レビューの段階:
- 復元の所要時間を記録(RTO充足の可否を評価)
- データ損失の範囲を測定(RPO充足の可否を評価)
- 発見された問題点および改善事項を文書化
- バックアップスケジュールまたはTTLの調整要否を検討
- 次回訓練の日程を確定
おわりに
Kubernetesクラスタのバックアップと復旧は選択ではなく必須です。「うちのクラスタは大丈夫だろう」という考えは、実際に障害が発生した瞬間に崩れます。Veleroはオープンソースでありながら、CSIスナップショット、ファイルシステムバックアップ、クロスクラスタ移行、スケジュールベースの自動バックアップなど、エンタープライズ水準の機能を提供します。
本記事で扱った要点をまとめると次の通りです。ワークロードの重要度に応じてTierを分け、各Tierに合ったRPO/RTOを設計してください。CSIスナップショットとData Moverを活用すればクロスリージョンDRが可能です。バックアップがあるからと安心せず、定期的に復元テストを行ってバックアップの有効性を検証してください。モニタリングと通知を構成し、バックアップの失敗を即座に検知して対応できるようにする必要があります。
Velero一つですべてのDRシナリオをカバーすることはできません。etcdネイティブバックアップでコントロールプレーンを保護し、Veleroでアプリケーションとデータを保護し、必要に応じてKasten K10のようなエンタープライズソリューションを併用するのが最も堅牢な戦略です。
参考資料
- Velero公式ドキュメント - How Velero Works
- Velero公式ドキュメント - Cluster Migration
- Velero公式ドキュメント - CSI Support
- Velero公式ドキュメント - File System Backup
- Velero公式ドキュメント - Troubleshooting
- Velero GitHub Repository
- Kubernetes公式ドキュメント - CSI Volume Snapshots
- Broadcom Knowledge Base - Velero Backup Failed or PartiallyFailed
- Veeam Kasten for Kubernetes
- Kubernetes公式ドキュメント - Operating etcd clusters