VeleroでEKSクラスタをバックアップ

VeleroでEKSクラスタのバックアップを試してみたので手順をまとめます。
今回はプロバイダーがAWS、オブジェクトストアがS3なのでvelero-plugin-for-awsの手順に従ってインストールを行います。 その他サポートしているプロバイダーはこちらを参照してください。

github.com

実行環境

  • macOS Catalina Version 10.15.7
  • velero v1.5.2

CLIのインストール

Homebrewで velero をインストールします。

$ brew install velero

S3バケット作成

バックアップを保存するS3バケットを作成します。

$ BUCKET=<YOUR_BUCKET>
$ REGION=ap-northeast-1
$ aws s3api create-bucket \
    --bucket $BUCKET \
    --region $REGION \
    --create-bucket-configuration LocationConstraint=$REGION

# パブリックアクセスをブロック
$ aws s3api put-public-access-block \
    --bucket $BUCKET \
    --region $REGION \
    --public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"

f:id:hiroki-sawano:20201218185128p:plain

IAMユーザの作成

IAMユーザ velero を作成します。

$ aws iam create-user --user-name velero

f:id:hiroki-sawano:20201218185214p:plain

IAMポリシーの追加

IAMユーザ velero に次の通り、IAMポリシーを割り当てます。

$ 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 put-user-policy \
   --user-name velero \
   --policy-name velero \
   --policy-document file://velero-policy.json

f:id:hiroki-sawano:20201218185656p:plain

アクセスキーの作成

velero ユーザのアクセスキーを設定します。

$ aws iam create-access-key --user-name velero

{
    "AccessKey": {
        "UserName": "velero",
        "AccessKeyId": "<access-key>",
        "Status": "Active",
        "SecretAccessKey": "<secret-access-key>",
        "CreateDate": "2020-12-18T09:58:03+00:00"
    }
}
$ cat > velero-credentials <<EOF
[default]
aws_access_key_id=<access-key>
aws_secret_access_key=<secret-access-key>
EOF

Veleroのインストール

EKSクラスタにVeleroをインストールします。

$ velero install \
    --provider aws \
    --plugins velero/velero-plugin-for-aws:v1.1.0 \
    --bucket $BUCKET \
    --backup-location-config region=$REGION \
    --snapshot-location-config region=$REGION \
    --secret-file ./velero-credentials

...
Waiting for resources to be ready in cluster...
Namespace/velero: attempting to create resource
Namespace/velero: created
ClusterRoleBinding/velero: attempting to create resource
ClusterRoleBinding/velero: created
ServiceAccount/velero: attempting to create resource
ServiceAccount/velero: created
Secret/cloud-credentials: attempting to create resource
Secret/cloud-credentials: created
BackupStorageLocation/default: attempting to create resource
BackupStorageLocation/default: created
VolumeSnapshotLocation/default: attempting to create resource
VolumeSnapshotLocation/default: created
Deployment/velero: attempting to create resource
Deployment/velero: created
Velero is installed! ⛵ Use 'kubectl logs deployment/velero -n velero' to view the status.

velero 名前空間にVeleroがデプロイされました。

$ kubectl get all -n velero
NAME                          READY   STATUS    RESTARTS   AGE
pod/velero-866bf8c8d5-dgtcq   1/1     Running   0          90s

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/velero   1/1     1            1           90s

NAME                                DESIRED   CURRENT   READY   AGE
replicaset.apps/velero-866bf8c8d5   1         1         1       90s

バックアップ対象となるPersistentVolumeを用意

VeleroはPersistentVolume(EBS)のスナップショットを取得してくれるので、 動作確認のために適当なボリュームを用意しておきます。

❯ kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM   STORAGECLASS   REASON   AGE
pvc-...   10Gi       RWO            Delete           Bound    ...     gp2                     22d
pvc-...   1Gi        RWO            Delete           Bound    ...     gp2                     21d
pvc-...   10Gi       RWO            Delete           Bound    ...     gp2                     23d
pvc-...   10Gi       RWO            Delete           Bound    ...     gp2                     23d
pvc-...   10Gi       RWO            Delete           Bound    ...     gp2                     22d
pvc-...   10Gi       RWO            Delete           Bound    ...     gp2                     22d

バックアップ

次のコマンドでバックアップを取得します。

❯ velero backup create backup-20201218
Backup request "backup-20201218" submitted successfully.
Run `velero backup describe backup-20201218` or `velero backup logs backup-20201218` for more details.

バックアップの状況は velero backup describe で確認できます。

  • バックアップ中
❯ velero backup describe backup-20201218
Name:         backup-20201218
Namespace:    velero
Labels:       velero.io/storage-location=default
Annotations:  velero.io/source-cluster-k8s-gitversion=v1.18.9-eks-d1db3c
              velero.io/source-cluster-k8s-major-version=1
              velero.io/source-cluster-k8s-minor-version=18+

Phase:  InProgress

Errors:    0
Warnings:  0

Namespaces:
  Included:  *
  Excluded:  <none>

Resources:
  Included:        *
  Excluded:        <none>
  Cluster-scoped:  auto

Label selector:  <none>

Storage Location:  default

Velero-Native Snapshot PVs:  auto

TTL:  720h0m0s

Hooks:  <none>

Backup Format Version:  1.1.0

Started:    2020-12-18 19:30:00 +0900 JST
Completed:  <n/a>

Expiration:  2021-01-17 19:30:00 +0900 JST

Estimated total items to be backed up:  607
Items backed up so far:                 147

Velero-Native Snapshots: <none included>
  • バックアップ完了
❯ velero backup describe backup-20201218
Name:         backup-20201218
Namespace:    velero
Labels:       velero.io/storage-location=default
Annotations:  velero.io/source-cluster-k8s-gitversion=v1.18.9-eks-d1db3c
              velero.io/source-cluster-k8s-major-version=1
              velero.io/source-cluster-k8s-minor-version=18+

Phase:  Completed

Errors:    0
Warnings:  0

Namespaces:
  Included:  *
  Excluded:  <none>

Resources:
  Included:        *
  Excluded:        <none>
  Cluster-scoped:  auto

Label selector:  <none>

Storage Location:  default

Velero-Native Snapshot PVs:  auto

TTL:  720h0m0s

Hooks:  <none>

Backup Format Version:  1.1.0

Started:    2020-12-18 19:30:00 +0900 JST
Completed:  2020-12-18 19:30:12 +0900 JST

Expiration:  2021-01-17 19:30:00 +0900 JST

Total items to be backed up:  561
Items backed up:              561

Velero-Native Snapshots:  6 of 6 snapshots completed successfully (specify --details for more information)

取得したバックアップは velero get backups で一覧表示できます。

$ velero get backups
NAME                   STATUS      ERRORS   WARNINGS   CREATED                         EXPIRES   STORAGE LOCATION   SELECTOR
backup-20201218        Completed   0        0          2020-12-18 19:30:00 +0900 JST   29d       default            <none>

S3バケット作成で用意したバケットにバックアップが作成されました。

f:id:hiroki-sawano:20201218193401p:plain

PVはEBSのスナップショットとしてバックアップされています。

f:id:hiroki-sawano:20201218193854p:plain

バックアップの削除

velero backup delete でS3に保存したバックアップやEBSのスナップショットも全て削除してくれます。

$ velero backup delete backup-20201218
Are you sure you want to continue (Y/N)? Y
Request to delete backup "backup-20201218" submitted successfully.
The backup will be fully deleted after all associated data (disk snapshots, backup files, restores) are removed.

バックアップスケジュールの設定

実運用では自動的に日時バックアップを取得したいので、次のマニフェストを作成します。
spec.schedule にバックアップの取得スケジュール(UTC)、 spec.template.includedNamespaces にバックアップする名前空間spec.template.ttl に保持期間を指定します。
Schedule APIの詳細についてはこちらを参照してください。

apiVersion: velero.io/v1
kind: Schedule
metadata:
  name: daily
  namespace: velero
spec:
  schedule: 0 0 * * *
  template:
    includedNamespaces:
    - '*'
    ttl: 720h0m0s
$ kubectl apply -f daily-backup.yml 

0時(UTC)にバックアップされるかと思いきや、即時バックアップが作成されました。 特に問題でもないですが、こちらのIssueの通り、指定した時刻だけでなく即時バックアップされる不具合があるそうです。

$ velero get backups
NAME                   STATUS      ERRORS   WARNINGS   CREATED                         EXPIRES   STORAGE LOCATION   SELECTOR
daily-20201218105219   Completed   0        0          2020-12-18 19:52:19 +0900 JST   29d       default            <none>

日をおいて確認すると、日毎のバックアップが期待通り取得されていました。

❯ velero get backups
NAME                   STATUS      ERRORS   WARNINGS   CREATED                         EXPIRES   STORAGE LOCATION   SELECTOR
daily-20201220000053   Completed   0        0          2020-12-20 09:00:53 +0900 JST   29d       default            <none>
daily-20201219000053   Completed   0        0          2020-12-19 09:00:53 +0900 JST   28d       default            <none>
daily-20201218105219   Completed   0        0          2020-12-18 19:52:19 +0900 JST   27d       default            <none>

f:id:hiroki-sawano:20201220220053p:plain

参考