災害に備えVeleroでKubernetesクラスタをバックアップする

この記事はOpenSaaS Studio Advent Calendar 2019の16日目の記事。

Kubernetesクラスタのバックアップ

GitOpsとCI/CDの整備により、Kubernetesクラスタにデプロイされているアプリケーションやミドルウェアは、デリバリ用のリポジトリとニアリーイコールにできる運用が一般化した。これだけ見ると、運用やインシデントでKubernetesクラスタを新しく作り直してマイグレーションするということは簡単なように思えるが、実際にはそうでもない。

実際には我々が直接管理しているマニフェストは最も上位層のリソースなので、Deploymentが生成するReplicaSetおよび、ReplicaSetが生成するPodをそのまま別の環境で再現するには、動的に生成されたリソースのマニフェストも含めてバックアップを取る必要がある。他にもBitnamiのSealedSecretだったり、cert-managerがLet’s Encryptから取得してきた証明書だったり、運用によって生成されたリソースがクラスタには多く含まれる。

そこでバックアップに悩む顧客を解決するツールがVeleroだ。

Velero

Veleroは元々Heptio Arkという名前で提供されていたKubernetesのバックアップツールで、今年5月にv1.0.0がリリースされた。このバージョンからはvelero installコマンドで簡単にVeleroをクラスタにセットアップできるにようになっている。

Veleroは代表的なパブリッククラウドであるAWS、GCP、Azureの3つをサポートしている。バックアップはこれらのプラットフォームがサポートしているオブジェクトストレージに保存される。リストア先のクラスタは、このバックアップを参照してリストアすれば良いのが基本的な仕組みだ。インストールや使い方は公式のリファレンスを見れば明快なので、そちらを参照してほしい。

単純にバックアップするクラスタ(cluster-A)とリストアする(cluster-B)がある場合、バックアップは次のようにし

(cluster-A) $ velero backup create your-backup

次のようにリストアを実行するだけだ。

(cluster-B) $ velero restore create --from-backup=your-backup

バックアップ保存先にGCSを使うと、次のような感じで保存されている。

your-backup.tar.gzを解凍すると、ありとあらゆるリソース毎のディレクトリが切られており、その中でさらにNamespace毎のディレクトリが切られていて、各リソースの定義と状態がJSONファイルとして保持されている。

定時バックアップ

VeleroはCronベースでの定時自動バックアップに対応している。不測の事態に備え、いつでもリストアできる状態にしておくと良いだろう。

velero schedule create your-schedule-backup --schedule "0 */1 * * *"

クラスタのメンテナンスとサービスアウト・サービスイン

Disaster RecoveryとしてVeleroは非常に有用だが、それ以外の用途でも有用だ。Veleroでのバックアップ・リストアは運用において様々な応用をもたらす

Kubernetesクラスタを運用すると、悩みの種として挙がってくるのがクラスタのバージョンアップだ。Kubernetesにはローリングアップデートとオートヒーリング機能があるため、“そこそこ安全に"アップデートすることは可能なのだが、Namespace横断で活用されるようなアプリケーション(kube-systemの諸々だったり、ServiceMeshを実現するIstio)の場合、ローリングアップデートでもかなり慎重にならざるを得ない。

そこでVeleroのバックアップ・リストアが活躍する。リストアでStandbyクラスタを複製し、クラスタの外にあるDNSなりロードバランサーをStandbyに振り向けることで、今までActiveとしてサービスインしていたクラスタをサービスアウトさせられる。これによって、Maintenanceになったクラスタを安全にアップグレードできるわけだ。

ここで示したのはあくまで一例だが、元のクラスタを戻さずに使い捨ててクラスタレベルでのBlue/Green Deploymentみたいな運用にすることも可能である。そこはそれぞれの運用にマッチする手法を選択してほしい。

また、クラスタは複製してもIngressのドメインは違うものにしたいみたいな要求もあるだろう。その場合は次のようにバックアップの対象外としたいラベルを設定して、リストア先だけ独自に設定すればよい。

kubectl label -n <ITEM_NAMESPACE> <RESOURCE>/<NAME> velero.io/exclude-from-backup=true

また、Persistence Volumeについても対応している。さらにベータではあるがResticと統合が可能である。Resticは様々なバックエンドをサポートし、かつ透過的に扱えるようにしたツールになっているため、プラットフォーム間でのリストアも可能になるという理解(今回はまだこれは試してない)。

というわけで、VeleroはDisaster Recovery以外にも発展的な利用ができそうなので、弊部署でも広く使っていくお気持ちである。