Amazon Web Services ブログ

Velero を使用した Amazon EKS クラスターリソースのバックアップとリストア

この記事は Backup and restore your Amazon EKS cluster resources using Velero (記事公開日: 2021 年 12 月 1 日) を翻訳したものです。

2023 年 9 月 9 日更新: この記事はもともと 2021 年 12 月 1 日に掲載されました。最新の EKS バージョンと Velero Helm チャートの変更をサポートするため、このブログ記事のウォークスルー手順を更新しました。


世界中の企業がマイクロサービスをカプセル化するためにコンテナを採用しており、その多くはコンテナ化されたアプリケーションのデプロイ、スケーリング、管理を自動化するために Kubernetes を選択しています。これらのマイクロサービスの数が増えるにつれて、以下を行うための一元的なバックアップのメカニズムを導入することがますます重要になります。

  • 物理的および論理的なエラーが発生した場合のアプリケーションの保護
  • Kubernetes クラスター間のマイグレーションの実行
  • 本番環境クラスターの開発環境やテスト環境へのレプリケーション

Velero は、Kubernetes クラスターのディザスタリカバリ、データ移行、データ保護を提供する人気のあるオープンソースツールです。Velero は、Kubernetes のクラスターリソースと永続ボリューム (Persistent Volume) を、オンデマンドまたはスケジュールに従って、サポートされた外部のストレージバックエンドにバックアップできます。

Amazon Elastic Kubernetes Service (Amazon EKS) は、高可用かつ安全な Kubernetes クラスターを提供し、パッチ適用、ノードのプロビジョニング、アップデートなどの主要タスクを自動化にするのに役立つマネージドソリューションです。AWS のお客様は、このソリューションを活用して、Kubernetes オブジェクトとアプリケーションを Amazon EKS からバックアップ、および Amazon EKS にリストアできます。これは、お客様は Velero を使用して、セルフホスト型の Kubernetes から Amazon EKS に移行できることも意味します。

このブログ記事では、Velero を使用して Amazon EKS クラスターのリソースをバックアップ、リストア、移行する方法に焦点を当て、組織のユースケースに最適なアプローチを決定するために Velero が提供するバックアップオプションを紹介します。

Velero の概要

このセクションでは、Velero と Amazon EKS の統合方法、このツールがアプリケーションのバックアップとリストアのために提供するカスタマイズ、およびバックアップとリストアのワークフローについて説明します。

Velero と Amazon EKS

Amazon EKS のアプリケーションレベルのバックアップは、次の 2 つのコンポーネントが対象となります。

  • etcd キーバリューストアに保存された Kubernetes オブジェクトとコンフィギュレーション
  • Persistent Volume に保存されたアプリケーションデータ

Amazon EKS では、etcd キーバリューストアは AWS によって管理され、Kubernetes API サーバーを介してのみアクセスできます。Velero は Kubernetes API を利用して、キーバリューストアに保存されているデータを取得します。API 呼び出しでは、名前空間 (Namespace)、リソースタイプ、またはラベルによってリソースを簡単にフィルタリングできるため、このアプローチは etcd に直接アクセスするよりも柔軟性があります。例えば、ラベルでフィルタリングしてバックアップの範囲を特定のアプリケーションに制限したり、オブジェクトタイプでフィルタリングして現在の RBAC 戦略を保存したりできます。

また、Velero はクラスターの Persistent Volume のスナップショットを取得し、クラスターのオブジェクトと一緒にリストアできます。詳細は次のセクションで説明します。

バックアップとリストア操作は Kubernetes のカスタムリソース定義 (CRD) オブジェクトとして宣言されます。CRD はこれらの新しい CRD オブジェクトを処理するコントローラーによって管理され、バックアップ、リストア、およびすべての関連操作が実行されます。これらのバックアップとリストアの CRD オブジェクトを作成する際は、以下のカスタマイズを指定できます。

  • リソースのフィルタリング: Namespace、オブジェクトタイプ、ラベルでフィルタリングして、バックアップやリストアの範囲を制限します。リストア時に、Namespace とオブジェクトタイプを除外してフィルタリングできます。
  • バックアップタイプの選択: オンデマンドバックアップを作成するか、定期的にバックアップを自動的に開始するスケジュールを設定します。
  • 保持時間の設定: バックアップを保持する期間を指定します。
  • フックの指定: バックアップまたはリストア操作の前後にコンテナ内でカスタムコマンドを実行するためのプレフックとポストフックを設定します。

バックアップとリストアのワークフロー

Velero は 2 つのコンポーネントで構成されます。

  • Velero サーバー: Amazon EKS クラスター内で実行される Pod
  • Velero CLI: ローカルで実行されるコマンドラインクライアント

Amazon EKS クラスターに対してバックアップを発行するたびに、Velero は以下の方法でクラスターリソースのバックアップを実行します。

  1. Velero CLI が Kubernetes API サーバーにアクセスし、バックアップ CRD オブジェクトを作成します。
  2. バックアップコントローラーが以下を実施します。
    1. バックアップ CRD オブジェクトのスコープ、すなわちフィルターが設定されているかどうかをチェックします。
    2. バックアップが必要なリソースについて API サーバーにクエリを実行します。
    3. 取得した Kubernetes オブジェクトを .tar ファイルに圧縮し、Amazon S3 に保存します。

Velero のバックアップワークフロー

同様に、リストア操作を発行するときは以下のようになります。

  1. Velero CLI は Kubernetes API サーバーにアクセスし、既存のバックアップからリストアするリストア CRD オブジェクトを作成します。
  2. リストアコントローラーが以下を実施します。
    1. リストア CRD オブジェクトを検証します。
    2. Amazon S3 にアクセスしてバックアップファイルを取得します。
    3. リストア操作を開始します。

Velero のリストアワークフロー

Velero は、スコープ内の Persistent Volume のバックアップとリストアも実行します。

  1. Amazon Elastic Block Store (Amazon EBS) を使用している場合、Velero はスコープ内の Persistent Volume の Amazon EBS スナップショットを作成します。
  2. その他のボリュームタイプ (hostPath を除く) の場合は、Velero の Restic 統合を使用して、ボリュームの内容のファイルレベルのバックアップを作成します。本記事執筆時点では、Restic はベータ版であるため、本番環境グレードのバックアップには推奨されません。

次のセクションでは、Amazon EKS 上のアプリケーションと関連する EBS ボリュームをバックアップする方法を紹介します。

ウォークスルー

以下のセクションでは、Velero を使用して、あるクラスター内のアプリケーションをバックアップし、そのアプリケーションを別のクラスター内にリストアする方法を説明します。ここでは、人気の高いオープンソースの Ghost パブリッシングプラットフォームを使用して、アプリケーション定義だけでなく、Persistent Volume Claim (PVC) を使用して EBS ボリュームに保存されているステートもバックアップおよびリストアする方法を示します。

前提条件

次のステップに進むためには、以下の前提条件が必要です。

このチュートリアルで使用する 2 つの EKS クラスターは同じアカウントにありますが、これは Velero を使用するためのハード要件ではありません。このブログ記事をガイドラインとして使用し、必要に応じて IAM と S3 バケットのアクセス許可を調整することができます。

以下のセクションのコマンドは Bash を前提として書かれています。

Velero のインストール

EKS のベストプラクティスを使用して Velero をインストールするには、いくつかのステップが必要です。まず、バックアップを保存するための S3 バケットを作成します。次に、IAM Roles for Service Accounts (IRSA) を使用して、バックアップとリストア操作のために必要な AWS アクセス許可を Velero に付与します。最後に、このツールの操作方法を簡素化する Velero CLI をインストールします。

バックアップを保存するための S3 バケットの作成

Velero は、AWS で実行する場合、EKS のバックアップを保存するために S3 を使用します。以下のコマンドを実行して、Velero 用の S3 バケットを作成します。<company-fqdn>-eks-velero-backups のような一意のバケット名を使用してください。

<BUCKETNAME><REGION> は自分の値に置き換えてください。

BUCKET=<BUCKETNAME>
REGION=<REGION>
aws s3 mb s3://$BUCKET --region $REGION

Amazon S3 は、デフォルトで地理的に離れた複数のアベイラビリティーゾーンにデータを保存しますが、コンプライアンス要件により、さらに離れた場所にデータを保存することが求められる場合があります。クロスリージョンレプリケーションを使用することで、これらの要件を満たすために、離れた AWS リージョン間でデータをレプリケーションすることができます。

IAM ポリシー

Velero はスナップショットを実行し、バックアップを S3 バケットに保存するために、EC2 と S3 のリソースに対して多くの API 呼び出しを実行します。以下の IAM ポリシーは、Velero に必要なアクセス許可を付与します。

cat > velero_policy.json <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeVolumes",
                "ec2:DescribeSnapshots",
                "ec2:CreateTags",
                "ec2:CreateVolume",
                "ec2:CreateSnapshot",
                "ec2:DeleteSnapshot"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:DeleteObject",
                "s3:PutObject",
                "s3:AbortMultipartUpload",
                "s3:ListMultipartUploadParts"
            ],
            "Resource": [
                "arn:aws:s3:::${BUCKET}/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::${BUCKET}"
            ]
        }
    ]
}
EOF

aws iam create-policy \
    --policy-name VeleroAccessPolicy \
    --policy-document file://velero_policy.json

Velero の Service Account の作成

EKS クラスター上で実行されるアプリケーションに AWS ポリシーを提供するためのベストプラクティスは、IAM Roles for Service Accounts (IRSA) を使用することです。eksctl は、必要な IAM ロールを作成し、信頼関係のスコープを velero-server Service Account に設定する簡単な方法を提供します。

<CLUSTERNAME>PrimaryRecovery の EKS クラスターの名前に置き換えてください。

PRIMARY_CLUSTER=<CLUSTERNAME>
RECOVERY_CLUSTER=<CLUSTERNAME>
ACCOUNT=$(aws sts get-caller-identity --query Account --output text)

eksctl create iamserviceaccount \
    --cluster=$PRIMARY_CLUSTER \
    --name=velero-server \
    --namespace=velero \
    --role-name=eks-velero-backup \
    --role-only \
    --attach-policy-arn=arn:aws:iam::$ACCOUNT:policy/VeleroAccessPolicy \
    --approve

eksctl create iamserviceaccount \
    --cluster=$RECOVERY_CLUSTER \
    --name=velero-server \
    --namespace=velero \
    --role-name=eks-velero-recovery \
    --role-only \
    --attach-policy-arn=arn:aws:iam::$ACCOUNT:policy/VeleroAccessPolicy \
    --approve

--namespace=velero フラグによって、velero Namespace で実行されているアプリケーションだけが、前のステップで作成した IAM ポリシーにアクセスできるようになります。

両方の EKS クラスターへの Velero のインストール

以下の手順には、Helm チャートを使用して Velero をインストールするために必要な手順が含まれています。この手順では、Velero バージョン v1.11.1 をインストールするチャートバージョン 5.0.2 を指定していることに注意してください。新しい Velero バージョンをインストールしたい場合は、互換性マトリックスを使用して Velero AWS プラグインのバージョンを正しい Velero バージョンに合わせるなど、以下の values.yaml ファイルを必ず調整してください。

helm repo add vmware-tanzu https://vmware-tanzu.github.io/helm-charts

cat > values.yaml <<EOF
configuration:
  backupStorageLocation:
  - bucket: $BUCKET
    provider: aws
  volumeSnapshotLocation:
  - config:
      region: $REGION
    provider: aws
initContainers:
- name: velero-plugin-for-aws
  image: velero/velero-plugin-for-aws:v1.7.1
  volumeMounts:
  - mountPath: /target
    name: plugins
credentials:
  useSecret: false
serviceAccount:
  server:
    annotations:
      eks.amazonaws.com/role-arn: "arn:aws:iam::${ACCOUNT}:role/eks-velero-backup"
EOF

cat > values_recovery.yaml <<EOF
configuration:
  backupStorageLocation:
  - bucket: $BUCKET
    provider: aws
  volumeSnapshotLocation:
  - config:
      region: $REGION
    provider: aws
initContainers:
- name: velero-plugin-for-aws
  image: velero/velero-plugin-for-aws:v1.7.1
  volumeMounts:
  - mountPath: /target
    name: plugins
credentials:
  useSecret: false
serviceAccount:
  server:
    annotations:
      eks.amazonaws.com/role-arn: "arn:aws:iam::${ACCOUNT}:role/eks-velero-recovery"
EOF

Velero サーバーを 2 回、Primary クラスターと Recovery クラスターにインストールする必要があります。kubectl config (kubectl チートシート) または kubectx を使用して、両方のクラスターのコンテキストを表示し、コンテキストを簡単に切り替えることができます。

kubectl config の管理を簡単にするために、エイリアスを使用してクラスターを kubeconfig に追加します。

PRIMARY_CONTEXT=primary
RECOVERY_CONTEXT=recovery
aws eks --region $REGION update-kubeconfig --name $PRIMARY_CLUSTER --alias $PRIMARY_CONTEXT
aws eks --region $REGION update-kubeconfig --name $RECOVERY_CLUSTER --alias $RECOVERY_CONTEXT

次のコマンドを使用して、これらの新しいコンテキストがあることを確認できます。

kubectl config get-contexts

コマンドによる新しいコンテキストの確認

「*」が、どのコンテキストにいるかを示しています。

コンテキストを Primary クラスターに変更し、Velero をインストールしましょう。

kubectl config use-context $PRIMARY_CONTEXT
helm install velero vmware-tanzu/velero --version 5.0.2 \
    --create-namespace \
    --namespace velero \
    -f values.yaml

次に、コンテキストを Recovery クラスターに変更し、Velero をインストールしましょう。

kubectl config use-context $RECOVERY_CONTEXT
helm install velero vmware-tanzu/velero --version 5.0.2 \
    --create-namespace \
    --namespace velero \
    -f values_recovery.yaml

各コンテキストで以下のコマンドを実行することで、Velero サーバーが正常にインストールされたことを確認できます。

kubectl get pods -n velero

Velero サーバーのインストール確認

Velero CLI のインストール

Velero はコマンドを CRD としてを送信することで動作します。クラスターのバックアップを作成するには、クラスターにバックアップ CRD を送信します。これを手作業で作成するのは難しい場合があるため、Velero チームはバックアップとリストアを簡単に実行できる CLI を作成しました。ここでは、Velero CLI を使用して Primary クラスターのバックアップを作成し、Recovery クラスターにリストアします。

インストール手順はオペレーティングシステムによって異なります。 こちらの手順に従って Velero をインストールしてください。

サンプルアプリケーションのバックアップとリストア

Velero をインストールした状態で、Primary クラスターにアプリケーションをインストールしてバックアップし、Recovery クラスターにリストアを行います。お客様は、以下の手順に従って、自分の Amazon EKS クラスター内の自分のアプリケーションをバックアップおよびリストアすることもできます。

Ghost アプリケーションのインストール (および記事の作成)

Ghost をサンプルアプリケーションとして Primary クラスターにバックアップし、Recovery クラスターにリストアします。一般的にデプロイされ、十分にテストされている Bitnami Helm チャートを使用します。このチャートは、ブログアプリケーションのための永続的なデータストアとして機能する Bitnami MySQL チャートに依存しています。MySQL のデータは EBS ボリュームに保存され、バックアップ実行の一環として Velero によってスナップショットが作成されます。

それでは、Primary クラスターにコンテキストに切り替え、Ghost をインストールしましょう (Ghost をインストールするときに表示される通知 ERROR: You did not provide an external host は無視してください。これは次のコマンドで解決されます)。

kubectl config use-context $PRIMARY_CONTEXT

helm install ghost oci://registry-1.docker.io/bitnamicharts/ghost \
    --create-namespace \
    --namespace ghost

export APP_HOST=$(kubectl get svc --namespace ghost ghost --template "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}")
export GHOST_PASSWORD=$(kubectl get secret --namespace "ghost" ghost -o jsonpath="{.data.ghost-password}" | base64 -d)
export MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace "ghost" ghost-mysql -o jsonpath="{.data.mysql-root-password}" | base64 -d)
export MYSQL_PASSWORD=$(kubectl get secret --namespace "ghost" ghost-mysql -o jsonpath="{.data.mysql-password}" | base64 -d)

helm upgrade ghost oci://registry-1.docker.io/bitnamicharts/ghost \
    --namespace ghost \
    --set service.type=LoadBalancer \
    --set ghostHost=$APP_HOST \
    --set ghostPassword=$GHOST_PASSWORD \
    --set mysql.auth.rootPassword=$MYSQL_ROOT_PASSWORD \
    --set mysql.auth.password=$MYSQL_PASSWORD

次のコマンドを実行することで、インストールが成功したことを確認できます。

kubectl get pods -n ghost

Ghost のインストールコマンドの実行

Persistent Volume のバックアップとリストアをデモするブログ記事の作成

Helm チャートのインストールが完了すると、コンソールにチャートの README が表示されます。 これには次のものが含まれます。

  1. ブログ URL
  2. 管理 URL
  3. デフォルトの管理者ユーザー名
  4. kubectl を使用してパスワードを取得する手順

オプションで、(上に表示されている管理 URL を使用して) Ghost 管理コンソールにサインインし、バックアップとリストアのプロセスに含めるサンプルのブログ記事を作成することができます。これにより、バックアップにはアプリケーションのデプロイメント構成だけではなく、すべての記事を含むブログデータベースの状態も含まれることが確認できます。

記事を作成するには、まず左側のナビゲーションペインで Posts を選択します。

Ghost コンソールでのブログ記事の作成

次に、ページの右上にある New post を選択します。

記事のタイトルを追加し、内容を書くことができます。サンプルのブログ記事を保存する準備ができたら、ページの右上にある Publish ドロップダウンメニュー項目を選択し、ドロップダウンメニューから Publish ボタンを選択します。

ブラウザでの新しい記事の表示

バックアップの作成

Primary クラスターのバックアップを作成しましょう。以下のコマンドを実行する前に、kubectl コンテキストが Primary クラスターに設定されていることを確認してください。

velero backup create ghost-backup

-o フラグを使用することで、Velero のバックアップ CRD がどのように見えるかを確認できます。これは、実際にバックアップ作成を Velero サーバーに送信せずに、バックアップ CRD の YAML を出力します。

velero backup create test -o yaml

Namespace のバックアップ

バックアップ CRD では、includedNamespaces 配列にワイルドカードが含まれているため、すべての Namespace をバックアップしていることがわかります。クラスター全体をバックアップしている場合でも、セレクターを使用してクラスターの個々のコンポーネントを選択できます。これにより、例えば単一のアプリケーションを含む単一の Namespace をバックアップできます。

バックアップが成功したことの検証

バックアップのステータスを確認し、バックアップが正常に完了したことを確認しましょう。

velero backup describe ghost-backup

コマンドの出力で、Phase: フィールドを探します。現在の PhaseInProgress の場合、しばらく待ってから Phase: Completed が表示されるまで再試行してください。開始時刻や完了時刻、バックアップされたアイテムの数などの情報を含む、バックアップの追加の詳細を確認できます。

バックアップの詳細情報

以前に作成した Amazon S3バケット内に、Velero が作成したバックアップファイルを確認できます。

aws s3 ls $BUCKET/backups/ghost-backup/

Velero によって作成されたバックアップファイル

アプリケーションの Recovery クラスターへのリストア

kubectl コンテキストを Recovery クラスターに切り替えます。

kubectl config use-context $RECOVERY_CONTEXT

次のコマンドを使用して、Ghost アプリケーションのみを Recovery クラスターにリストアします。

velero restore create ghost-restore \
    --from-backup ghost-backup \
    --include-namespaces ghost

リストアが成功したことの検証

リストアのステータスを確認し、リストアが正常に完了したことを確認しましょう。

velero restore describe ghost-restore

出力の Phase: Completed を探してください。Phase: InProgress と表示された場合は、しばらく待ってからコマンドを再実行してください。次に、Recovery クラスター内の Ghost ブログの LoadBalancer Service の URL を取得します。

kubectl -n ghost get svc ghost

EXTERNAL-IP の URL にアクセスして、ブログがリストアされたことを確認します。Ghost ブログと、前のステップで作成したサンプルのブログ記事が表示されるはずです。

おめでとうございます!Primary クラスターのバックアップと、Recovery クラスターへのアプリケーションのリストアに成功しました。

本番環境のバックアップ/リストア/DR 操作では、サービスが期待通りに動作していることを確認した後、本番の DNSレコードが Recovery クラスターを指すように移動する必要がある点に注意してください。

クリーンアップ

今後の課金が発生しないようにするために、リソースを削除してください。eksctl を使ってクラスターを作成した場合は、eksctl delete cluster <clustername> コマンドを使用してクラスターを削除できます。

バックアップを保存するために使用した S3 バケットと、Velero が使用している IAM ロールも削除する必要があります。

aws s3 rb s3://$BUCKET --force  
aws iam delete-policy --policy-arn arn:aws:iam::$ACCOUNT:policy/VeleroAccessPolicy

まとめ

ディザスタリカバリとマイグレーション戦略にはいくつかの種類があります。このブログ記事では、Velero が障害や災害イベントからの迅速なリカバリと、Amazon EKS のアプリケーションとクラスターリソースのシームレスな移行をどのように保証するかを紹介しました。このツールが提供するオプションをハイライトし、ステートフルアプリケーションをバックアップして新しいクラスターにリストアするプロセスを紹介しました。同様に、お客様は自分のアプリケーションと Kubernetes リソースを他の Amazon EKS クラスターにマイグレーション、レプリケーション、または以前のアプリケーション状態をリストアすることもできます。

このアプローチにより、単に CI/CD パイプラインをリダイレクトして新しい EKS クラスターにデプロイするのとは対照的に、ディザスタリカバリやマイグレーションイベントのためのオペレーションを一元化できます。これは、Kubernetes においてアプリケーションのデプロイやアップデートに使用される CI/CD パイプラインは、このような状況では必要のないアクションを実行する可能性があるためです。さらに、データの永続化に対処するためのアプローチを別途考える必要もあります。代わりに、このようなイベントのための特定の CI/CD パイプラインを作成することができます。

セルフマネージド型の Kubernetes クラスターの場合、お客様は Amazon EKS への移行にこのオープンソースツールを使用することもできます。このユースケースを深く掘り下げるには、このブログ記事で説明されているベストプラクティスに従うことをお勧めします。

翻訳はプロフェッショナルサービスの杉田が担当しました。原文はこちらです。