Skip to content

Dzēsts Docker vai Kubernetes ražošanas apjoms: glābšana docker system prune --volumes, overlay2 Inodes, un etcd Momentuzņēmumi

Ārkārtas palīdzības numuri dažādās valstīs atšķiras. Šajā lapā tiek izmantots numurs 911, kas ir ASV un Kanādas numurs. Daudzās citās valstīs tiek izmantots 112, 999 vai cits numurs. Atrodiet savas valsts numuru.

Skriešana docker compose down -v, docker system prune -a --volumes, docker volume rm, vai kubectl delete pvc nepareizā termināļa cilnē ražošanā ir viens no ātrākajiem veidiem, kā dzēst reāllaika PostgreSQL, MySQL, MariaDB, Redis, MongoDB vai SQLite datu bāzes sējumu. Atšķirībā no mākoņa virtuālās mašīnas momentuzņēmumiem, kas tiek pārvietoti uz 7 dienu atkritni, Docker vietējā apjoma draiveris (/var/lib/docker/volumes/<name>/_data) un Kubernetes local-path / hostPath nodrošinātāji nekavējoties izdod standarta POSIX unlink() un rmdir() zvani tieši pret pamatā esošo Linux resursdatora failu sistēmu (ext4, XFS, vai Btrfs). Katrs ieraksts, kas notiek šajā Linux resursdatorā pēc komandas pabeigšanas, var pārrakstīt atbrīvotos datu bāzes blokus diskā. Ja jūsu servera disks ir piepildīts līdz 100 procentiem (0 bytes free) pirms kāds skrēja docker system prune --volumes panikā konsultējies servera disks ir 100% pilns, datu bāzes WAL žurnāla uzpūšanās un nulles vietas atkopšana; par bezmetāla Linux failu dzēšanu ārpus konteineriem skatiet nejauša rm -rf vai Shift-Delete operētājsistēmā ext4, XFS, APFS un NTFS: tikai lasāma atkārtota pievienošana un inode griešana un virtuālās mašīnas VMDK, VHDX un qcow2 momentuzņēmumu ķēdes korupcija un hipervizora glābšana. Ja šis ražošanas pārtraukums ietekmē slimnīcas pacientu aprūpi, neatliekamās palīdzības nosūtīšanu vai sabiedrisko pakalpojumu drošības sistēmas, zvaniet uz vietējo neatliekamās palīdzības numuru (911 ASV un Kanādā, 112 visā Eiropas Savienībā, 999 Apvienotajā Karalistē) vai pārbaudiet mūsu direktoriju neatliekamās palīdzības numuri.

Dariet to tagad

  1. ** NESKRIET docker compose up -d, systemctl restart dockervai atkārtoti izvietojiet Kubernetes pod**: atkārtoti izveidojot konteineru vai restartējot Docker dēmonu, tiek ierakstīti megabaiti jauna overlay2 metadati, konteinera JSON žurnāli un svaigi inicializēti tukši datu bāzes faili (initdb) tieši virs precīzā ext4 vai XFS bloki, kur pirms dažām sekundēm atradās jūsu dzēstais sējums.
  2. Pārbaudiet 5 sekunžu laikā, ja konteinera process (postgres, mysqld, redis-server, node, python) joprojām darbojas atmiņā (ps aux un sudo lsof +L1): ja kāds izdzēsa failus pievienotā sējumā vai atsaistīja anonīmu sējumu, kamēr konteiners joprojām darbojas, Linux kodols saglabā 100 procentus no nesaistītajiem datu bāzes failiem diskā, kamēr konteinera resursdatora procesa ID (PID) satur atvērtu faila deskriptoru (FD). Varat kopēt šos failus tieši no /proc/<PID>/fd/ vai /proc/<PID>/root/ ar nulles datu zudumu pirms konteinera apstāšanās.
  3. Ja konteiners jau ir apturēts un sējums ir izdzēsts (docker compose down -v vai docker system prune --volumes), nekavējoties iesaldē resursdatora diska ierakstus: Apturiet Docker dēmonu (sudo systemctl stop docker.socket docker.service containerd), tāpēc fona konteineros un veselības pārbaudēs vairs netiek ierakstīti žurnāli /var/lib/docker, tad vai nu pārmontējiet /var/lib/docker (vai sakne / nodalījums) tikai lasāms (sudo mount -o remount,ro /) vai nekavējoties uzņemiet bloka līmeņa mākoņa apjoma momentuzņēmumu (AWS EBS Snapshot, GCP Persistent Disk Snapshot, DigitalOcean Volume Snapshot) pirms kaut kam pieskarties.
  4. Ja izmantojat Kubernetes (kubectl delete pvc vai kubectl delete namespace), pārbaudiet PersistentVolume (PV) ReclaimPolicy (kubectl get pv) nekavējoties:
  5. Ja PV bija persistentVolumeReclaimPolicy: Retain, jūsu dati nav dzēsti: PV vienkārši pārcēlās uz Released statuss un jūsu mākoņa disks (EBS, Azure Disk, Ceph RBD, NFS) ir 100% neskarts.
  6. Pat ja kubectl delete pvc ir iestrēdzis Terminating, Kubernetes Finalizatori (kubernetes.io/pvc-protection) neļauj CSI draiverim dzēst pamatā esošo krātuvi, ja vien jebkurā podā joprojām ir atsauce uz šo PVC. Neizdzēsiet Pod, kamēr neesat nokopējis datus no darbojas Pod.
  7. Attēlot pamatā esošā bloka nodalījumu (dd / ddrescue izmantojot SSH) ārējam diskam vai atsevišķam mākoņa apjomam pirms palaišanas ext4magic, extundelete, vai PhotoRec: nekad nepalaidiet failu izgriezējus, kas ieraksta izvades failus tajā pašā diska nodalījumā, no kura tiek veikta atkopšana /var/lib/docker/volumes.
  8. ** Bojātam vai nejauši izdzēstam Kubernetes klastera stāvoklim (kubectl delete crd / namespace), apstājieties kube-apiserver un atjaunojiet jaunāko etcd momentuzņēmums (etcdctl snapshot restore)**: ja klastera stāvoklis ir etcd tika dzēsta, kamēr joprojām pastāv pamatā esošie mākoņa krātuves apjomi, un tas tiek atjaunots etcd atgūst visu PV, PVC, Secret, un ConfigMap objektus vienlaicīgi.

Danger

** Nekad nenoņemiet kubernetes.io/pvc-protection vai kubernetes.io/pv-protection finālists ar kubectl patch ... -p '{"metadata":{"finalizers":null}}' kad PVC ir iestrēdzis Terminating**: šis pabeigtājs ir vienīgais, kas saglabā jūsu mākoņa CSI draiveri (aws-ebs-csi-driver, pd.csi.storage.gke.io, Longhorn, Rook-Ceph) no aparatūras izdošanas DeleteVolume API izsaukums, lai iznīcinātu jūsu ražošanas disku. Kamēr PVC ir iestrēdzis Terminating, Pod joprojām darbojas un skaļums joprojām ir uzstādīts: palaist kubectl exec vai kubectl cp (vai pg_dump / mysqldump) nekavējoties, lai glābtu 100 procentus no jūsu datu bāzes, pirms Pod tiek pārtraukts.


Lēmumu koks: dzēsts Docker sējums, overlay2 slānis vai Kubernetes PVC šķirošana

Izmantojiet šo blokshēmu, lai izvēlētos ātrāko atkopšanas ceļu bez zaudējumiem, pamatojoties uz to, vai konteinera process joprojām darbojas, vai sējums tika nodrošināts ar lokālo disku vai mākoņa CSI krātuvi un kura failu sistēma tiek mitināta. /var/lib/docker:

flowchart TD
    Start["Pēc Docker vai Kubernetes dzēšanas komandas trūkst ražošanas datu"] --> WhichEnv{"Kura platforma un komanda izraisīja zaudējumus?"}

    WhichEnv -->|"Docker: konteiners joprojām darbojas (sējuma/konteinera iekšpusē atsaistītie faili)"| ProcRescue["Atveriet nesaistīto failu deskriptorus, izmantojot sudo lsof +L1 un /proc/PID/fd/N vai /proc/PID/root/"]

    WhichEnv -->|"Docker: konteiners apturēts un apjoms dzēsts (rakstīt uz leju -v / apgriezt --volumes)"| StopDocker["Nekavējoties palaist: sudo systemctl stop docker.socket docker containerd"]

    WhichEnv -->|"Kubernetes: kubectl delete pvc / pv / statefulset / namespace"| K8sCheck{"Vai pods joprojām darbojas, VAI PVC ir iestrēdzis, pārtraucot darbību?"}

    K8sCheck -->|"Jā: Pod joprojām darbojas (finalizatora bloķēšanas CSI dzēšana)"| K8sExec["NEDRĪKST DZĒST Pod -> Nekavējoties palaidiet kubectl exec / pg_dump / tar pār stdout lokālajā diskā"]
    K8sCheck -->|"Nē: Pod Gone -> Pārbaudiet kubectl get pv"| ReclaimCheck{"Kas bija PV atgūšanas politika?"}

    ReclaimCheck -->|"Saglabāt (PV statuss = atbrīvots)"| ClearClaimRef["100% datu neskarti -> Rediģēt PV, lai noņemtu spec.claimRef.uid -> Atkārtoti saistīt ar jaunu PVC"]
    ReclaimCheck -->|"Dzēst (Cloud EBS/PD/Longhorn/Local-Path)"| CloudOrLocal{"Mākoņa CSI sējums vai lokālais resursdatora disks?"}

    CloudOrLocal -->|"Mākoņa CSI (AWS EBS/GCP/Azure/Ceph)"| CloudSnap["Pārbaudiet Cloud Console atkritni / automatizētos EBS momentuzņēmumus / Ceph RBD miskasti (rbd trash ls)"]
    CloudOrLocal -->|"Vietējā mezgla disks (lokālais ceļš/hostPath)"| StopDocker

    StopDocker --> RemountRO["Atkārtoti montējiet resursdatora nodalījumu, tikai lasāms (mount -o remount,ro) VAI straumējiet bloka attēlu, izmantojot SSH"]
    RemountRO --> HostFS{"Kādi failu sistēmas resursdatori ir /var/lib/docker?"}
    HostFS -->|"ext4"| Ext4Rec["Izmantojiet debugfs / ext4magic Journal Inode Transaction Rollback (-laika zīmogs)"]
    HostFS -->|"XFS / Btrfs"| CarveRec["Izmantojiet Btrfs Roots / xfs_irecover / Custom Signature Carving for SQLite, Postgres Heap vai InnoDB .ibd"]

1. fāze: kā Docker un Kubernetes faktiski izdzēš sējumus diskā

Pirms jebkuras atkopšanas komandas palaišanas izprotiet, kur jūsu dati fiziski atradās Linux resursdatorā un ko patiesībā aizskāra dzēšanas komanda:

Krātuves veids un komanda Dzēst Resursdatora failu sistēmas ceļš Linux mezglā Ko patiesībā darīja komanda Dzēst Tūlītēja atkopšanas metode
** Nosaukts Docker Volume (docker volume rm vai docker compose down -v)** /var/lib/docker/volumes/<vol_name>/_data Atsaistīti iekšējie faili _data/ un noņēma direktorijas ierakstu no /var/lib/docker/volumes/metadata.db (boltdb). Nekavējoties apturiet Docker, atkārtoti uzstādiet /var/lib/docker tikai lasāms un atkoptu atsaistītās inodes, izmantojot ext4magic / debugfs vai parakstu grebšana.
Anonymous Docker Volume (docker run -v /var/lib/mysql + docker rm -v vai docker system prune --volumes) /var/lib/docker/volumes/<64-char-hex-id>/_data docker system prune --volumes dzēš katru anonīmo un nosaukto sējumu, uz kuru pašlaik nav atsauces vismaz viens esošs konteiners. Nekavējoties pārtrauciet Docker; ja jums bija citi apturēti konteineri, kuru tilpumi nav apgriezti, pārbaudiet atlikušo daudzumu /var/lib/docker/volumes/*/_data mapes vispirms pirms nepiešķirto bloku grebšanas.
Konteinera rakstāmais slānis (docker rm <container> kad dati tika ierakstīti ārpus sējuma) /var/lib/docker/overlay2/<layer-id>/diff/ Konteinera augšdaļa ir atsaistīta diff/ direktorijā iekšpusē overlay2 krātuves draiveris. Nekavējoties apturiet Docker un atkopiet atsaistīto direktoriju koku no ext4 žurnāls vai XFS bloki.
Docker Desktop operētājsistēmā macOS vai Windows (docker system prune --volumes) Viena virtuālās mašīnas diska attēlā: -/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw (macOS) vai %LocalAppData%\Docker\wsl\disk\docker_data.vhdx (Windows WSL2). Nosūtīts unlink() Linux virtuālajā mašīnā un, ja discard/TRIM ir aktīvs Docker.raw / docker_data.vhdx, resursdatora failā izspieda retus caurumus. Aizveriet Docker Desktop 5 sekunžu laikā, kopējiet Docker.raw vai docker_data.vhdx uz ārējo disku un palaist ext4magic / PhotoRec pret virtuālā diska attēlu.
Kubernetes PVC ar Delete Ceph URB atgūšanas politika (Rook-Ceph) vai Longhorn Ceph OSD baseins (rbd) vai /var/lib/longhorn/replicas/. Ja csi-rbdplugin ir trash iespējots (rbd trash), UBR attēls tiek pārvietots uz Ceph miskasti; pretējā gadījumā bloki netiek kartēti. Skrien rbd trash ls --pool <pool> iekšpusē rook-ceph-tools pod un atjaunot ar rbd trash restore.

2. fāze: atvērto datu bāzes failu glābšana no joprojām strādājoša konteinera (/proc/<pid>/fd/)

Pagaidiet: vai konteiners joprojām darbojas? Bieži vien inženieris palaiž lietojumprogrammas migrācijas skriptu, tīrīšanas cron darbu vai rokasgrāmatu rm -rf /var/lib/postgresql/data/* vai rm /app/data/production.sqlite3 darbojas konteinerā vai dzēš pamatā esošo saimniekdatora saistīšanas-mount mapi /opt/app/data kamēr pats konteiners (postgres, mysqld, mariadbd, redis-server, mongod, gunicorn, node) ir joprojām darbojas.

Operētājsistēmā Linux fails netiek izdzēsts no diska, kad rm vai unlink() tiek saukts. Tā diska bloki un inode paliek 100 procenti piešķirti un lasāmi līdz pēdējam procesam, kurā ir atvērta faila deskriptors (FD) uz šo inode to aizver vai iziet.

1. darbība: atrodiet resursdatora procesa ID (PID) konteinera procesam

Linux resursdatora mezglā (nevis konteinera iekšpusē) atrodiet resursdatoru PID jūsu datubāzē vai pieteikšanās procesā:

sudo lsof +L1 | grep -E "postgres|mysqld|mariadbd|sqlite|redis|mongo|node|python|java"
Apskatiet izvadi:
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)
Apskatiet kolonnu NLINK: tur rakstīts 0, un faila nosaukums beidzas ar (deleted). Fails ir pilnībā pazudis no ls /var/lib/docker/volumes/..., tomēr katrs baits (482 MB iekšā users.ibd, 89 MB iekšā production.sqlite3) joprojām ir dzīvs iekšā /proc/<PID>/fd/<FD>.

2. darbība. Kopējiet atsaistītos datu bāzes failus tieši no /proc/<PID>/fd/

neapturiet vai restartējiet konteineru. Kamēr process joprojām darbojas, kopējiet neapstrādāto failu deskriptorus tieši uz sava saimniekdatora drošo mapi:

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

3. darbība. Vēl labāk: izpildiet reāllaika loģisko izgāztuvi (pg_dump / mysqldump / .backup), pirms konteiners aizver FD

Ja postgres vai mysqld joprojām darbojas ar saviem datu failiem, kas ir atvērti atmiņā un /proc/<PID>/fd/, vispirms mēģiniet palaist reāllaika loģisko izgāztuvi, izmantojot esošo unix ligzdu vai TCP savienojumu:

# 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
(Piezīme: PostgreSQL tiek atvērts un aizvērts .1, .2 dinamiski segmentēt failus visos darbinieku procesos, tāpēc pg_dump var neizdoties uz nekešatmiņas tabulām; apvienojot dzīvu SQL vaicājumu ar katra atvērtā kopēšanu /proc/<pid>/fd/* visā visā postgres bērnu aizmugursistēmas PID saglabā maksimāli iespējamo tabulu kaudzes datus.)


3. fāze: dzēsta Docker sējuma atkopšana ieslēgta ext4 vai XFS pēc konteinera apstāšanās

Kā būtu, ja tu skrietu docker compose down -v vai docker system prune --volumes, tātad konteiners ir jau apstājies un viss /proc/<pid>/fd/ deskriptori ir slēgti? Tagad jūs sacenšas ar fona diska ierakstiem Linux resursdatorā.

1. darbība: iesaldējiet Linux resursdatora failu sistēmu 10 sekunžu laikā

  1. Nekavējoties apturiet Docker, konteineru, kubelet un cron, lai neviens konteiners, veselības pārbaude vai žurnāla rotators nerakstītu vēl vienu baitu /var/lib/docker:
    sudo systemctl stop docker.socket docker.service containerd.service cron.service
    
  2. Pārbaudiet, kura bloka ierīce un failu sistēma ir spēkā /var/lib/docker:
    df -Th /var/lib/docker
    
    Filesystem     Type  Size  Used Avail Use% Mounted on
    /dev/nvme0n1p1 ext4  100G   42G   58G  42% /
    
  3. Atkārtoti uzstādiet tikai lasāmo nodalījumu (vai straumējiet neapstrādātu nodalījuma attēlu, izmantojot SSH uz citu datoru):
  4. Ja /var/lib/docker atrodas savā īpašajā nodalījumā vai LVM sējumā (piemēram /dev/nvme0n1p2 vai /dev/mapper/vg0-docker), nekavējoties atkārtoti pievienojiet to tikai lasāmai:
    sudo mount -o remount,ro /var/lib/docker
    
  5. Ja /var/lib/docker atrodas saknē / nodalījums (/), mēģiniet piespiest saknes nodalījumu tikai lasāmu, izmantojot kodola Magic SysRq trigeri (echo u | sudo tee /proc/sysrq-trigger) vai sudo mount -o remount,ro /.
  6. Ja izmantojat mākoņa VPS (AWS EC2, GCP, DigitalOcean, Hetzner, Linode): nekavējoties atveriet mākoņa tīmekļa konsoli un servera bloku sējumā noklikšķiniet uz Izveidot momentuzņēmumu (vai straumējiet neapstrādāto bloka ierīci, izmantojot SSH, uz otru serveri: sudo dd if=/dev/nvme0n1p1 bs=4M status=progress | gzip -1 | ssh user@backup-server "cat > /mnt/storage/docker_host_raw.img.gz").

2. darbība. Pārbaudiet, vai jūsu dati joprojām atrodas CITĀ neapgrieztā sējumā vai overlay2 slānis

Pirms nepiešķirtu diska bloku izveidošanas pārbaudiet, vai jūsu datu bāze faktiski nav saglabāta saistījumā vai citā vārdā nosauktā sējumā, kas ir saglabājies:

# 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
Katru nedēļu administratori pēc skriešanas krīt panikā docker volume rm app_db_data, tikai atklāt ar find /var/lib/docker ka docker-compose.yml faktiski bija izveidojis projectname_app_db_data (kas joprojām ir 100 procenti neskarts diskā), kamēr app_db_data bija vecs, neizmantots sējums pirms sešiem mēnešiem.

3. darbība. Atjaunojiet atsaistītus Docker sējumu direktorijus ext4 izmantojot ext4 Žurnāls (ext4magic un debugfs)

Kad docker volume rm dzēš /var/lib/docker/volumes/<vol_name>/_data uz an ext4 failu sistēma, ext4 nullē tiešās bloka norādes (i_block / apjoms koka saknes) dzīvajā inode tabulā. Tomēr ext4 žurnāls (inode <8>, parasti 128 MB uz 1024 MB apļveida gredzena buferis) joprojām glabā precīzu inode tabulu un direktoriju bloku vēsturiskās kopijas tieši pirms docker compose down -v tika izpildīts.

+-------------------------------------------------------------------------+
| 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.        |
+-------------------------------------------------------------------------+

Skrien ext4magic pret jūsu tikai lasāmo nodalījumu (vai .img momentuzņēmuma kopija otrā serverī), norādot laikspiedolu (-a) no 5 minūtes pirms jūs skrējāt docker compose down -v vai 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: nolasa žurnāla momentuzņēmumu, ko saglabājāt RAM uzreiz pēc Docker apturēšanas. - -f var/lib/docker/volumes: atlasa precīzu Docker sējumu direktoriju koku (piezīme: izlaidiet sākuma daļu / iekšā ext4magic relatīvie ceļi). - -a $(date -d "-15 minutes" +%s): stāsta ext4magic lai rekonstruētu direktoriju koku, izmantojot inode kopijas, kas bija derīgas pirms 15 minūtēm (tieši pirms nejaušas dzēšanas). - -r: Atgūst pilnus direktorijus, kuros nav pārrakstīts neviens bloks; ja -r palaiž garām daļēji pārrakstītos failus, palaidiet otro gājienu, aizstājot -r ar -m (burvju grebšana + žurnāla hibrīda režīms).

4. darbība: neapstrādātu SQLite, PostgreSQL vai MySQL InnoDB failu izgriešana, kad žurnāls ir iesaiņots (XFS vai ext4)

Warning

Kāpēc XFS neatbalsta ext4magic un nepieciešama tūlītēja tikai lasāma atvienošana: Atšķirībā no ext4, kas savā žurnālā ieraksta pilnas 256 baitu inode kopijas, XFS reģistrē metadatu nolūku deltas un agresīvi atkārtoti izmanto atbrīvotos inode B kokus (agi). Ja /var/lib/docker sēž uz an XFS nodalījums (pēc noklusējuma RHEL, Rocky Linux, AlmaLinux un Amazon Linux), atvienošana /var/lib/docker vai pārmontēšana / tikai lasāma dažu sekunžu laikā ir vissvarīgākais solis pirms grebšanas.

Ja saimniekdators izmanto XFS vai ja ext4 žurnāls jau ir apvilkts virs inode rādītājiem, izmantojiet paraksta un struktūras izgriezumu pret neapstrādātu diska attēlu (docker_host_raw.img):

  1. ** SQLite3 datu bāzēm (.sqlite, .db - piemēram, Vaultwarden, Nextcloud, Home Assistant, Gitea, Grafana)**: Katra SQLite3 datu bāze sākas ar nepārprotamu 16 baitu ASCII galveni tās pirmās 4 kilobaitu lapas 0. baitā: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 ("SQLite format 3\0"), un saglabā precīzu datu bāzes lapas izmēru (Bytes 16..17, parasti 4096) un kopējais datu bāzes lielums lapās (Bytes 28..31, lielais 32 bitu vesels skaitlis) tieši tajā pašā galvenē.
  2. Skrien PhotoRec ar [File Opt] -> [x] sqlite iespējots vai skenējiet nodalījumu tieši ar grep -ab "SQLite format 3" lai atrastu precīzu izdzēstā SQLite faila baitu nobīdi un izvilktu to ar dd:
    # Find the exact byte offsets of every "SQLite format 3" header on the partition:
    sudo grep -ab "SQLite format 3" /dev/nvme0n1p1
    
    Kad tas ir izvilkts, palaist sqlite3 carved.db ".recover" | sqlite3 repaired.db lai rekonstruētu katru neskarto B-koka lapu lapu.

Tip

Kā precīzi aprēķināt dd no galvenes atsaistīta SQLite3 faila baita lielums: vienreiz grep -ab "SQLite format 3" sniedz sākuma baitu nobīdi OFFSET no jūsu izdzēstās SQLite datu bāzes, lasīt baitus 16..17 (uint16 big-endian Page Size, piem., 0x1000 = 4096 baiti) un baiti 28..31 (uint32 big-endian Page Count, piem., 25000 lapas), izmantojot hexdump -C -s OFFSET -n 32. Pavairošana Page Size x Page Count sniedz precīzu baita garumu, kuram pāriet dd (iflag=skip_bytes,count_bytes), ja fails atrodas blakus diskā.

  1. MySQL/MariaDB InnoDB (.ibd tabulas faili): Katrs InnoDB .ibd tabula sastāv no secīgiem 16 KB (16,384 baits) lapas, kas satur FIL_PAGE_INDEX (0x45BF) galvene un tabula ir unikāla space_id. Izmantojiet Percona / TwinDBundrop-for-innodb (stream_parser + c_parser) skenēšanas rīku komplekts /dev/nvme0n1p1 visiem 16 KB InnoDB indeksa lapas un izmetiet katru rindu tieši TSV/SQL failos, lai tos atkārtoti importētu.
  2. ** PostgreSQL kaudzes failiem ($PGDATA/base/<db_oid>/<relfilenode>)**: PostgreSQL saglabā katru tabulu kā blakus esošu 8 KB (8,192 baits) kaudzes lapas, kas satur PageHeaderData (pd_lower, pd_upper, pd_special). Izmantojiet pg_filedump vai pglazarus / pdu, lai skenētu nepiešķirtos diska reģionus 8 KB lapas, kas atbilst jūsu tabulas kolonnu kopas izkārtojumam (HeapTupleHeaderData) un rekonstruēt rindas.

4. fāze: Kubernetes PVC, PV un etcd Momentuzņēmuma avārijas atkopšana

Kubernetes (EKS, GKE, AKS, k3s, RKE2, kubeadm, OpenShift), nejauši izdzēšot PersistentVolumeClaim (kubectl delete pvc), StatefulSet vai visa nosaukumvieta (kubectl delete ns prod) izmanto ļoti atšķirīgu arhitektūru nekā savrupajam Docker.

A scenārijs: PVC parāda Terminating (The Finalizer Lifesaver)

Palaist:

kubectl get pvc -n <namespace>
Ja STATUS kolonna saka Terminating, atviegloti nopūtieties: jūsu dati vēl NAV dzēsti. - Kāpēc? Katrs Kubernetes PVC, kas izveidots kopš Kubernetes 1.9, automātiski ietver finalizers: [kubernetes.io/pvc-protection]. - Kamēr Pod joprojām tiek uzstādīts šis PVC, Kubernetes kontrolleris atsakās pabeigt PVC dzēšanu un nekad neizsauc CSI draivera numuru. DeleteVolume RPC. - Nekavējoties rīkoties: NEDRĪKST dzēst vai restartēt Pod, un NE NELĀPOT** pabeigtāju. Nekavējoties nokopējiet visus datus no darbojas Pod uz vietējo datoru vai S3 spaini:
# 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

B scenārijs: PVC tika dzēsts un kubectl get pv parāda PersistentVolume in Released stāvoklis (ReclaimPolicy: Retain)

Palaist:

kubectl get pv
Ja jūsu PersistentVolume (pv-prod-postgres) joprojām ir sarakstā ar STATUS: Released (jo tā StorageClass izmantoja reclaimPolicy: Retain), 100 procenti jūsu datu joprojām neskarti atrodas pamatā esošajā diskā. Tomēr Kubernetes atsakās ļaut jaunam PVC saistīt ar a Released PV jo PV joprojām satur a spec.claimRef norādot uz vecajiem dzēstajiem PVC UID.

Kā pagatavot a Released PV Available atkal pēc 10 sekundēm bez datu zuduma: 1. Rediģējiet objektu PersistentVolume un izdzēsiet spec.claimRef bloķēt:

kubectl patch pv <your-pv-name> --type json -p '[{"op": "remove", "path": "/spec/claimRef"}]'
2. Skrien kubectl get pv vēlreiz: statuss nekavējoties mainās no Released līdz Available. 3. Atkārtoti izveidojiet savu PersistentVolumeClaim (norādot volumeName: <your-pv-name> un atbilstošo ietilpību/krātuvesClassName). Tas nekavējoties saistīsies ar esošo PV ar neskartiem failiem.

C scenārijs: notīrīta Kubernetes klastera stāvokļa atjaunošana no an etcd momentuzņēmums (etcdctl snapshot restore)

Ja nu kāds skrēja kubectl delete namespace prod vai helm uninstall un iznīcināja 200 Kubernetes manifestus, noslēpumus, konfigurācijas kartes un PV definīcijas pašpārvaldītajā ierīcē. kubeadm, k3s, vai RKE2 vadības plakne?

  1. ** Atrodiet savu jaunāko etcd momentuzņēmums** (pēc noklusējuma in /var/lib/rancher/k3s/server/db/snapshots/, /var/lib/rancher/rke2/server/db/snapshots/, vai jūsu ieplānotais /var/backups/etcd/snapshot.db).
  2. Pārbaudiet momentuzņēmuma integritāti, pirms pieskaraties dzīvajam klasterim:
    ETCDCTL_API=3 etcdctl snapshot status /path/to/snapshot.db --write-out=table
    
  3. Stop kube-apiserver un etcd vadības plaknes mezglā(-os):
  4. kubeadm (statiskās pākstis): pārvietot /etc/kubernetes/manifests/kube-apiserver.yaml un /etc/kubernetes/manifests/etcd.yaml uz laiku uz /root/manifests_hold/ tātad kubelet tīri aptur abus konteinerus, pēc tam paceļ atpakaļ /var/lib/etcd uz /var/lib/etcd.bak.
  5. k3s: Skrien sudo systemctl stop k3s un sudo k3s server --cluster-reset --cluster-reset-restore-path=/path/to/snapshot.
  6. ** Atjaunot etcd datu direktorijs ieslēgts 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. Pārvietot etcd.yaml un kube-apiserver.yaml atpakaļ iekšā /etc/kubernetes/manifests/. 30 sekunžu laikā, kube-apiserver atkal savienojas ar atjaunoto etcd veikals un katrs izdzēstais Namespace, Secret, ConfigMap un PersistentVolume objekts atkal parādās.

5. fāze: Docker un Kubernetes sējumu sacietēšana pret nejaušu dzēšanu

Kad jūsu ražošanas datu bāze ir atjaunota, ieviesiet šīs četras arhitektūras aizsargmargas, lai viena CLI drukas kļūda vairs nekad nevarētu dzēst reāllaika sējumu:

  • Mainiet katru produkciju Kubernetes StorageClass no reclaimPolicy: Delete uz reclaimPolicy: Retain: pēc noklusējuma iebūvēta mākoņa StorageClasses (gp2, gp3, standard-rwo) noklusējuma uz reclaimPolicy: Delete, kas nozīmē, ka PVC dzēšana iznīcina mākoņa disku. Izveidot a StorageClass ar reclaimPolicy: Retain (vai lāpojiet esošos PV ar kubectl patch pv <pv-name> -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'), tāpēc, dzēšot PVC vai nosaukumvietu, pamatā esošais bloka apjoms nekad netiek izdzēsts.
  • Iespējot AWS EBS atkritni / GCP momentuzņēmumu grafikus / Velero ar CSI momentuzņēmumiem: iespējojot AWS EBS atkritni, visi izdzēstie EBS sējumi tiek saglabāti 7-30 dienas, pat ja CSI draiveris zvana. DeleteVolume.
  • ** Nekad nelietojiet docker system prune --volumes automātiskajos tīrīšanas skriptos vai CI/CD palaistos**: ja ražošanas datu bāzes konteiners īslaicīgi avarē (Exited (1)) tieši tajā brīdī, kad tiek palaists cron darbs docker system prune -a --volumes -f, Docker uzskata savus anonīmos sējumus par "nelietotiem" un neatgriezeniski dzēš tos. Sloksne --volumes no visiem tīrīšanas skriptiem.
  • Izmantojiet precīzas resursdatora saistīšanas stiprinājumus (/srv/prod_data/postgres:/var/lib/postgresql/data) vai ārējām pārvaldītām datu bāzēm statusa ražošanas darba slodzēm: atšķirībā no /var/lib/docker/volumes/, resursdatora saistīšanas-mount direktorijus ārpus /var/lib/docker/ kuras nekad nav pieskāries docker compose down -v, docker volume rm, vai docker system prune --volumes.

Reģionālie neatliekamās palīdzības numuri un aģentūru protokoli

Ja konteinera vai Kubernetes krātuves dzēšana ietekmē slimnīcas klīniskās darbības, sabiedriskās drošības nosūtīšanu vai regulētos personas datus, nekavējoties eskalējiet:

  • ASV un Kanāda: sastādiet 911 ja konteineru klastera kļūme atspējo pacientu klīnisko uzraudzību, EHR sistēmas vai ārkārtas nosūtīšanu. Ziņojiet par ļaunprātīgu konteineru infrastruktūras iznīcināšanu vai kiberincidentiem CISA (1-844-Say-CISA / cisa.gov/report) vai Kanādas kiberdrošības centrs (1-833-CYBER-88).
  • Apvienotā Karaliste: sastādiet 999 par draudiem dzīvībai vai kritiskai NHS infrastruktūrai. Saskaņā ar Apvienotās Karalistes GDPR personas datu pastāvīgai iznīcināšanai vai pieejamības zaudēšanai bez atkopjamas dublējuma ir jāizvērtē 72 stundu paziņojums par pārkāpumu ICO (0303 123 1113).
  • Eiropas Savienība: sastādiet 112 visās ES dalībvalstīs. Uzņēmumiem, uz kuriem attiecas NIS2 direktīva, 24 stundu laikā pēc nopietna pakalpojuma pārtraukuma ir jāiesniedz savs valsts CSIRT agrīnais brīdinājums, un pastāvīga personas datu zaudēšana izraisa VDAR 33. panta ziņošanu 72 stundu laikā.
  • Austrālija un Jaunzēlande: sastādiet 000 Austrālijā vai 111 Jaunzēlandē; ziņot par kritiskās infrastruktūras incidentiem ACSC (1300 CYBER1).
  • Indija un Āzijas un Klusā okeāna valstis: sastādiet 112 Indijā ārkārtas reaģēšanai; ziņot par mākoņa vai konteineru drošības incidentiem CERT-In (incident@cert-in.org.in) obligātajā 6 stundu logā.

Bieži uzdotie jautājumi

Vai docker compose down -v dzēst resursdatora saistīšanas savienojumus (./data:/var/lib/mysql) vai tikai Named un Anonymous Docker sējumi?

`docker compose down -v` TIKAI dzēš nosauktos sējumus, kas deklarēti `volumes:` sadaļa `docker-compose.yml` un anonīmie sējumi, kas pievienoti konteineriem; to nekad dzēš failus resursdatora saistīšanas mount iekšpusē (piemēram, `- /opt/mysql_data:/var/lib/mysql` vai `- ./postgres_data:/var/lib/postgresql/data`). Ja jūsu rakstīšanas failā tika izmantots saimniekdatora ceļš, kas sākas ar `/` vai `./`, pārbaudiet šo mapi resursdatorā tūlīt: jūsu faili joprojām ir 100% neskarti.

Kāpēc darīja docker system prune --volumes Vai dzēst savu datu bāzes apjomu, kad es apturēju konteineru tikai uz 2 minūtēm, lai atjauninātu vides mainīgo?

Uzmanīgi pagaidiet, līdz atšķirsies `docker stop` un `docker rm`: ja konteiners ir tikai `Stopped / Exited` (redzams `docker ps -a`), `docker system prune --volumes` dara nē dzēst tā sējumus, jo apturētais konteiners joprojām atsaucas uz tiem. Tomēr, ja jūs skrējāt `docker rm ` (lai atkārtoti izveidotu konteineru ar jauniem karodziņiem) vai ja esat izturējis `docker system prune -a --volumes` (kas vispirms izdzēš visus apturētos konteinerus un tad dzēš visus sējumus, kas vairs nav pievienoti nevienam konteineram), apjoms kļuva "karājošs" milisekundē, kad apturēts konteiners tika noņemts un nekavējoties pēc tam noslaucīts.

Vai es varu atgūt izdzēstu Docker sējumu Docker Desktop datorā Mac (Apple Silicon / Intel) vai Windows (WSL2)?

Jā, ja nekavējoties aizverat Docker Desktop, lai virtuālā mašīna pārstātu darboties `fstrim` pret virtuālo disku. Operētājsistēmā MacOS Docker glabā visus Linux sējumus `-/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw`; operētājsistēmā Windows WSL2, iekšpusē `%LocalAppData%\Docker\wsl\disk\docker_data.vhdx`. Kopējiet to `.raw` vai `.vhdx` failu nekavējoties ārējam SSD, pievienojiet to tikai lasāmu operētājsistēmā Linux (izmantojot `losetup -Pr` priekš `.raw` vai `qemu-nbd -r` priekš `.vhdx`), un palaist `ext4magic` vai `PhotoRec` pret virtuālo `ext4` nodalījums iekšpusē.

Kā rīkoties, ja es izdzēsu Kubernetes StatefulSet ar kubectl delete statefulset postgres? Vai tas izdzēsa arī manus PVC?

Nē. Pēc noklusējuma Kubernetes (ja vien nav `persistentVolumeClaimRetentionPolicy.whenDeleted: Delete` tika skaidri konfigurēts Kubernetes 1.27+), kas darbojas `kubectl delete statefulset` dzēš StatefulSet kontrolleri un tā aplikācijas, atstājot visu `PersistentVolumeClaims` (`data-postgres-0`, `data-postgres-1`) un to pamatā esošie dati ir 100% neskarti. Vienkārši atkārtoti piesakiet savu `StatefulSet` YAML manifests ar tādu pašu nosaukumu un `volumeClaimTemplates`, un jaunie podi tiks automātiski atkārtoti pievienoti esošajiem `data-postgres-0` PVC.

Kā piekļūt failiem Docker iekšienē overlay2 direktoriju, kad konteiners atsakās startēt (CrashLoopBackOff / Exited (1))?

Neizdzēsiet avarējušo konteineru. Kamēr apturētais konteiners joprojām pastāv `docker ps -a`, tā rakstāmā slāņa un skaļuma stiprinājumi diskā ir pilnībā neskarti. Varat kopēt failus tieši no apturētā konteinera, izmantojot `docker cp :/var/lib/postgresql/data /root/rescued_data`vai atrodiet precīzu tā saimniekdatoru `overlay2` ceļš skrienot `docker inspect --format '{{.GraphDriver.Data.UpperDir}}'` un lasot šo direktoriju tieši kā `root`.

Ko darīt, ja kāds izdzēsis Kubernetes Namespace (kubectl delete ns prod) un visiem PVC bija reclaimPolicy: Delete AWS EBS vai GCP?

Ja mākoņa CSI draiveris (`ebs.csi.aws.com` vai `pd.csi.storage.gke.io`) jau izpildīts `DeleteVolume` jo `reclaimPolicy` bija `Delete`, nekavējoties pārbaudiet trīs mākoņa līmeņa drošības tīklus: (1) pārbaudiet **AWS Recycle Bin for EBS Volumes** AWS EC2 konsolē (ja kontā/tagiem bija aktīvs saglabāšanas kārtula, dzēstais EBS sējums atrodas atkritnē un to var atjaunot ar 1 klikšķi); (2) pārbaudiet **AWS dublēšana / DLM / GCP momentuzņēmumu grafiki**, lai iegūtu jaunāko automatizēto apjoma momentuzņēmumu; un (3) pārbaudiet, vai jūsu datu bāze straumēja WAL/binlogus (`WAL-G`, `pgBackRest`, `Litestream`) uz S3/GCS spaini.


Saistītie ceļveži


Avoti un oficiālās vadlīnijas

  • Kubernetes oficiālā dokumentācija (kubernetes.io / Cloud Native Computing Foundation): Uzglabāšanas objekta izmantošanas aizsardzība (kubernetes.io/pvc-protection Finalizatori), Pastāvīgo apjomu atgūšana (Retain vs. Delete), un darbojas etcd Klasteri priekš Kubernetes (etcdctl snapshot restore).
  • Docker Inc. (docs.docker.com): Pārvaldīt datus programmā Docker: sējumi, saistīšanas stiprinājumi, overlay2 Krātuves draivera arhitektūra un plūmju atsauce.
  • Linux kodola organizācija (kernel.org): * /proc Failu sistēma (procfs Atveriet failu deskriptora atkopšanu, izmantojot /proc/<pid>/fd/) un Ext4 žurnāla specifikācija*.
  • ext4magic Projekta dokumentācija (ext4magic.sourceforge.net): tiesu medicīnas inode un žurnāla transakciju atkopšana Ext3/Ext4 failu sistēmās.
  • Nacionālais standartu un tehnoloģiju institūts (NIST) (ASV): Īpaša publikācija 800-190: Lietojumprogrammu konteinera drošības rokasgrāmata un incidentu atkopšana.