
Получает EBS-диски AWS AMI, которую вы можете запустить, передавая снимки через EBS direct APIs в приватный S3-бакет с манифестами sha256 и опциональной распаковкой raw-образов.
Получите диски AMI, который вы уже можете запустить, в приватный бакет S3. Ни каталога, ни списка продуктов, ни вшитых AMI id. Вы передаёте AMI id.
S3 — это хранилище. Загрузка, снапшот, сжатие и выгрузка выполняются внутри AWS. Локальная пропускная способность используется только если вы позже вытянете конкретный объект.
graph LR
A[AMI you supply] -->|run-instances| B[boot instance]
B -->|every EBS disk| C[snapshots you own]
C --> D[terminate boot instance]
C -->|ListSnapshotBlocks / GetSnapshotBlock| E[helper]
E -->|raw then zstd| F[(S3 golden store)]
F -->|optional pull| G[local artifacts]
DeleteOnTermination.raw | zstd | aws s3 cp -. Том не создаётся и не подключается.manifest.json.region.OptInRequired — это шаг в консоли.Снимайте дампы только тех образов, на запуск которых у вас есть право. Храните артефакты приватно. Плата за ПО Marketplace, если она есть у листинга, начисляется только пока boot-инстанс работает.
AWS не даёт покупателям снапшот, лежащий в основе AMI из Marketplace. copy-image
и create-volume для этого снапшота завершаются ошибкой. Загрузка AMI создаёт
том, принадлежащий этому аккаунту, и с этого тома можно снять снапшот.
Том, который всё ещё несёт product code Marketplace, можно подключить только как
корневое устройство остановленного инстанса, поэтому подключение его к helper как диска
данных не работает. ListSnapshotBlocks + GetSnapshotBlock возвращают байты
по HTTPS без подключения. Невыделенные блоки выдаются как нули, чтобы смещения
оставались корректными.
Прямой API говорит на CBOR с членами в PascalCase. Checksum — это base64 от
сырого дайджеста, а не hex. ebs_snapshot_read.py обрабатывает и то, и другое.
jq, flock и учётные данные, которые могут применить стек и выполнить
вызовы instance/snapshot/SSM/S3, описанные нижеzstd только для unpack.shПрава оператора, используемые скриптами (роль helper отдельная и создаётся Terraform):
ec2:DescribeImages, DescribeInstances, DescribeSnapshots, RunInstances,
TerminateInstances, CreateSnapshot, DeleteSnapshot, CreateTags,
RegisterImageiam:PassRole на instance profile helperssm:GetParameter, SendCommand, GetCommandInvocation,
DescribeInstanceInformations3:* на бакет артефактов (get/put/list/delete/head)sts:GetCallerIdentitycd terraform && cp terraform.tfvars.example terraform.tfvars
# edit region / name_prefix if needed — still no AMI ids
cd ..
make init && make apply && make configure
make probe AMI=ami-0123456789abcdef0
make dump LABEL=my-image AMI=ami-0123456789abcdef0
make ls
ami-0123456789abcdef0 — это плейсхолдер. Замените его на AMI id, который
этот аккаунт может запустить.
make apply создаёт VPC, security group только для исходящего трафика, бакет S3 и
роль IAM для helper. Он не запускает оплачиваемые вычисления, если только
helper_enabled = true. В VPC нет NAT gateway, поэтому стоимость простоя — это только бакет
(и он пуст, пока вы что-нибудь не снимете).
scripts/dump.sh --ami ami-0123456789abcdef0 --label my-image
scripts/dump.sh --ami ami-0123456789abcdef0 --label my-image --boot-type m5.2xlarge --dwell 60
scripts/dump.sh --ami ami-0123456789abcdef0 --label my-image --dry-run
scripts/dump.sh --ami ami-0123456789abcdef0 --label my-image --snapshot-id snap-0123456789abcdef0
--dry-run описывает AMI и печатает план. Он не запускает.
Значения по умолчанию:
| Флаг | По умолчанию | Примечания |
|---|---|---|
--boot-type | m5.xlarge, или m6g.xlarge, если AMI — arm64 | Листинги часто отклоняют другие типы. В ошибке AWS указаны те, которые они разрешают. |
--dwell | 180 | Секунды, которые гость работает до снапшота. 0 — снапшот сразу после запуска инстанса. |
--workers | 32 | Одновременные вызовы GetSnapshotBlock на диск. |
Метки должны соответствовать ^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$. Они становятся ключами S3.
Повторный запуск пропускает метку, объект которой уже есть в S3 и sha256 которой есть в
манифесте. --force извлекает заново.
images.tsv, один образ на строку. Пустые строки и комментарии # игнорируются.
Третье поле — необязательный тип инстанса.
# LABEL AMI BOOT_TYPE
my-image ami-0123456789abcdef0
other-image ami-0123456789abcdef0 m5.2xlarge
make dump-batch BATCH=images.tsv JOBS=2
--jobs N даёт каждому воркеру свой слот helper. Обновления манифеста блокируются
через flock. Два отдельных процесса-драйвера могут совместно использовать manifest.json; задайте
им разные значения DUMP_STATE_DIR, если они не должны делить файл слота helper.
make probe AMI=ami-0123456789abcdef0
run-instances --dry-run бесплатен. DryRunOperation означает, что аккаунт может
его запустить. OptInRequired означает, что нужно принять этот листинг в консоли AWS, а затем
проверить снова. Этот репозиторий не будет принимать условия за вас.
--snapshot-id пропускает загрузку и читает один существующий снапшот. Только для одного образа.--register-ami регистрирует запускаемый AMI в этом аккаунте из только что созданных
снапшотов и сохраняет эти снапшоты. Они тарифицируются за ГБ-месяц.--keep-snapshot сохраняет снапшоты без регистрации AMI. Очистка
пропускает снапшоты с тегом Keep=true, если только вы не передадите --force.make ls # keys + manifest, no download
make watch # in-flight helper log, multipart upload size
make pull LABELS="my-image"
make pull LABELS="my-image" RAW=1 # also write a sparse .raw
scripts/unpack.sh my-image # partition metadata next to the raw
pull проверяет sha256 сжатого объекта, прежде чем отметить метку как
загруженную. unpack записывает разрежённый raw-образ в artifacts/raw/ и
.diskmeta.txt (file, sfdisk, blkid, parted). Монтируйте через
losetup -Pf --show artifacts/raw/<label>.raw.
s3://<bucket>/
golden/<label>/<label>.raw.zst
golden/<label>/<label>.raw.zst.sha256 # checksum of the compressed stream
golden/<label>/<label>.stats.json
golden/<label>/<label>.<device>.raw.zst # extra disks, root is the unsuffixed object
_scripts/snapshot_to_s3.sh
_scripts/ebs_snapshot_read.py
_status/<label>.json # expires after 7 days
_logs/<label>.log # expires
У golden/ нет истечения жизненного цикла. Незавершённые multipart-загрузки прерываются
через 3 дня. terraform destroy удаляет бакет (force_destroy = true),
включая golden/.
manifest.json (локальный, в gitignore) — это индекс: AMI id, имя, владелец,
архитектура, product codes, ключи по дискам, sha256, размеры, время извлечения.