# Восстановление: два отдельных опыта

Выполняется только внутри одноразовой VM (Virtual Machine — виртуальная машина)
из separate-lab.md. На 192.168.0.12 эти команды **не выполняются**.
Здесь нет готового восстановления производственного кластера.

API (Application Programming Interface — программный интерфейс);
HA (High Availability — высокая доступность);
TLS (Transport Layer Security — защита соединения);
RTO (Recovery Time Objective — целевое время восстановления).

## Опыт A. Большинство трёх участников

Контекст kind-kaas-ha. Сначала:

```bash
kubectl --context kind-kaas-ha -n default create configmap restore-marker --from-literal=message=before-snapshot
docker ps --format '{{.Names}}'
kubectl --context kind-kaas-ha -n kube-system get pods -l component=etcd -o wide
```

Ожидаются kaas-ha-control-plane, kaas-ha-control-plane2 и kaas-ha-control-plane3.
Не останавливай первый контейнер: он нужен как стабильный адрес учебной проверки.

```bash
docker stop kaas-ha-control-plane3
kubectl --context kind-kaas-ha --request-timeout=10s get configmap restore-marker
docker stop kaas-ha-control-plane2
kubectl --context kind-kaas-ha --request-timeout=10s get configmap restore-marker
docker start kaas-ha-control-plane2 kaas-ha-control-plane3
kubectl --context kind-kaas-ha wait --for=condition=Ready nodes --all --timeout=180s
```

После одной остановки запрос должен работать; после двух ожидается отказ/таймаут.
После возвращения дождись восстановления. Контейнеры никогда не запускай одновременно
с восстановленными копиями их старых data-dir как будто это один кластер.

## Опыт B. Независимая копия и восстановление etcd

Для первого опыта восстановления используй **один** управляющий участник:
обычный kind-kaas-lab из separate-lab.md. Это упрощает членство и отделяет его от опыта большинства.
Сначала удали свой kaas-ha, создай обычный kaas-lab.
Не применяй этот порядок к трём участникам или существующему кластеру.

```bash
kubectl --context kind-kaas-lab -n default create configmap restore-marker --from-literal=message=before-snapshot
CP=kaas-lab-control-plane
ETCD_POD=etcd-kaas-lab-control-plane
kubectl --context kind-kaas-lab -n kube-system exec "$ETCD_POD" -- etcdctl version
kubectl --context kind-kaas-lab -n kube-system exec "$ETCD_POD" -- etcdutl version
kubectl --context kind-kaas-lab -n kube-system exec "$ETCD_POD" -- etcdutl snapshot restore --help
```

Проверь поддержку --bump-revision и --mark-compacted. Если etcdutl отсутствует или
параметры не поддерживаются, остановись и возьми инструмент соответствующего выпуска etcd
на отдельную VM по официальной инструкции. Не убирай параметры молча.
Старый учебный образ и текущий выпуск etcd могут иметь разные возможности.

Сохрани снимок через etcdctl с локальными сертификатами учебного контейнера:

```bash
umask 077
mkdir -p ~/kaas-sandbox/restore-evidence
kubectl --context kind-kaas-lab -n kube-system exec "$ETCD_POD" -- etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key snapshot save /var/lib/etcd/course-snapshot.db
kubectl --context kind-kaas-lab -n kube-system exec "$ETCD_POD" -- etcdutl snapshot status /var/lib/etcd/course-snapshot.db -w table
docker cp "$CP":/var/lib/etcd/course-snapshot.db ~/kaas-sandbox/restore-evidence/snapshot.db
sha256sum ~/kaas-sandbox/restore-evidence/snapshot.db
```

Копия вынесена из контейнера, но всё ещё на той же VM. Для защиты от потери VM
перенеси её отдельно закрытым способом. Она может содержать Secrets, не публикуй файл.

Ниже сначала создаётся новый каталог, а исходный остаётся нетронутым:

```bash
CP_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$CP")
kubectl --context kind-kaas-lab -n kube-system exec "$ETCD_POD" -- etcdutl snapshot restore /var/lib/etcd/course-snapshot.db --name "$CP" --initial-cluster "$CP=https://$CP_IP:2380" --initial-advertise-peer-urls "https://$CP_IP:2380" --initial-cluster-token course-restored --bump-revision 1000000000 --mark-compacted --data-dir /var/lib/etcd/course-restored
```

Успешная команда доказывает только чтение копии и создание data-dir.
Для возврата Kubernetes нужны следующие действия на **этом одноразовом** одиночном control plane:

1. Измени marker на after-snapshot и проверь новое значение.
2. Вынеси kube-apiserver.yaml, kube-controller-manager.yaml и kube-scheduler.yaml
   из /etc/kubernetes/manifests во временный закрытый каталог **вне** manifests.
   Дождись остановки их контейнеров по `docker exec "$CP" crictl ps`.
3. Вынеси etcd.yaml туда же и дождись остановки etcd. Не редактируй файл рядом
   с действующим манифестом: kubelet может прочитать оба.
4. В сохранённом etcd.yaml измени **hostPath.path** тома etcd-data:
   /var/lib/etcd → /var/lib/etcd/course-restored.
   Путь внутри контейнера и аргумент --data-dir=/var/lib/etcd остаются прежними.
   Сверь --name и peer-адрес с параметрами restore.
5. Верни только etcd.yaml в manifests. По журналу нового контейнера и endpoint health
   с прежними TLS-сертификатами проверь готовность. Затем верни остальные три манифеста.
6. Через kind-kaas-lab дождись /readyz; проверь marker=before-snapshot.
   Создай ConfigMap с новым именем и новый Deployment, затем проверь согласование
   и готовность приложения. Используй demo.yaml после загрузки образа из separate-lab.md.
7. Запиши время от начала аварийного опыта до проверенного ответа приложения.
   Старые данные и отдельную копию сохраняй до завершения разбора.

Это намеренно ручная работа с чтением конкретного static Pod manifest, а не скрипт,
который переписывает любой сервер. Сопоставь шаги с официальным порядком для выбранной версии:
https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/
https://etcd.io/docs/v3.6/op-guide/recovery/

Если выполнен только restore каталога — отметь «частичный опыт etcd».
Критерий восстановления Kubernetes отмечается только после шагов 6–7.
Восстановление management cluster с облачными ресурсами требует дополнительного сравнения
владения и инвентаря из модулей Cluster API и выпускного проекта.
