Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Як провести live migration контейнера між хостами (CRIU)?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Docker exposing **`docker checkpoint`** (powered CRIU), щоб freeze стан running-container на disk і restore деінде. ```bash # Enable experimental на daemon: "experimental": true у /etc/docker/daemon.json # На host A: snapshot running-container docker checkpoint create app cp1 --checkpoint-dir=/var/checkpoints # Copy /var/checkpoints/cp1 на host B (rsync, scp) rsync -a /var/checkpoints/cp1/ hostb:/var/checkpoints/cp1/ # На host B: створи container у stopped-state і start з checkpoint docker create --name app myorg/app:1.0 docker start --checkpoint=cp1 --checkpoint-dir=/var/checkpoints app ``` **Reality check:** це **experimental і рідко production-grade.** Більшість команд беруть **stateless redeploy** (kill на A, start на B зі shared-state) замість CRIU. CRIU блищить для HPC/наукових workload з довгими running-обчисленнями. Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**CRIU** (Checkpoint/Restore In Userspace) це Linux-feature, що freezes running process-tree у набір файлів і restoring later, на тому ж host або іншому, ідеально, з program-ом ні в чому не помічаючим. Docker інтегрує CRIU через experimental `docker checkpoint`-subcommand, що найближче Docker має до live container-migration. Працює для вузьких use case. Для більшості команд stateless-redeploy простіший і надійніший. ## Теорія ### TL;DR - CRIU dump'ить process-memory, file-descriptor, socket і namespace на disk; restoring on demand. - `docker checkpoint create` виробляє checkpoint; `docker start --checkpoint` resume з нього. - Потребує `"experimental": true` у `daemon.json` і kernel з CRIU-support. - Обидва host'и потребують ту ж kernel-version, той самий CPU-instruction-set, ту ж Docker-version, identical filesystem-state у момент snapshot. - Network-state finicky: IP/MAC container'а рухається з migration; потребує network, що це дозволяє. - **Use case вузький**: довгі обчислення, де не можеш restart from scratch (HPC, ML-training, довгі simulation). - **Більшість production-патернів** (web-app, microservice) беруть **stateless-redeploy** замість, де state живе поза container (DB, object-storage). ### Як CRIU працює 1. Зупини всі process у target's PID-namespace (через `ptrace`). 2. Читай від кожного process: - Memory-page - Open file / socket-state / pipe - Namespace (PID, mnt, net, uts, ipc, user) - Thread, futex, signal 3. Serialize все вище на disk як protobuf-encoded-файли. 4. (Опційно) тримай process running, re-attach'ом, або kill його. 5. На target-host recreate process з тими ж PID (Linux дозволяє requesting specific PID у новому namespace), restore memory-page, reattach FD. 6. Resume execution. Крукс у тому, що **kernel-state** має матчити: file-path, mounted-volume, network-state, `/etc/hosts`, device. CRIU детектить mismatch і refuse restore у багатьох випадках. ### Чому це рідко на практиці - **Kernel-version sensitivity.** Process snapshotted на kernel 5.10 може fail restore на 5.15, бо internal kernel-structure changed. - **Hardware sensitivity.** Різний CPU-vendor або microarchitecture може ламати (AVX-availability, TSC-behavior, randomness-sources). - **Network і filesystem-state.** Open TCP-connection, NFS-handle, special-file, легко зламати. - **Більшість workload не потребує.** Stateless web-server може restart за секунди; не треба live-migrate, ти просто deploy новий. - **Сучасні альтернативи.** Kubernetes pod-eviction + rescheduling, blue-green-deploy, rolling-update, всі простіші за CRIU. ### Коли реально допомагає - **Наукові обчислення**: 12-годинна simulation, що крутилася 8 годин; host потребує maintenance. Snapshot, migrate, resume. Краще за restart. - **Довгі ML-training-job**: similar. - **Hot-patching stateful in-memory-сервісів**: рідко, advanced. - **Container live-migration у research/POC**: CRIU це building-block для проєктів типу P.Haul (process haul) або container live-migration-прототипів. ## Приклади ### Setup Kernel має бути built з CRIU-options. Більшість сучасних distro мають. Перевір: ```bash zgrep CONFIG_CHECKPOINT /proc/config.gz # CONFIG_CHECKPOINT_RESTORE=y ``` Встанови CRIU: ```bash sudo apt install -y criu # Debian/Ubuntu sudo dnf install -y criu # Fedora/RHEL criu check # Looks OK. ``` Enable experimental у `/etc/docker/daemon.json`: ```json { "experimental": true } ``` ```bash sudo systemctl restart docker docker version | grep Experimental ``` ### Same-host snapshot/restore (найпростіший випадок) Запусти long-running-container: ```bash docker run -d --name counter --rm \ busybox sh -c 'i=0; while true; do echo $i; i=$((i+1)); sleep 1; done' # Дивися, як рахує docker logs -f counter # 0 # 1 # 2 # ... # 47 ``` Checkpoint на 47: ```bash docker checkpoint create counter cp1 # cp1 ``` Container тепер stopped (дефолтна поведінка). Checkpoint-файли у `/var/lib/docker/containers/<id>/checkpoints/cp1/`. Restore: ```bash docker start --checkpoint=cp1 counter docker logs -f counter # 48 # 49 # ... ``` Counter resume з 48, не з 0. State preserved. ### Snapshot без зупинки container ```bash docker checkpoint create --leave-running counter cp1 # Container продовжує running, поки checkpoint береться ``` ### Cross-host-migration #### Крок 1, image має бути на обох host'ах ```bash # На host A docker save myorg/app:1.0 | ssh hostb "docker load" # Або push у registry і pull на B ``` #### Крок 2, checkpoint на host A ```bash docker checkpoint create --checkpoint-dir=/var/checkpoints app cp1 ``` `--checkpoint-dir` override default-location, щоб ти міг легко grab файли. #### Крок 3, copy checkpoint і volume-data на host B ```bash rsync -a --delete /var/checkpoints/cp1/ hostb:/var/checkpoints/cp1/ # Плюс bind-mounted-каталоги, named-volume тощо. ``` #### Крок 4, на host B recreate container у stopped-state ```bash ssh hostb docker create --name app \ -v /data:/data \ -p 8080:8080 \ myorg/app:1.0 # Нота: ті самі volume-mount, ті самі port, той самий image ``` #### Крок 5, restore з checkpoint ```bash docker start --checkpoint=cp1 --checkpoint-dir=/var/checkpoints app docker logs app # Має resume з того, де host A залишив ``` ### Що може піти не так - **«Failed to restore: open files mismatch»**: file був open на host A, що не існує на host B. Фіксь bind-mount. - **«Failed to restore: socket peer not found»**: open TCP-connection не може бути re-established. CRIU має `--tcp-established`-режим для коротких connection, але ненадійний для long-lived. - **«Unable to restore PID X»**: PID вже зайнятий на host B's PID-namespace. CRIU зазвичай обробляє це у container (private PID-namespace), але edge-cases існують. - **Kernel/glibc/CPU-mismatch**: один з десятків subtle-помилок. Читай CRIU-docs. ### Де реально блищить (реальний приклад) Довга наукова simulation: ```bash # День 1: start 24-годинної simulation docker run -d --name sim --gpus all myorg/simulation:1.0 sim_run config.toml # 18 годин in, GPU-driver host'а потребує оновлення. Не можна restart. docker checkpoint create --leave-running sim cp1 --checkpoint-dir=/scratch/cp1 rsync -a /scratch/cp1/ gpu-host-2:/scratch/cp1/ ssh gpu-host-2 docker create --name sim --gpus all myorg/simulation:1.0 sim_run config.toml docker start --checkpoint=cp1 --checkpoint-dir=/scratch/cp1 sim # Simulation resume на іншому host, продовжує ще 6 годин ``` ## Реальне застосування - **HPC-кластери і research-environment** (оригінальний use case). - **Деякі container-orchestrator** типу Singularity (HPC-focused) інтегрують CRIU як feature. - **Kubernetes Pod Live-Migration** у alpha з 2024 (KEP-2008), використовує CRIU під капотом. - **Docker Swarm і stock K8s production**: не покладайся. Бери deploy-стратегію (rolling, blue-green, canary). ### Limitation 1. **Experimental.** Docker не graduate `checkpoint` до GA. API можуть змінитися. 2. **Без GPU-state migration** у stock-CRIU. Active research, не production. 3. **Без support деяких namespace** у старих версіях. 4. **Не у Docker Desktop.** Docker Desktop VM не enable CRIU. 5. **Performance**: writing всю memory на disk бере секунди-до-хвилин для великих container. ### Альтернативи, що краще вирішують ту саму проблему | Потреба | Кращий tool | |---|---| | Перенести web-server без downtime | Blue-green-deploy зі stateless-app | | Перенести stateful-сервіс | Externalize state (DB, S3); redeploy stateless wrapper | | Maintenance-вікно на node | Drain, reschedule (K8s, Swarm, Nomad) | | Довге обчислення | Periodic application-level checkpoint (write progress на disk кожні N хвилин; resume звідти) | Application-level checkpoint зазвичай кращий answer за CRIU, бо: - Portable через kernel/CPU/distro-зміни. - Менші (тільки твої дані, не вся memory). - Переживають image-upgrade. - Testable. ### Типові помилки **Treating CRIU як production-grade live-migration** Це experimental у Docker. Для production, бери rolling-deploy. **Не матчити state через host'и** Volume-content, mounted-secret, host's `/etc/resolv.conf`, все має матчити. Легше сказати, ніж зробити. **Спроба migrate container з active TCP-connection** CRIU's `--tcp-established` крихкий. Drain connection спочатку, або прийми reset. **Skip kernel-match** Migration з kernel 5.10 на 5.15 може працювати, може ні. Test у staging. ### Питання для поглиблення **Q:** Чи `docker checkpoint` enabled за замовчуванням? **A:** Ні. Маєш enable `"experimental": true` у `/etc/docker/daemon.json` і restart daemon. **Q:** Що з Kubernetes live-migration? **A:** KEP-2008 (Container Live-Migration) у alpha. Використовує CRIU під капотом. Не рекомендовано для prod ще (станом на кінець 2024). **Q:** Чи можу я checkpoint container з database всередині? **A:** Технічно так, але on-disk DB-файли мають бути на target-host. Це одна з причин, чому DB зазвичай на volume, і volume реплікується окремо (DB-replication). **Q:** (Senior) Чому CRIU не стандартний answer для перенесення stateful-сервісів? **A:** Бо universe «identical state on both hosts» крихкий. Сучасні stateful-сервіси (DB, message-queue) спроєктовані для replication: leader/follower, multi-master, distributed-consensus. Ти переносиш дані через application-replication-протокол, не через snapshot kernel-state. CRIU обходить data-model app і припускає, що може recreate кожен byte process-state, far more brittle, ніж дзеркалити дані через Postgres-replication або Kafka-mirroring. **Q:** (Senior) Коли правильний час розглядати CRIU? **A:** Коли (1) workload single-instance і не може trivially restart, (2) progress у process-memory (не в DB чи file), (3) контролюєш обидва host, включаючи kernel-version, (4) ціна reproduction state from scratch перевищує engineering-ціну роботи з quirk CRIU. HPC/research check всі чотири. Production-microservice check ні одне.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.