Перейти к основному содержимому

Yandex Cloud Cron Snapshot

· 3 мин. чтения

Upd: я дополнил пост расширенным примером применимом в облаке с большим количеством дисков. Также там добавлено удаление старых снепшотов.

Upd2: https://github.com/nikolaymatrosov/go-yc-serverless-snapshotЯ переписал пример на Go, так как в Облаке недавно появился рантайм для Go 1.14.

Upd3: Пример на Go обновлен для версии ратайма 1.16.

Upd 2022–01–08: Пример на для NodeJS переписан с использованием новой версии SDK v2. Код из поста ниже устарел.

Так как пока в Облаке отсутствует нативная возможность настроить создание снэпшотов по расписанию можно сделать эту функциональность из подручных средств.

Я подумал, что будет удобно разметить диски, которые мы хотим бекапить.

Наш демо-диск

Для этого при помощи CLI назначим ему label.

yc compute disk update --id ef34spdueq1ps7b37m51 --labels snapshot=1

Теперь создадим функцию. Вот код на TypeScript.

import {DiskService, SnapshotService} from "yandex-cloud/api/compute/v1";

const FOLDER_ID = process.env.FOLDER_ID;

export async function handler(event, context) {
const snapshotService = new SnapshotService();
const diskService = new DiskService();
const diskList = await diskService.list({
folderId: FOLDER_ID,
});

const snapshotOperations = [];

for (const disk of diskList.disks) {
if ('snapshot' in disk.labels) {
const op = snapshotService.create({
folderId: FOLDER_ID,
diskId: disk.id
});
snapshotOperations.push(op);
}
}
// await Promise.all(snapshotOperations);
}
package.json
{
"name": "functions",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"yandex-cloud": "~1.1.1"
}
}
tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"target": "es2018",
"sourceMap": true
},
"exclude": [
"node_modules"
]
}

Следующим шагом делаем из кода и установленных node_modulesархив и заливаем его в Object Storage. Потому что на прямую загрузку архива есть лимит в 3.5Мб. Но после npm install мы точно не влезем в этот лимит.

Кстати, если вы собираете архив на ОС отличной от Linux не забудьте выполнить следующую команду.

npm rebuild --target_platform=linux --target_arch=x64 --target_libc=glibc --update-binary

Иначе у вас не будет нужной папки node-v72-linux-x64-glibc (это бинарники GRPC) и функция будет падать не найдя её.

Теперь можно заливать архив и переходить к созданию сервисного аккаунта, функции и триггера.

Сервисный аккаунт с ролью editor.

Функция

Триггер

Отдельно стоит отметить, что триггер ожидает cron-выражение не в linux формате, а в AWS. Вот документация по формату.

Можно руками дернуть функцию и убедиться, что снепшот создался.

Upd 18.01.2020:

Приведенное выше решение будет хорошо работать если у вас в фолдере мало дисков. Но если у вас их хотя бы 16, то вы сталкнетесь с тем, что вы не можете делать снепшоты со всех дисков одновременно.

В облаке есть квота на количество одновременно запущенных операций. По умолчанию она равна 15. Ее конечно можно поднять, но рано или поздно вы все равно упретесь в жесткий лимит. Так что можно подойти к проблеме с другой стороны и спроектировать чуть более сложную систему бекапа, которая будет автоматически ретраить операции создания снепшота, если что-то пойдет не так и позволит нам не беспокоиться об этой квоте.

Для этого нам понадобится очередь сообщений и две функции. Первая функция будет запускаться по cron’у и складывать в очередь задачи для второй функции. Вторая же будет вычитывать задачи из очереди сообщений и обрабатывать их, создавая снепшоты.

При создании снепшота в поле labels будет добавляться время когда этот снепшот можно будет удалять. На основе этой информации еще одна функция запускающаяся по крону будет чистить устаревшие снепшоты.

Код этого решения здесь.