---
title: 'Перенести данные томов между кластерами Kubernetes'
sidebar_label: 'Перенести данные томов между кластерами Kubernetes'
sidebar_position: 12
description: 'Как перенести данные томов между кластерами Kubernetes с помощью K8up'
---

import Formbricks from '@theme/MDXComponents/Formbricks'

# Перенести данные томов между кластерами Kubernetes

Вы можете перенести данные томов (PersistentVolumeClaim, PVC) из одного кластера Kubernetes в другой с помощью оператора K8up.

K8up — оператор резервного копирования для Kubernetes.
Он создает резервные копии данных PVC с помощью restic, загружает их в S3-совместимое хранилище и восстанавливает в любом кластере, в котором установлен K8up.
Способ подходит, когда нужно перенести данные отдельных томов, а не весь кластер.

В примерах копия тома из пространства имен `my-app` исходного кластера сохраняется в объектное хранилище [S3 Selectel](/s3/) и восстанавливается в новый PVC в пространстве имен `my-app-new` целевого кластера.

1. [Установите K8up](#install-k8up).

2. [Создайте секреты для K8up](#create-k8up-secrets).

3. [Создайте резервную копию тома](#create-volume-backup).

4. [Восстановите данные в другом кластере](#restore-data).

## 1. Установить K8up \{#install-k8up}

K8up нужно установить и в исходный, и в целевой кластер: сначала CRD, затем оператор K8up через Helm.
Версия CRD должна соответствовать версии оператора K8up — подробнее на странице [Releases](https://github.com/k8up-io/k8up/releases) в GitHub репозитории K8up.

1. Откройте CLI.

2. Установите CRD K8up:

   ```bash
   kubectl apply -f https://github.com/k8up-io/k8up/releases/download/k8up-4.8.6/k8up-crd.yaml
   ```

3. Установите оператор K8up:

   ```bash
   helm repo add k8up-io https://k8up-io.github.io/k8up
   helm install k8up k8up-io/k8up --version 4.8.6 --namespace k8up --create-namespace
   ```

4. Повторите шаги 1-3 для целевого кластера.

## 2. Создать секреты для K8up \{#create-k8up-secrets}

Секреты создаются в пространстве имен с переносимыми томами.
Нужны два секрета: с S3-ключом для доступа к хранилищу и с паролем репозитория restic.
Паролем репозитория шифруются все резервные копии, без пароля восстановить данные не получится.

1. Откройте CLI.

2. Создайте файл `secrets.yaml` с секретами:

   ```yaml
   apiVersion: v1
   kind: Secret
   metadata:
     name: s3-secrets-k8up
     namespace: my-app
   stringData:
     username: <s3_access_key>
     password: <s3_secret_key>
   ---
   apiVersion: v1
   kind: Secret
   metadata:
     name: restic-repository-password
     namespace: my-app
   stringData:
     password: <repo_password>
   ```

   Укажите:

   * `<s3_access_key>` — значение поля **Access key** из [S3-ключа](/access-control/manage/edit-user-data-or-role.mdx#issue-s3-key);
   * `<s3_secret_key>` — значение поля **Secret key** из [S3-ключа](/access-control/manage/edit-user-data-or-role.mdx#issue-s3-key);
   * `<repo_password>` — пароль репозитория restic, придумайте и сохраните его.
     Паролем репозитория шифруются все резервные копии, без пароля восстановить данные не получится.

3. Примените секреты:

   ```bash
   kubectl apply -f secrets.yaml
   ```

## 3. Создать резервную копию тома \{#create-volume-backup}

:::warning

Чтобы копия данных была согласованной, на время копирования остановите запись в том.

:::

1. Откройте CLI.

2. Добавьте метку PVC, по которой K8up найдет том:

   ```bash
   kubectl -n my-app label pvc <pvc_name> app.kubernetes.io/name=<pvc_name>
   ```

   Укажите `<pvc_name>` — имя переносимого PVC.

3. Создайте файл `backup.yaml` с ресурсом Backup:

   ```yaml
   apiVersion: k8up.io/v1
   kind: Backup
   metadata:
     name: <pvc_name>
     namespace: my-app
   spec:
     podSecurityContext:
       runAsUser: 0
       runAsGroup: 1000
     labelSelectors:
       - matchExpressions:
           - key: app.kubernetes.io/name
             operator: In
             values:
               - "<pvc_name>"
     failedJobsHistoryLimit: 2
     successfulJobsHistoryLimit: 2
     backend:
       repoPasswordSecretRef:
         name: restic-repository-password
         key: password
       s3:
         endpoint: https://s3.<pool>.storage.selcloud.ru
         bucket: <bucket_name>
         accessKeyIDSecretRef:
           name: s3-secrets-k8up
           key: username
         secretAccessKeySecretRef:
           name: s3-secrets-k8up
           key: password
   ```

   Укажите:

   * `<pvc_name>` — имя переносимого PVC;
   * `<pool>` — [пул](/infrastructure/locations.mdx#pool), в котором находится бакет, например `ru-1`;
   * `<bucket_name>` — имя [бакета](/s3/buckets/create-bucket.mdx) в S3 Selectel.

   Здесь `podSecurityContext` задает пользователя (UID) и группу (GID), от имени которых под резервного копирования читает файлы тома. Значение `0` (root) позволяет читать все файлы. Если в журнале пода появились ошибки чтения файлов (`permission denied`), укажите UID и GID пользователя, от которого работает приложение с этим томом.

4. Примените ресурс Backup:

   ```bash
   kubectl apply -f backup.yaml
   ```

   K8up создаст под `backup-<pvc_name>`, который скопирует данные тома в хранилище.

5. Проверьте статус резервной копии и пода резервного копирования:

   ```bash
   kubectl -n my-app get backup
   kubectl -n my-app get pods
   ```

6. Убедитесь, что данные скопировались полностью, для этого посмотрите журнал пода резервного копирования:

   ```bash
   kubectl -n my-app logs <pod_name>
   ```

   Укажите `<pod_name>` — имя пода резервного копирования.

7. Запишите ID снапшота — он понадобится для восстановления:

   ```bash
   kubectl -n my-app get snapshots
   ```

   В ответе появится список снапшотов.

## 4. Восстановить данные в другом кластере \{#restore-data}

1. Создайте в целевом пространстве имен PVC, в который будут восстановлены данные.
   Размер PVC должен быть не меньше размера исходного тома.
   Для кластера Managed Kubernetes используйте инструкцию [Создать PersistentVolumeClaim](/managed-kubernetes/volumes/persistent-volumes.mdx#2-create-persistentvolumeclaim).

2. Создайте в целевом пространстве имен секреты, которые вы [создали на этапе 2](#create-k8up-secrets), — с теми же значениями, что и в исходном кластере.

3. Откройте CLI.

4. Создайте файл `restore.yaml` с ресурсом Restore:

   ```yaml
   apiVersion: k8up.io/v1
   kind: Restore
   metadata:
     name: <pvc_name>
     namespace: my-app-new
   spec:
     podSecurityContext:
       runAsUser: 0
       runAsGroup: 0
     snapshot: <snapshot_id>
     restoreMethod:
       folder:
         claimName: <pvc_name>
     backend:
       repoPasswordSecretRef:
         name: restic-repository-password
         key: password
       s3:
         endpoint: https://s3.<pool>.storage.selcloud.ru
         bucket: <bucket_name>
         accessKeyIDSecretRef:
           name: s3-secrets-k8up
           key: username
         secretAccessKeySecretRef:
           name: s3-secrets-k8up
           key: password
   ```

   Укажите:

   * `<snapshot_id>` — ID снапшота, который вы записали на шаге 7 при [создании резервной копии на этапе 3](#create-volume-backup);
   * `<pvc_name>` — имя PVC, который вы создали на шаге 1;
   * `<pool>` — пул, в котором находится бакет;
   * `<bucket_name>` — имя [бакета](/s3/buckets/create-bucket.mdx) в S3 Selectel.

   Здесь `podSecurityContext` задает пользователя (UID) и группу (GID), от имени которых восстанавливаются файлы, — восстановленные данные получат этого владельца. Укажите UID и GID пользователя, от которого будет работать приложение в целевом кластере, — иначе приложение может не получить доступ к восстановленным данным.

5. Примените ресурс Restore:

   ```bash
   kubectl apply -f restore.yaml
   ```

   K8up создаст под `restore-<pvc_name>`, который подключит PVC и восстановит в него данные.

6. Дождитесь завершения операции и проверьте журнал пода:

   ```bash
   kubectl -n my-app-new get pods
   kubectl -n my-app-new logs <pod_name>
   ```

   Укажите `<pod_name>` — имя пода восстановления.

7. Подключите восстановленный PVC к приложению в целевом кластере.

<Formbricks />
