
Erwirbt die EBS-Datenträger eines AWS-AMI, das Sie starten können, und streamt Snapshots über EBS-Direct-APIs in einen privaten S3-Bucket mit sha256-Manifesten und optionaler Entpackung von Rohimages.
Erfassen Sie die Datenträger eines AMI, das Sie bereits starten können, in einem privaten S3-Bucket. Kein Katalog, keine Produktliste, keine fest eingebauten AMI-IDs. Sie übergeben die AMI-ID.
S3 ist der Speicher. Booten, Snapshot, Komprimieren und Hochladen laufen vollständig innerhalb von AWS. Lokale Bandbreite wird nur genutzt, wenn Sie später ein bestimmtes Objekt herunterladen.
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 setzen.raw | zstd | aws s3 cp -. Es wird kein Volume erstellt oder angehängt.manifest.json auf.region existieren.OptInRequired ist ein Konsolenschritt.Erfassen Sie nur Images, zu deren Ausführung Sie berechtigt sind. Halten Sie die Artefakte privat. Eine Marketplace-Softwaregebühr, falls das Listing eine hat, fällt nur an, solange die Boot-Instanz läuft.
AWS gibt Käufern nicht den Snapshot hinter einem Marketplace-AMI. copy-image
und create-volume gegen diesen Snapshot schlagen fehl. Das Booten des AMI erstellt ein
Volume, das dieses Konto besitzt, und von diesem Volume kann ein Snapshot erstellt werden.
Ein Volume, das noch einen Marketplace-Produktcode trägt, kann nur als
Root-Gerät einer gestoppten Instanz angehängt werden, daher funktioniert das Anhängen an einen Helper als Daten-
Datenträger nicht. ListSnapshotBlocks + GetSnapshotBlock liefern die Bytes
über HTTPS ohne Anhängen. Nicht zugewiesene Blöcke werden als Nullen ausgegeben, damit die Offsets
korrekt bleiben.
Die Direct-API spricht CBOR mit PascalCase-Membern. Checksum ist base64 des
rohen Digests, nicht hex. ebs_snapshot_read.py behandelt beides.
jq, flock und Anmeldedaten, die den Stack anwenden und die
unten genannten Instance-/Snapshot-/SSM-/S3-Aufrufe ausführen könnenzstd nur für unpack.shVom Operator verwendete Berechtigungen, die von den Skripten genutzt werden (die Helper-Rolle ist separat und wird von Terraform erstellt):
ec2:DescribeImages, DescribeInstances, DescribeSnapshots, RunInstances,
TerminateInstances, CreateSnapshot, DeleteSnapshot, CreateTags,
RegisterImageiam:PassRole auf das Helper-Instance-Profilssm:GetParameter, SendCommand, GetCommandInvocation,
DescribeInstanceInformations3:* auf den Artefakt-Bucket (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 ist ein Platzhalter. Ersetzen Sie ihn durch eine AMI-ID, die dieses
Konto starten kann.
make apply erstellt ein VPC, eine Egress-Only-Sicherheitsgruppe, einen S3-Bucket und
die Helper-IAM-Rolle. Es startet keine kostenpflichtige Compute, es sei denn
helper_enabled = true. Das VPC hat kein NAT-Gateway, daher sind die Leerlaufkosten nur der Bucket
(und der ist leer, bis Sie etwas erfassen).
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 beschreibt das AMI und gibt den Plan aus. Es startet nichts.
Standardwerte:
| Flag | Standard | Hinweise |
|---|---|---|
--boot-type | m5.xlarge, oder m6g.xlarge wenn das AMI arm64 ist | Listings lehnen oft andere Typen ab. Der AWS-Fehler nennt die, die sie erlauben. |
--dwell | 180 | Sekunden, die der Gast läuft, bevor der Snapshot erstellt wird. 0 erstellt den Snapshot, sobald die Instanz läuft. |
--workers | 32 | Gleichzeitige GetSnapshotBlock-Aufrufe pro Datenträger. |
Labels müssen ^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$ entsprechen. Sie werden zu S3-Keys.
Ein erneuter Lauf überspringt ein Label, dessen Objekt bereits in S3 liegt und dessen sha256 im
Manifest steht. --force ruft es erneut ab.
images.tsv, ein Image pro Zeile. Leerzeilen und #-Kommentare werden ignoriert.
Das dritte Feld ist ein optionaler Instanztyp.
# LABEL AMI BOOT_TYPE
my-image ami-0123456789abcdef0
other-image ami-0123456789abcdef0 m5.2xlarge
make dump-batch BATCH=images.tsv JOBS=2
--jobs N gibt jedem Worker seinen eigenen Helper-Slot. Manifest-Aktualisierungen werden
mit flock gesperrt. Zwei separate Treiberprozesse können sich manifest.json teilen; geben Sie
ihnen unterschiedliche DUMP_STATE_DIR-Werte, wenn sie keine Helper-Slot-Datei teilen dürfen.
make probe AMI=ami-0123456789abcdef0
run-instances --dry-run ist kostenlos. DryRunOperation bedeutet, dass das Konto es
starten kann. OptInRequired bedeutet, dass Sie dieses Listing in der AWS-Konsole akzeptieren und dann
erneut prüfen müssen. Dieses Repo akzeptiert keine Bedingungen für Sie.
--snapshot-id überspringt das Booten und liest einen vorhandenen Snapshot. Nur ein einzelnes Image.--register-ami registriert ein startbares AMI in diesem Konto aus den gerade erstellten
Snapshots und behält diese Snapshots. Sie werden pro GB-Monat abgerechnet.--keep-snapshot behält die Snapshots, ohne ein AMI zu registrieren. Die Bereinigung
überspringt Snapshots mit dem Tag Keep=true, es sei denn, Sie übergeben --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 prüft den sha256 des komprimierten Objekts, bevor es das Label als
heruntergeladen vermerkt. unpack schreibt ein sparses Raw-Image unter artifacts/raw/ und eine
.diskmeta.txt (file, sfdisk, blkid, parted). Mounten mit
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