Skip to content

Docker nebo Kubernetes Production Volume smazáno: Záchrana docker system prune --volumes, overlay2 Inody a etcd Snímky

Tísňová čísla se v jednotlivých zemích liší. Tato stránka používá 911, číslo pro Spojené státy a Kanadu. Mnoho dalších zemí používá číslo 112, 999 nebo jiné číslo. Najděte číslo pro vaši zemi.

Běh docker compose down -v, docker system prune -a --volumes, docker volume rmnebo kubectl delete pvc na nesprávné záložce terminálu v produkci je jedním z nejrychlejších způsobů, jak vymazat živý svazek databáze PostgreSQL, MySQL, MariaDB, Redis, MongoDB nebo SQLite. Na rozdíl od snímků cloudového virtuálního stroje, které se přesouvají do 7denního koše, ovladač místního svazku Docker (/var/lib/docker/volumes/<name>/_data) a Kubernetes local-path / hostPath poskytovatelé okamžitě vydají standardní POSIX unlink() a rmdir() volání přímo proti základnímu hostitelskému souborovému systému Linuxu (ext4, XFSnebo Btrfs). Každý zápis, ke kterému dojde na tomto hostiteli Linuxu po dokončení příkazu, může přepsat uvolněné bloky databáze na disku. Pokud je disk vašeho serveru zaplněn na 100 procent (0 bytes free), než někdo utekl docker system prune --volumes v panice se poraďte disk serveru je 100% plný, databáze WAL log bloat a obnova s ​​nulovým prostorem; pro mazání linuxových souborů naboso mimo kontejnery viz náhodné rm -rf nebo Shift-Delete na ext4, XFS, APFS a NTFS: opětovné připojení pouze pro čtení a vyřezávání inodů a poškození řetězce virtuálních strojů VMDK, VHDX a qcow2 a záchrana hypervizoru. Pokud tento výpadek výroby ovlivní nemocniční péči o pacienty, nouzové odeslání nebo bezpečnostní systémy veřejných služeb, zavolejte na místní tísňové číslo (911 ve Spojených státech a Kanadě, 112 po celé Evropské unii, 999 ve Spojeném království) nebo se podívejte do našeho adresáře tísňová čísla.

Udělejte to teď

  1. NEPOUŽÍVEJTE docker compose up -d, systemctl restart dockernebo znovu nasaďte Kubernetes pod: Opětovné vytvoření kontejneru nebo restartování démona Docker zapíše megabajty nových overlay2 metadata, kontejnerové protokoly JSON a čerstvě inicializované prázdné databázové soubory (initdb) přímo nad přesným ext4 nebo XFS bloky, kde se váš smazaný svazek před několika sekundami nacházel.
  2. **Zkontrolujte za 5 sekund, pokud proces kontejneru (postgres, mysqld, redis-server, node, python) stále běží v paměti (ps aux a sudo lsof +L1(PID) má otevřený deskriptor souboru (FD). Tyto soubory můžete zkopírovat přímo z /proc/<PID>/fd/ nebo /proc/<PID>/root/ s nulovou ztrátou dat před zastavením kontejneru.
  3. Pokud je kontejner již zastaven a svazek byl odstraněn (docker compose down -v nebo docker system prune --volumes), okamžitě zmrazit zápisy na hostitelský disk: Zastavte démona Docker (sudo systemctl stop docker.socket docker.service containerd), takže kontejnery na pozadí a zdravotní kontroly přestanou zapisovat logy /var/lib/docker, pak buď znovu namontujte /var/lib/docker (nebo kořen / oddíl) jen pro čtení (sudo mount -o remount,ro /) nebo okamžitě pořiďte snímek objemu cloudu na úrovni bloku (AWS EBS Snapshot, GCP Persistent Disk Snapshot, DigitalOcean Volume Snapshot), než se čehokoli dotknete.
  4. Pokud jste na Kubernetes (kubectl delete pvc nebo kubectl delete namespace), zkontrolujte PersistentVolume (PV) ReclaimPolicy (kubectl get pv) ihned:
  5. Pokud PV měl persistentVolumeReclaimPolicy: Retain, vaše data nevymazána: the PV prostě se přestěhoval do Released stav a váš cloudový disk (EBS, Azure Disk, Ceph RBD, NFS) je 100 procent neporušený.
  6. I když kubectl delete pvc je zaseknutý v Terminating, Kubernetes Finalizátory (kubernetes.io/pvc-protection) zablokuje ovladač CSI ve smazání základního úložiště, pokud jakýkoli modul stále odkazuje na toto PVC. Neodstraňujte modul, dokud nezkopírujete data z běžícího modulu.
  7. Zobrazte základní blokový oddíl (dd / ddrescue přes SSH) na externí disk nebo samostatný cloudový svazek před spuštěním ext4magic, extundeletenebo PhotoRec: Nikdy nespouštějte vyřezávače souborů, které zapisují výstupní soubory na stejný diskový oddíl, ze kterého obnovujete /var/lib/docker/volumes.
  8. Pro poškozený nebo náhodně vymazaný stav clusteru Kubernetes (kubectl delete crd / namespace), zastavit kube-apiserver a obnovit své nejnovější etcd snímek (etcdctl snapshot restore): Pokud je stav clusteru v etcd byla vymazána, zatímco základní objemy cloudového úložiště stále existují, obnovuje se etcd obnoví vše PV, PVC, Secreta ConfigMap objekty současně.

Danger

Nikdy neodstraňujte kubernetes.io/pvc-protection nebo kubernetes.io/pv-protection finalizátor s kubectl patch ... -p '{"metadata":{"finalizers":null}}' když je tam zaseknutý PVC Terminating: Tento finalizátor je jediná věc, která udržuje váš cloudový ovladač CSI (aws-ebs-csi-driver, pd.csi.storage.gke.io, Longhorn, Rook-Ceph) od vydání hardwaru DeleteVolume Volání API ke zničení vašeho produkčního disku. Zatímco je PVC zaseknuté Terminating, Pod stále běží a svazek je stále připojen: spustit kubectl exec nebo kubectl cp (nebo pg_dump / mysqldump) okamžitě zachránit 100 procent vaší databáze, než modul skončí.


Rozhodovací strom: odstraněn svazek Docker, overlay2 vrstva nebo třídění PVC Kubernetes

Pomocí tohoto vývojového diagramu vyberte nejrychlejší cestu obnovy s nulovou ztrátou na základě toho, zda je proces kontejneru stále aktivní, zda byl svazek zálohován místním diskem nebo cloudovým úložištěm CSI a který souborový systém je hostitelem. /var/lib/docker:

flowchart TD
    Start["Po příkazu Docker nebo Kubernetes Delete chybí produkční data"] --> WhichEnv{"Která platforma a velení způsobily ztrátu?"}

    WhichEnv -->|"Docker: Kontejner stále běží (soubory odpojené uvnitř svazku/kontejneru)"| ProcRescue["Záchrana otevřených deskriptorů nepropojených souborů pomocí sudo lsof +L1 a /proc/PID/fd/N nebo /proc/PID/root/"]

    WhichEnv -->|"Ukotvitelný panel: Kontejner zastaven a svazek odstraněn (složit -v / prořezat --volumes)"| StopDocker["Okamžitě spustit: sudo systemctl stop docker.socket docker kontejner"]

    WhichEnv -->|"Kubernetes: kubectl odstranit pvc / pv / statefulset / jmenný prostor"| K8sCheck{"Je podložka stále v provozu NEBO se PVC zaseklo v koncovce?"}

    K8sCheck -->|"Ano: Pod stále běží (finalizátor blokuje odstranění CSI)"| K8sExec["NEODSTRAŇUJTE Pod -> Okamžitě spusťte kubectl exec / pg_dump / tar přes stdout na místní disk"]
    K8sCheck -->|"Ne: Pod Gone -> Check kubectl get pv"| ReclaimCheck{"Co bylo PV ReclaimPolicy?"}

    ReclaimCheck -->|"Zachovat (stav PV = uvolněno)"| ClearClaimRef["100% nedotčená data -> Upravit PV pro odstranění spec.claimRef.uid -> Znovu navázat na nové PVC"]
    ReclaimCheck -->|"Smazat (Cloud EBS / PD / Longhorn / Local-Path)"| CloudOrLocal{"Cloudový svazek CSI nebo místní hostitelský disk?"}

    CloudOrLocal -->|"Cloud CSI (AWS EBS / GCP / Azure / Ceph)"| CloudSnap["Zkontrolujte koš cloudové konzole / automatické snímky EBS / koš Ceph RBD (rbd trash ls)"]
    CloudOrLocal -->|"Místní disk uzlu (místní cesta / cesta hostitele)"| StopDocker

    StopDocker --> RemountRO["Znovu připojit hostitelský oddíl pouze pro čtení (mount -o remount,ro) NEBO Streamovat obraz bloku přes SSH"]
    RemountRO --> HostFS{"Jaký souborový systém je hostitelem /var/lib/docker?"}
    HostFS -->|"ext4"| Ext4Rec["Použít debugfs / ext4magic Journal Inode Transaction Rollback (-a časové razítko)"]
    HostFS -->|"XFS / Btrfs"| CarveRec["Použijte Btrfs Roots / xfs_irecover / Custom Signature Carving pro SQLite, Postgres Heap nebo InnoDB .ibd"]

Fáze 1: Jak Docker a Kubernetes skutečně odstraňují svazky na disku

Před spuštěním jakéhokoli příkazu pro obnovu zjistěte, kde se vaše data na hostiteli Linuxu fyzicky nacházela a čeho se příkaz delete dotkl:

Typ úložiště a příkaz Delete Cesta hostitelského souborového systému na Linux Node Co příkaz Delete vlastně udělal Metoda okamžité obnovy
Pojmenovaný svazek Docker (docker volume rm nebo docker compose down -v) /var/lib/docker/volumes/<vol_name>/_data Odpojili soubory uvnitř _data/ a odstranil záznam z adresáře /var/lib/docker/volumes/metadata.db (boltdb). Okamžitě zastavte Docker, znovu připojte /var/lib/docker pouze pro čtení a obnovit nepropojené inody prostřednictvím ext4magic / debugfs nebo vyřezávání podpisu.
Anonymní svazek dockeru (docker run -v /var/lib/mysql + docker rm -v nebo docker system prune --volumes) /var/lib/docker/volumes/<64-char-hex-id>/_data docker system prune --volumes odstraní každý anonymní a pojmenovaný svazek, na který aktuálně neodkazuje alespoň jeden existující kontejner. Okamžitě zastavte Docker; pokud jste měli jiné zastavené kontejnery, jejichž objemy nebyly ne ořezány, zkontrolujte zbývající /var/lib/docker/volumes/*/_data složky nejprve před vyřezáváním nepřidělených bloků.
Kontejnerová zapisovatelná vrstva (docker rm <container> když byla data zapsána mimo svazek) /var/lib/docker/overlay2/<layer-id>/diff/ Odpojil horní část kontejneru diff/ adresář uvnitř overlay2 ovladač úložiště. Okamžitě zastavte Docker a obnovte nepropojený strom adresářů z ext4 deník popř XFS bloky.
Docker Desktop na macOS nebo Windows (docker system prune --volumes) Uvnitř obrazu disku jednoho virtuálního stroje: -/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw (macOS) nebo %LocalAppData%\Docker\wsl\disk\docker_data.vhdx (Windows WSL2). Odesláno unlink() uvnitř virtuálního počítače Linux a pokud discard/TRIM je aktivní Docker.raw / docker_data.vhdx, udělal řídké otvory v hostitelském souboru. Do 5 sekund ukončete Docker Desktop, zkopírujte Docker.raw nebo docker_data.vhdx na externí disk a spusťte ext4magic / PhotoRec proti obrazu virtuálního disku.
Kubernetes PVC s Delete ReclaimPolicy na Ceph RBD (Rook-Ceph) nebo Longhorn Ceph OSD pool (rbd) nebo /var/lib/longhorn/replicas/. Pokud csi-rbdplugin má trash povoleno (rbd trash), snímek RBD se přesune do koše Ceph; jinak jsou bloky nemapované. Spustit rbd trash ls --pool <pool> uvnitř rook-ceph-tools pod a obnovit pomocí rbd trash restore.

Fáze 2: Záchrana otevřených databázových souborů ze stále běžícího kontejneru (/proc/<pid>/fd/)

Počkejte: je kontejner stále spuštěn? Technik často spouští skript migrace aplikace, úlohu cron čištění nebo příručku rm -rf /var/lib/postgresql/data/* nebo rm /app/data/production.sqlite3 uvnitř běžícího kontejneru nebo odstraní podkladovou složku hostitelského připojení /opt/app/data zatímco samotný kontejner (postgres, mysqld, mariadbd, redis-server, mongod, gunicorn, node) je stále v provozu.

V Linuxu se soubor nesmaže z disku, když rm nebo unlink() se nazývá. Jeho diskové bloky a inode zůstávají 100 procent přidělené a čitelné až do posledního procesu s otevřeným deskriptorem souboru (FD) do tohoto inodu jej zavře nebo opustí.

Krok 1: Najděte ID hostitelského procesu (PID) kontejnerového procesu

Na hostitelském uzlu Linuxu (nikoli uvnitř kontejneru) vyhledejte hostitele PID vašeho procesu databáze nebo aplikace:

sudo lsof +L1 | grep -E "postgres|mysqld|mariadbd|sqlite|redis|mongo|node|python|java"
Podívejte se na výstup:
COMMAND     PID   USER   FD   TYPE DEVICE  SIZE/OFF NLINK    NODE NAME
mysqld    18492    999   14u   REG  259,1 482344960     0 1849201 /var/lib/mysql/app_prod/users.ibd (deleted)
mysqld    18492    999   15u   REG  259,1 125829120     0 1849202 /var/lib/mysql/app_prod/orders.ibd (deleted)
mysqld    18492    999   16u   REG  259,1  79691776     0 1849190 /var/lib/mysql/ibdata1 (deleted)
python3   22104   1000    4u   REG  259,1  89128960     0 3102944 /data/production.sqlite3 (deleted)
Podívejte se na sloupec NLINK: říká se 0 a název souboru končí (deleted). Soubor je úplně pryč ls /var/lib/docker/volumes/..., ale každý bajt (482 MB v users.ibd, 89 MB v production.sqlite3) je uvnitř stále naživu /proc/<PID>/fd/<FD>.

Krok 2: Zkopírujte nepropojené databázové soubory přímo z /proc/<PID>/fd/

ne nezastavujte ani nerestartujte kontejner. Zatímco proces stále běží, zkopírujte nezpracované deskriptory souborů přímo do bezpečné složky na vašem hostiteli:

sudo mkdir -p /root/proc_emergency_rescue

# Example 1: Rescuing an unlinked SQLite3 database (PID 22104, FD 4)
sudo cp /proc/22104/fd/4 /root/proc_emergency_rescue/production.sqlite3
# Check if PID 22104 also holds the -wal file open (e.g. FD 5) and copy it too:
sudo cp /proc/22104/fd/5 /root/proc_emergency_rescue/production.sqlite3-wal

# Example 2: Automatically rescuing ALL open (deleted) MySQL/Postgres files for PID 18492
for fd in /proc/18492/fd/*; do
    target=$(sudo readlink "$fd" 2>/dev/null)
    if echo "$target" | grep -q "(deleted)"; then
        fd_num=$(basename "$fd")
        clean_name=$(echo "$target" | sed 's/ (deleted)//; s/\//_/g')
        echo "Rescuing FD $fd_num -> $clean_name"
        sudo cp "$fd" "/root/proc_emergency_rescue/${fd_num}${clean_name}"
    fi
done

Krok 3: Ještě lepší: Spusťte živý logický výpis (pg_dump / mysqldump / .backup) předtím, než kontejner uzavře FD

Pokud postgres nebo mysqld stále běží s datovými soubory otevřenými v paměti a /proc/<PID>/fd/, zkuste nejprve spustit živý logický výpis přes existující unixový soket nebo připojení TCP:

# If the database engine can still read its open file descriptors:
docker exec <container_name> pg_dumpall -U postgres > /root/proc_emergency_rescue/live_dump.sql
# Or for MySQL:
docker exec <container_name> mysqldump -u root -p --all-databases --single-transaction > /root/proc_emergency_rescue/live_mysql.sql
(Poznámka: PostgreSQL se otevírá a zavírá .1, .2 dynamicky segmentovat soubory napříč pracovními procesy, tzn pg_dump může selhat u tabulek bez mezipaměti; kombinace živého SQL dotazu s kopírováním každého otevření /proc/<pid>/fd/* přes vše postgres podřízené backendové PID ukládají maximální možná data haldy tabulky.)


Fáze 3: Obnovení smazaného svazku Docker zapnuto ext4 nebo XFS po zastavení kontejneru

Co kdybys utekl docker compose down -v nebo docker system prune --volumes, takže kontejner je již zastaven a vše /proc/<pid>/fd/ jsou deskriptory uzavřeny? Nyní jste v závodě se zápisy na disk na pozadí na hostiteli Linux.

Krok 1: Zmrazte hostitelský souborový systém Linux do 10 sekund

  1. Okamžitě zastavte Docker, kontejner, kubelet a cron, takže žádný kontejner, kontrola stavu ani rotátor protokolu nezapíše další bajt do /var/lib/docker:
    sudo systemctl stop docker.socket docker.service containerd.service cron.service
    
  2. Zkontrolujte, které blokové zařízení a systém souborů obsahuje /var/lib/docker:
    df -Th /var/lib/docker
    
    Filesystem     Type  Size  Used Avail Use% Mounted on
    /dev/nvme0n1p1 ext4  100G   42G   58G  42% /
    
  3. Znovu připojte oddíl jen pro čtení (nebo streamujte nezpracovaný obraz oddílu přes SSH do jiného počítače):
  4. Pokud /var/lib/docker je na vlastním vyhrazeném oddílu nebo svazku LVM (např /dev/nvme0n1p2 nebo /dev/mapper/vg0-docker), okamžitě jej znovu připojte pouze pro čtení:
    sudo mount -o remount,ro /var/lib/docker
    
  5. Pokud /var/lib/docker je na kořeni / oddíl (/), zkuste vynutit kořenový oddíl pouze pro čtení pomocí spouštěče kernel Magic SysRq (echo u | sudo tee /proc/sysrq-trigger) nebo sudo mount -o remount,ro /.
  6. Pokud používáte cloudové VPS (AWS EC2, GCP, DigitalOcean, Hetzner, Linode): Okamžitě přejděte do své cloudové webové konzole a klikněte na Vytvořit snímek na svazku bloků serveru (nebo streamujte nezpracované blokové zařízení přes SSH na druhý server: sudo dd if=/dev/nvme0n1p1 bs=4M status=progress | gzip -1 | ssh user@backup-server "cat > /mnt/storage/docker_host_raw.img.gz").

Krok 2: Zkontrolujte, zda jsou vaše data stále uložena v JINÉM neoříznutém svazku nebo overlay2 vrstva

Před vyřezáváním nepřidělených diskových bloků ověřte, že vaše databáze nebyla ve skutečnosti uložena v připojeném připojení nebo jinak pojmenovaném svazku, který přežil:

# Search the entire /var/lib/docker tree read-only for any surviving database files:
sudo find /var/lib/docker -name "PG_VERSION" -o -name "ibdata1" -o -name "*.sqlite*" -o -name "*.db" -o -name "dump.rdb" -o -name "WiredTiger" 2>/dev/null
Každý týden administrátoři po spuštění panikaří docker volume rm app_db_data, jen objevit s find /var/lib/docker že docker-compose.yml skutečně vytvořil projectname_app_db_data (který je na disku stále 100 procent neporušený). app_db_data byl starý nepoužitý svazek před šesti měsíci.

Krok 3: Obnovení nepropojených adresářů svazků Dockeru zapnuto ext4 pomocí ext4 Deník (ext4magic a debugfs)

Když docker volume rm smaže /var/lib/docker/volumes/<vol_name>/_data na an ext4 souborový systém, ext4 vynuluje přímé ukazatele bloku (i_block / kořen stromu rozsahu) v tabulce živých inodů. Nicméně, ext4 deník (inode <8>, obvykle 128 MB do 1024 MB kruhová kruhová vyrovnávací paměť) stále obsahuje historické kopie přesných tabulek inodů a adresářových bloků z předchozího docker compose down -v byl popraven.

+-------------------------------------------------------------------------+
| HOW ext4magic RECOVERS A DELETED DOCKER VOLUME FROM THE EXT4 JOURNAL    |
|                                                                         |
| Live Inode Table on Disk (After docker volume rm):                      |
|   Inode #918402 (users.ibd): [Size = 0, Extent Pointers = ZEROED]       |
|                                                                         |
| Ext4 Journal Ring Buffer (Inode <8> on Disk):                           |
|   Transaction #41902 (10 mins ago):                                     |
|   Inode #918402 (users.ibd): [Size = 482MB, Extents = Blocks 9000..9999]|
|                                                                         |
| -> ext4magic reads the old Inode Copy from Journal Transaction #41902   |
|    and extracts Blocks 9000..9999 directly to your rescue drive.        |
+-------------------------------------------------------------------------+

Spustit ext4magic proti vašemu oddílu pouze pro čtení (nebo .img kopie snímku na druhém serveru) s uvedením časového razítka (-a) od 5 minut předtím, než jste běželi docker compose down -v nebo docker system prune --volumes:

# Install ext4magic on your rescue machine (never on the affected partition)
sudo apt-get install -y ext4magic e2fsprogs

# Dump the ext4 journal from the frozen partition / image to a file in RAM (/dev/shm)
sudo debugfs -R "dump <8> /dev/shm/ext4_journal.copy" /dev/nvme0n1p1

# Recover all files deleted under var/lib/docker/volumes after (Current Time - 15 minutes)
sudo mkdir -p /mnt/external_rescue/docker_recovered
sudo ext4magic /dev/nvme0n1p1 \
  -j /dev/shm/ext4_journal.copy \
  -f var/lib/docker/volumes \
  -a $(date -d "-15 minutes" +%s) \
  -r -d /mnt/external_rescue/docker_recovered
- -j /dev/shm/ext4_journal.copy: Ihned po zastavení Dockeru přečte snímek deníku, který jste uložili do paměti RAM. - -f var/lib/docker/volumes: Cílí na přesný strom adresářů svazků Docker (poznámka: vynechejte úvodní / v ext4magic relativní cesty). - -a $(date -d "-15 minutes" +%s): Vypráví ext4magic rekonstruovat strom adresářů pomocí kopií inodů platných před 15 minutami (těsně před náhodným smazáním). - -r: Obnoví kompletní adresáře, kde nebyly přepsány žádné bloky; -li -r chybí částečně přepsané soubory, spusťte výměnu druhého průchodu -r s -m (magická řezba + žurnálový hybridní režim).

Krok 4: Vyřezávání nezpracovaných souborů SQLite, PostgreSQL nebo MySQL InnoDB po zabalení deníku (XFS nebo ext4)

Warning

Proč XFS nepodporuje ext4magic a vyžaduje okamžité odpojení pouze pro čtení: Na rozdíl od ext4, která do svého deníku zapisuje plné 256bajtové kopie inodů, XFS protokoluje delty záměru metadat a agresivně znovu používá uvolněné inodové B-stromy (agi). Li /var/lib/docker sedí na an XFS oddíl (výchozí na RHEL, Rocky Linux, AlmaLinux a Amazon Linux), odpojení /var/lib/docker nebo přemontování / čtení pouze během několika sekund je nejdůležitějším krokem před vyřezáváním.

Pokud hostitel používá XFS nebo pokud ext4 žurnál již zabalený přes ukazatele inodů, použijte podpis a vyřezávání struktury proti surovému obrazu disku (docker_host_raw.img):

  1. Pro databáze SQLite3 (.sqlite, .db - např. Vaultwarden, Nextcloud, Home Assistant, Gitea, Grafana): Každá databáze SQLite3 začíná nezaměnitelnou 16bajtovou hlavičkou ASCII na byte 0 své první 4 kilobajtové stránky: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 ("SQLite format 3\0") a ukládá přesnou velikost stránky databáze (Bytes 16..17, obvykle 4096) a celkovou velikost databáze ve stránkách (Bytes 28..31, big-endian 32bitové celé číslo) přímo uvnitř stejného záhlaví.
  2. Spustit PhotoRec s [File Opt] -> [x] sqlite povoleno, nebo prohledejte oddíl přímo pomocí grep -ab "SQLite format 3" najít přesný bajtový offset smazaného souboru SQLite a extrahovat jej pomocí dd:
    # Find the exact byte offsets of every "SQLite format 3" header on the partition:
    sudo grep -ab "SQLite format 3" /dev/nvme0n1p1
    
    Po vytažení spusťte sqlite3 carved.db ".recover" | sqlite3 repaired.db rekonstruovat každou neporušenou listovou stránku B-stromu.

Tip

Jak přesně vypočítat dd velikost bajtu nepropojeného souboru SQLite3 z jeho hlavičky: Jednou grep -ab "SQLite format 3" vám dává počáteční bajtový offset OFFSET smazané databáze SQLite, přečtěte si bajty 16..17 (velikost stránky uint16 big-endian, např. 0x1000 = 4096 bajtů) a bajtů 28..31 (uint32 big-endian Page Count, např. 25000 stránky) pomocí hexdump -C -s OFFSET -n 32. Násobení Page Size x Page Count vám dává přesnou délku bajtu, do které se má předat dd (iflag=skip_bytes,count_bytes), když je soubor na disku souvislý.

  1. Pro MySQL / MariaDB InnoDB (.ibd soubory tabulky): Každý InnoDB .ibd tabulka se skládá ze sekvenční 16 KB (16,384 byte) stránky obsahující FIL_PAGE_INDEX (0x45BF) hlavička a jedinečná tabulka space_id. Použijte Percona / TwinDB undrop-for-innodb (stream_parser + c_parser) sada nástrojů ke skenování /dev/nvme0n1p1 pro všechny 16 KB Indexové stránky InnoDB a výpis každého řádku přímo do souborů TSV/SQL pro opětovné importování.
  2. Pro soubory haldy PostgreSQL ($PGDATA/base/<db_oid>/<relfilenode>): PostgreSQL ukládá každou tabulku jako souvislou 8 KB (8,192 byte) haldy stránek obsahujících PageHeaderData (pd_lower, pd_upper, pd_special). Použijte pg_filedump nebo pglazarus / pdu pro vyhledání nepřidělených oblastí disku 8 KB stránky odpovídající rozvržení n-tice sloupců vaší tabulky (HeapTupleHeaderData) a rekonstruujte řádky.

Fáze 4: Kubernetes PVC, PV a etcd Snímek nouzového zotavení

V Kubernetes (EKS, GKE, AKS, k3s, RKE2, kubeadm, OpenShift), omylem smažete PersistentVolumeClaim (kubectl delete pvc), StatefulSet nebo celý jmenný prostor (kubectl delete ns prod) má velmi odlišnou architekturu než samostatný Docker.

Scénář A: Ukazuje se PVC Terminating (The Finalizer Lifesaver)

Běh:

kubectl get pvc -n <namespace>
Pokud STATUS sloupec říká Terminating, vydechněte: vaše údaje ještě NEBYLY smazány. - Proč? Každé Kubernetes PVC vytvořené Od Kubernetes 1.9 automaticky zahrnuje finalizers: [kubernetes.io/pvc-protection]. - Dokud modul stále montuje toto PVC, ovladač Kubernetes odmítá dokončit odstranění PVC a nikdy nevolá ovladač CSI DeleteVolume RPC. - Okamžitá akce: NEodstraňujte ani restartujte modul a NEneopravujte finalizátor. Okamžitě zkopírujte všechna data z běžícího modulu do místního počítače nebo do bucketu S3:
# Stream a compressed tar backup or pg_dump out of the still-running pod immediately:
kubectl exec -n <namespace> <pod-name> -- pg_dumpall -U postgres > ./rescued_k8s_db.sql
# Or tar an entire mounted volume directory out over stdout:
kubectl exec -n <namespace> <pod-name> -- tar czf - /var/lib/postgresql/data > ./rescued_pvc_files.tar.gz

Scénář B: PVC bylo odstraněno a kubectl get pv zobrazuje PersistentVolume v Released stát (ReclaimPolicy: Retain)

Běh:

kubectl get pv
Pokud váš PersistentVolume (pv-prod-postgres) je stále uveden s STATUS: Released (protože jeho StorageClass používá reclaimPolicy: Retain), 100 procent vašich dat stále leží nedotčených na základním disku. Kubernetes však odmítá, aby se nové PVC vázalo na a Released PV, protože PV stále obsahuje a spec.claimRef ukazující na staré odstraněné PVC UID.

Jak udělat a Released PV Available znovu za 10 sekund s nulovou ztrátou dat: 1. Upravte objekt PersistentVolume a odstraňte jej spec.claimRef blok:

kubectl patch pv <your-pv-name> --type json -p '[{"op": "remove", "path": "/spec/claimRef"}]'
2. Spustit kubectl get pv znovu: stav se okamžitě změní z Released až Available. 3. Znovu vytvořte svůj PersistentVolumeClaim (upřesnění volumeName: <your-pv-name> a odpovídající kapacita/název třídy úložiště). Okamžitě se naváže na stávající PV se všemi soubory nedotčenými.

Scénář C: Obnovení vymazaného stavu clusteru Kubernetes z etcd snímek (etcdctl snapshot restore)

Co kdyby někdo utekl kubectl delete namespace prod nebo helm uninstall a vymazali 200 Kubernetes manifestů, tajemství, ConfigMaps a definic PV na samoobslužném kubeadm, k3snebo RKE2 řídící letadlo?

  1. Najděte své nejnovější etcd snímek (ve výchozím nastavení v /var/lib/rancher/k3s/server/db/snapshots/, /var/lib/rancher/rke2/server/db/snapshots/nebo podle vašeho plánu /var/backups/etcd/snapshot.db).
  2. Před dotykem živého clusteru ověřte integritu snímku:
    ETCDCTL_API=3 etcdctl snapshot status /path/to/snapshot.db --write-out=table
    
  3. Zastávka kube-apiserver a etcd na uzlu (uzlech) řídicí roviny:
  4. Zapnuto kubeadm (statické moduly): Pohyb /etc/kubernetes/manifests/kube-apiserver.yaml a /etc/kubernetes/manifests/etcd.yaml dočasně na /root/manifests_hold/ tak kubelet zastaví oba kontejnery čistě a poté zpět /var/lib/etcd do /var/lib/etcd.bak.
  5. Zapnuto k3s: Spustit sudo systemctl stop k3s a sudo k3s server --cluster-reset --cluster-reset-restore-path=/path/to/snapshot.
  6. Obnovit etcd datový adresář zapnut kubeadm:
    sudo ETCDCTL_API=3 etcdctl snapshot restore /path/to/snapshot.db \
      --data-dir=/var/lib/etcd \
      --name=<control-plane-node-name> \
      --initial-cluster=<node-name>=https://<node-ip>:2380 \
      --initial-advertise-peer-urls=https://<node-ip>:2380
    
  7. Pohybujte se etcd.yaml a kube-apiserver.yaml zpět do /etc/kubernetes/manifests/. Během 30 sekund, kube-apiserver se znovu připojí k obnovenému etcd store a každý odstraněný objekt Namespace, Secret, ConfigMap a PersistentVolume se znovu objeví.

Fáze 5: Posilování svazků Docker a Kubernetes proti náhodnému smazání

Jakmile bude vaše produkční databáze obnovena, implementujte tyto čtyři architektonické mantinely, aby jediný překlep CLI již nikdy nemohl smazat živý svazek:

  • Změňte každý produkční Kubernetes StorageClass od reclaimPolicy: Delete do reclaimPolicy: Retain: Ve výchozím nastavení vestavěné cloudové StorageClasses (gp2, gp3, standard-rwo) výchozí reclaimPolicy: Delete, což znamená, že odstranění PVC zničí cloudový disk. Vytvořte a StorageClass s reclaimPolicy: Retain (nebo opravte stávající PV pomocí kubectl patch pv <pv-name> -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'), takže odstranění PVC nebo jmenného prostoru nikdy neodstraní podkladový blok bloku.
  • Povolení koše AWS EBS / Plány snímků GCP / Velero se snímky CSI: Povolení koše AWS EBS uchová veškerý smazaný svazek EBS po dobu 7 až 30 dnů, i když zavolá ovladač CSI DeleteVolume.
  • Nikdy nepoužívejte docker system prune --volumes v automatických čistících skriptech nebo běžcích CI/CD: Pokud se kontejner produkční databáze krátce zhroutí (Exited (1)) přesně v okamžiku spuštění úlohy cron docker system prune -a --volumes -f, Docker považuje své anonymní svazky za „nepoužité“ a trvale je smaže. Proužek --volumes ze všech čistících skriptů.
  • Použijte explicitní připojení hostitelské vazby (/srv/prod_data/postgres:/var/lib/postgresql/data) nebo externí spravované databáze pro stavové produkční úlohy: Na rozdíl od /var/lib/docker/volumes/, hostitelské adresáře pro připojení vazby mimo /var/lib/docker/ se nikdy nedotknou docker compose down -v, docker volume rmnebo docker system prune --volumes.

Regionální čísla tísňového volání a protokoly agentur

Když smazání kontejneru nebo úložiště Kubernetes ovlivní klinický provoz nemocnice, odeslání veřejné bezpečnosti nebo regulovaná osobní data, okamžitě eskalujte:

  • Spojené státy a Kanada: Vytočit 911 pokud selhání clusteru kontejnerů zakáže klinické monitorování pacienta, systémy EHR nebo nouzové odeslání. Nahlaste vymazání škodlivé kontejnerové infrastruktury nebo kybernetické incidenty CISA (1-844-Say-CISA / cisa.gov/report) nebo Kanadské centrum pro kybernetickou bezpečnost (1-833-CYBER-88).
  • Spojené království: Vytočit 999 pro ohrožení života nebo kritickou infrastrukturu NHS. Podle britského GDPR vyžaduje trvalé zničení nebo ztráta dostupnosti osobních údajů bez obnovitelné zálohy vyhodnocení 72hodinového oznámení o porušení ICO (0303 123 1113).
  • Evropská unie: Vytočit 112 ve všech členských státech EU. Subjekty podle směrnice NIS2 musí předložit včasné varování svému národnímu CSIRT do 24 hodin po vážném výpadku služby a trvalá ztráta osobních údajů spustí článek 33 GDPR hlášení do 72 hodin.
  • Austrálie a Nový Zéland: Vytočit 000 v Austrálii nebo 111 na Novém Zélandu; hlásit incidenty kritické infrastruktury ACSC (1300 CYBER1).
  • Indie a Asie a Tichomoří: Vytočit 112 v Indii pro reakci na mimořádné události; hlásit bezpečnostní incidenty cloudu nebo kontejnerů na CERT-In (incident@cert-in.org.in) v rámci povinného 6hodinového okna.

Často kladené otázky

ano docker compose down -v odstranit připojení hostitelské vazby (./data:/var/lib/mysql) nebo pouze svazky Named and Anonymous Docker?

`docker compose down -v` POUZE odstraní pojmenované svazky deklarované v `volumes:` sekce `docker-compose.yml` a anonymní svazky připojené ke kontejnerům; to nikdy odstraní soubory uvnitř připojení hostitelské vazby (jako např `- /opt/mysql_data:/var/lib/mysql` nebo `- ./postgres_data:/var/lib/postgresql/data`). Pokud váš soubor pro psaní používal cestu hostitele začínající na `/` nebo `./`, zkontrolujte tuto složku na hostiteli právě teď: vaše soubory jsou stále 100 procent neporušené.

Proč ano? docker system prune --volumes odstranit svazek databáze, když jsem zastavil kontejner pouze na 2 minuty, abych aktualizoval proměnnou prostředí?

Opatrně počkejte na rozdíl mezi `docker stop` a `docker rm`: pokud je kontejner pouze `Stopped / Exited` (viditelné v `docker ps -a`), `docker system prune --volumes` dělá ne odstranit jeho svazky, protože zastavený kontejner na ně stále odkazuje. Pokud jste však běželi `docker rm ` (pro opětovné vytvoření kontejneru s novými příznaky) nebo pokud jste prošli `docker system prune -a --volumes` (který nejprve odstraní všechny zastavené kontejnery a pak smaže všechny svazky, které již nejsou připojeny k žádné nádobě), objem „visel“ v milisekundě, kdy byl zastavený zásobník odstraněn a byl ihned poté vymazán.

Mohu obnovit smazaný svazek Docker v Docker Desktop na Macu (Apple Silicon / Intel) nebo Windows (WSL2)?

Ano, pokud okamžitě ukončíte Docker Desktop, virtuální počítač se zastaví `fstrim` proti virtuálnímu disku. V macOS Docker ukládá všechny svazky Linuxu dovnitř `-/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw`; na Windows WSL2, uvnitř `%LocalAppData%\Docker\wsl\disk\docker_data.vhdx`. Zkopírujte to `.raw` nebo `.vhdx` soubor okamžitě na externí SSD, připojte jej pouze pro čtení v Linuxu (pomocí `losetup -Pr` pro `.raw` nebo `qemu-nbd -r` pro `.vhdx`), a běžte `ext4magic` nebo `PhotoRec` proti virtuálnímu `ext4` oddíl uvnitř.

Co když jsem smazal Kubernetes StatefulSet s kubectl delete statefulset postgres? Smazalo to i moje PVC?

ne. Ve výchozím nastavení v Kubernetes (pokud `persistentVolumeClaimRetentionPolicy.whenDeleted: Delete` byl explicitně nakonfigurován na Kubernetes 1.27+), běží `kubectl delete statefulset` smaže ovladač StatefulSet a jeho moduly, opouštět všechny `PersistentVolumeClaims` (`data-postgres-0`, `data-postgres-1`) a jejich podkladová data jsou 100 procent neporušená. Jednoduše znovu použijte svůj `StatefulSet` YAML manifest se stejným názvem a `volumeClaimTemplates`a nové pody se automaticky znovu připojí ke stávajícím `data-postgres-0` PVC.

Jak získám přístup k souborům v Dockeru overlay2 adresář, když se kontejner odmítne spustit (CrashLoopBackOff / Exited (1))?

Neodstraňujte havarovaný kontejner. Dokud zastavený kontejner stále existuje `docker ps -a`, jeho zapisovatelná vrstva a připojení svazku jsou na disku zcela nedotčené. Soubory můžete buď zkopírovat přímo ze zastaveného kontejneru pomocí `docker cp :/var/lib/postgresql/data /root/rescued_data`nebo najděte jeho přesného hostitele `overlay2` cesta běháním `docker inspect --format '{{.GraphDriver.Data.UpperDir}}'` a čtení tohoto adresáře přímo jako `root`.

Co když někdo smazal Kubernetes Namespace (kubectl delete ns prod) a všechny PVC měly reclaimPolicy: Delete na AWS EBS nebo GCP?

Pokud cloudový ovladač CSI (`ebs.csi.aws.com` nebo `pd.csi.storage.gke.io`) již provedeno `DeleteVolume` protože `reclaimPolicy` byl `Delete`, okamžitě zkontrolujte tři bezpečnostní sítě na úrovni cloudu: (1) zkontrolujte **Koš AWS pro svazky EBS** v konzole AWS EC2 (pokud bylo u účtu/značek aktivní pravidlo uchování, smazaný svazek EBS se nachází v koši a lze jej obnovit jedním kliknutím); (2) zkontrolujte **Zálohování AWS / DLM / Plány snímků GCP** pro nejnovější automatický snímek svazku; a (3) zkontrolujte, zda vaše databáze streamovala WAL/binlogy (`WAL-G`, `pgBackRest`, `Litestream`) do kbelíku S3/GCS.


Související průvodci


Zdroje a oficiální pokyny

  • Oficiální dokumentace Kubernetes (kubernetes.io / Cloud Native Computing Foundation): Ochrana při používání objektu úložiště (kubernetes.io/pvc-protection Finalizátory), Reclaiming PersistentVolumes (Retain vs. Delete) a Provozní etcd Clustery pro Kubernetes (etcdctl snapshot restore).
  • Docker Inc. (docs.docker.com): Správa dat v Dockeru: svazky, připojení připojení, overlay2 Architektura ovladače úložiště a referenční příručka Prune.
  • Organizace Linuxového jádra (kernel.org): The /proc Souborový systém (procfs Otevřete File Descriptor Recovery přes /proc/<pid>/fd/) a Ext4 Journal Specification.
  • ext4magic Projektová dokumentace (ext4magic.sourceforge.net): Forenzní obnovení inodu a žurnálových transakcí na souborových systémech Ext3/Ext4.
  • Národní institut pro standardy a technologie (NIST) (Spojené státy americké): Speciální publikace 800-190: Application Container Security Guide & Incident Recovery.