「Velero」を使ったAKSのバックアップを紹介

惣道哲也氏:「Velero」を使ったAKSのバックアップを紹介したいと思います。一応時間は30分いただいているんですけど、若干余裕があるので、もしかしたら35分ぐらいまでしゃべるかもしれません。

自己紹介します。私、惣道といいます。Twitterはこのチューリップのアイコンでやってます。普段はHPEという会社で、お客様向けのシステムの構築とか設計とか提案とかをしていて、オープンソース系クラウドとかコンテナとかAIとかデータ分析とか、そのへんをやっています。この本を見かけたら、買ってください。

Elasticsearch実践ガイド (impress top gear)

今日お話しする内容は、クラスタの運用管理とバックアップ。Kubernetesクラスタで運用管理が必要かという話をしたいと思います。

Kubernetesにバックアップは必要か?

もともとKubernetes自身がワークロードを自動化してくれる、管理を自動化してくれるというメリットがありますので、一見、yamlでリソース管理を全部表現してしまえば、ユーザーがやることはないよねという考え方もできるんですけれども、実際には、下に書いてあるように、クラスタ基盤自身の運用管理は必要です。

ということで、今日はバックアップでしたり基盤自体の運用監視どうしますかとかお話しします。このへん、本当は今日Azure Monitorの話とかもできればよかったんですけれども。

バージョンアップは、右に絵に描いてあるように、AKSだったらupgradeコマンドを使えばワークロードを動かしながら自動でアップグレードしてくれるんですけれども、そういったことを手でやる場合には、運用管理がけっこう大変なタスクだったりします。あと、ログを管理したりとか基盤自体のノードのメンテナンスとか、そういったことはタスクとしては必要だという話ですね。

Kubernetes自身にバックアップが必要ですかという話については、2019年のKubeConで、Spotifyの事例ということで、いわゆるやらかし系の事例を発表したんですけれども。Spotifyって10億ユーザーいて、ただ全部のワークロードがKubernetesクラスタ上で動いているわけではなかったので幸いだったんですけれども、本番クラスタを落としました。

最初ですね、USってところがグレーになっていますが、これGKEなんですけど、ブラウザを開いてテスト環境のクラスタをいろいろ操作しながら検証していて、終わったので消そうと思ってバチャッって切りました。そのときに間違えて、USクラスタの開いてるタブのほうを落としてしまい、本番USクラスタを落としてしまいました。

急いでリストアしなければいけないんですけれども、そこが自動化されていなかったので手動で、ドキュメントも誤記があったり再作成スクリプトもバグがあったりとかで、けっこう大変だったわけですね。

ただ、3時間ぐらいで復旧したので、それはさすがだなと思ったんですけれども、翌月さらにやらかします。今度は本番クラスタの2リージョンを落としてしまいます。これはTerraformとGitHubのプルリクマージのミスと言っているんですけれども、こんな状態になりました。非常に大変で。

結論としては、彼らはバックアップが大事ですと言っています。もちろんバックアップとともにリストア試験することも大事だと思っているので、こういったことをベストプラクティスとして挙げられていました。なので、バックアップは、私はすごく必要だなと思っています。

今日のセッションの目的は、本当はオフラインだったらみなさんに挙手いただいて「Kubernetesをバックアップしたことある人?」って聞きたかったんですけど、(オンラインなので)全然わからないので、たぶん2〜3割ぐらいかなと勝手に想像しています。このセッションを聞いて「Veleroを使ったらクラスタバックアップできそうだな」と思って、試していただけたらいいなと思います。

ちなみに、もうちょっと原理主義的に突き詰めると、「バックアップじゃなくて、もう全部構成するyamlとかをGitで置いてしまって、Gitを唯一解として、そこから何があってもデプロイすればいいじゃん」みたいなGitOps的な考え方もあるにはあります。ですが、すごく熟れたパイプラインの設計とかブランチ戦略どうするんだとか、どっちかというとバックアップを管理する以上に難しいことも求められたりとかするので、まぁちょっとそういうのもあるんですけれども、バックアップ取りましょうって話をしたいと思います。

Veleroは内部の実装のことを気にしなくても使える

Veleroの紹介をしたいなと思っているんですけれども、ひと言でいうと、Kubernetesクラスタの中でも、そのリソース、PodとかServiceリソースとか、そういったものを全部バックアップします。オブジェクトストレージにバックアップを取るものになっています。あと、KubernetesはPV(Persistent Volume)を使うと思うんですけれども、そのスナップショットも取れますよというものですね。

もともとは、Heptio社が「Ark」という名前で作っていたものです。Heptio社はGoogleのKubernetesを作った3人のエンジニアのうち、2人が創業した名だたる企業でして、2018年にVMware社に買収され、名称も「Velero」に変わっています。

こんなことができますよって話ですね。Veleroがどんなことができるのかというアーキテクチャ図、これはVeleroのホームページから図を拝借しているんですけれども、この図を使って簡単に説明すると、そんなに難しくありません。

1番と書いてあるのは、Veleroは基本的にカスタムリソースを使います。オペレーター的に管理をするんですけど、カスタムリソースというのはKubernetesの拡張リソースみたいなもので、kindで言うところのkindのPodとかkindのServiceとかではなくて、そのコアのもののほかにkind: Backupとかkind: Restoreとか、その拡張されたカスタマイズされたリソース、これを定義してAPIに投げられます。

APIに投げると、これがKubernetes API上で認識されて、真ん中にあるBackupControllerという常駐Podのバックアップのリクエストを検知して、2番で実際にバックアップ対象のリソースを全部APIからgetしてきてごそって抜いて、それを図の4番のところでオブジェクトストレージ上に束ねてアップするというのが、簡単にいうとVeleroの仕組みです。オプションでPVのスナップショット、これもSnapshot APIを投げることをやってくれます。

どういうKubernetesクラスタを使っているか、要はバックエンドのどういうクラウドプロバイダを使っているかによって、オブジェクトストレージのお作法とかもいろいろあると思うんですけれども、そこはプラグイン形式になっていて、AKSであればAzure用のプラグインを設定してあげるだけで、BLOBに入れたりとかManaged Disks のスナップショットを取ってくれたりということを全部Veleroが吸収してやってくれます。ユーザーからは非常に抽象化された感覚でバックアップを定義、管理できるのがうれしいところです。

これを手組みでやるとすごく辛くて。例えばさっきの図のetcdというところが基本的には永続データをもっているので、じゃあetcdctlで全部データ抜けばいいじゃんと思うかもしれないですけど、これすごくしんどくて。クラスタの管理とかですね。あとは、一貫性をもって全部必要なyamlをエクスポートできますか、みたいな話もあったりします。

また、さっきお話ししたように、バックエンドのオブジェクトストレージとかに応じていろんなコマンドとかを使い分けなければいけないのも、手組みだと大変なので、そこをVeleroを使うと、透過された抽象化されたやり方で、kind: Backup みたいな定義だけを書けば細かい実装のところを全部カバーしてくれるイメージになります。

Veleroがスマートだなと思うのは、やっぱりそのetcdを直接叩くのではなくて、Kubernetes APIにアクセスして、getで全部リソースをyamlみたいなかたちで取り出してバックアップするところが肝だなと思っていて、あまり内部の実装のことを気にしなくても使えるという便利なところがあります。

Veleroの特徴

その他特徴を1枚のスライドにまとめると、バックアップ・リストアはクラスタ全体でも取れますし、Namespace単位でも取れます。あとラベル指定を、例えばDev環境のものだけとかプロダクション環境のものだけとか、そういった取り方もできたりします。

オブジェクトストレージは、メガクラウド系は全部カバーしていますし、あとはオンプレだと例えばMinIOを使ってとか、そういったこともできます。このへんもプラグインを使い分けることによって、どのオブジェクトストレージに保管するかが制御できます。

PVも、これオプションではありますけれども、プラグインを使えばPVのスナップショットにも対応しています。

スケジュール管理は、あとでデモでもお伝えするんですけれども、cronフォーマットみたいに書けば、「毎日何時にバックアップを取ります」みたいなことも簡単に指定できます。

一番下もすごく気が利いていて、前後のhook処理が可能です。バックアップするときって、例えばPVをマウントするときとか、ファイルシステムをダーティバッファをディスクにちゃんと書き出してからバックアップするみたいなことに気をつけないと、ディスクが不整合になってマウントするときにうまくできないことがあります。Veleroはhook処理を任意でカスタマイズできるので、バックアップを取る前にfsfreezeコマンドでフリーズかけて、終わったあとにunfreezeするみたいなこともできるので、非常にちゃんと考えられているところが、特徴としてはあります。

Veleroの導入から利用までの手順

簡単に、Veleroをどうやって使うのかということを、このあとお伝えしたいなと思います。

これ、AKS上でやったんですけれども、1.16.7で東日本リージョンでやりました。Veleroは最新版が今1.3.1というバージョンになっています。プラグインが一番下にあって、これがAzureを使うときには、このプラグインを使います。というか、インストール時に指定するんですけれども、こういったバージョンでやっています。

ざっくり1枚にまとめるとこんな感じです。事前準備では、インストール前に格納するためのBLOBのセットアップとかそういったことが必要なので、AKS作るのはもちろんなんですけれども、ストレージアカウントを作って、BLOBコンテナも先に作っておきます。

あと、Service Principalがここでも必要なのですが、これはVeleroが直接AKSのリソースをいくつか管理、例えばスナップショットを取るとかそういったことをやるので、Service PrincipalをContributor roleで作っておく必要があります。

インストール自体は1コマンドで簡単にできて、できあがったら、一番右側、実際のワークロードをバックアップしたりリストアしたりという、当たり前ですけど、そういった流れになってきます。

次のスライドから簡単にどんなイメージなのかをコマンドレベルで紹介したいと思いますが、さっきお伝えしたように、ちょっと細かい全部のコマンドは載せてなくて、ダイジェストでわかりやすいように、ある程度端折って書いています。細かいところは、ぜひブログから確認してもらいたいと思います。

Veleroインストールの事前準備

AKSクラスタを作るところ、ここは今までのセッションでも散々やってきたと思いますが、ストレージアカウントとBLOBコンテナと作っておきます。

別にコマンドじゃなきゃいけないってことはないんですけれども、これはBlobStorageタイプで作っておけば、あとのパラメータはある程度任意です。ただ、たぶんSKUはLRSだとDRにならないからGRSにしようねとか、そのへんは要件に応じて決めていただければいいかなと思います。

これはバックアップしたものを置いておく場所ですね。これを先に作っておきます。

SP(Service Principal)も、コマンドでも何で作ってもいいんですけれども、事前に作っておきます。作ると、当たり前ですけど、AzureADの画面からはこんな感じでVeleroのSPが見えるようになっています。

このへんを全部指定して実際にインストールしていくんですけれども、このへんはクレデンシャルってファイルを作って、Azureの場合にはSUBSCRIPTION_IDとかテナントの情報とかさっきのService Principalの情報なんかを全部書いて、ファイルを用意しておいて、このファイルをインストール時に渡す、みたいな仕組みになっています。

Velero CLIとVeleroのインストール

インストール時と、あとインストール後の実際のバックアップとかリストアは全部……さっきAPIを投げると言ったんですけれども、実際にはVeleroのCLIというバイナリを使ってVeleroコマンドというので全部やります。このVeleroコマンドがさっきの常駐Podに命令を投げるみたいなので、いわゆるクライアントのCLIとしてVelero CLIをインストールします。

これはもうバイナリを落としてきてPATHを通すだけですね。PATHを通すとVeleroコマンドが使えます。

インストールはここに書いてある1コマンドで全部終わりますが、ちょっと細かいんですけどポイントだけお伝えすると、オレンジで書いている引数の上2つはAzure固有のものですね。Azureのproviderで使いますよ、それからpluginはAzureのプラグインを使いますよということを指定しています。

その次にさっきのsecret-fileで、Azure固有のアクセスをするための、Service Principalの情報とかテナントの情報をまとめたファイルを渡してあげます。

残りは格納先の情報になるんですけれども、BLOBコンテナのbucketの名前とかです。あとはbackup-locationと言っているのは、そのBLOBのロケーションのことを言うんですけれども、これの細かい定義をここにつらつらとオプションで書けますし、一番下の行はスナップショットを取るときのいろんな細かい振る舞いの定義を書けます。

細かい設定が本当にいろいろできるので、詳しくはこの上にあるGitHubのところに全部オプションの説明が書いてあるので、細かい使い方をしたいときは確認してみてください。これでPodが立ち上がってバックアップがすぐに実行できるようになります。