Создание и восстановление контрольных точек контейнеров#

Checkpoint/Restore In Userspace (CRIU) - это программное обеспечение, которое позволяет установить контрольную точку на запущенном контейнере или отдельном приложении и сохранить его состояние на диск. Можно использовать сохраненные данные для восстановления контейнера после перезагрузки в момент, когда была создана контрольная точка.

Создание и восстановление контрольных точек локально#

Данный сценарий основан на веб-сервере, базирующимся на Python. Он возвращает одно целое число, увеличивающееся после каждого запроса к серверу.

  1. Создайте сервер на основе Python:

    cat counter.py
    

    Пример конфигурации сервера:

    !/usr/bin/python3
    
    import http.server
    
    counter = 0
    
    class handler(http.server.BaseHTTPRequestHandler):
        def do_GET(s):
            global counter
            s.send_response(200)
            s.send_header('Content-type', 'text/html')
            s.end_headers()
            s.wfile.write(b'%d\n' % counter)
            counter += 1
    
    
    server = http.server.HTTPServer(('', 8088), handler)
    server.serve_forever()
    
  2. Создайте контейнер со следующим определением:

    cat Containerfile
    ~~
    
    Пример содержимого файла контейнера:
    
    ~~~bash
    FROM registry.example.ru/ubi9/ubi
    
    COPY counter.py /home/counter.py
    
    RUN useradd -ms /bin/bash counter
    
    RUN dnf -y install python3 && chmod 755 /home/counter.py
    
    USER counter
    ENTRYPOINT /home/counter.py
    

    Контейнер основан на универсальном базовом образе (UBI 8) и использует сервер на основе Python.

  3. Создайте контейнер:

    podman build . --tag counter
    

    Файлы counter.py и Containerfile входные данные для процесса сборки контейнера (podman build). Созданный образ хранится локально и помечается тегом counter.

  4. Запустите контейнер от имени пользователя с административными полномочиями:

    podman run --name criu-test --detach counter
    
  5. Для раскрытия списка всех запущенных контейнеров введите:

    podman ps
    

    Пример вывода команды:

    CONTAINER ID  IMAGE  COMMAND  CREATED   STATUS  PORTS NAMES
    e4f82fd84d48  localhost/counter:latest  5 seconds ago  Up 4 seconds ago  criu-test
    
  6. Отобразите IP-адреса контейнера:

    podman inspect criu-test --format "{{.NetworkSettings.IPAddress}}"
    
  7. Отправьте запросы в контейнер:

    curl <IP-address>:8088
    0
    curl <IP-address>:8088
    1
    

    Где <IP-address> - IP-адрес, полученный в ходе выполнения предыдущего шага.

  8. Создайте контрольную точку для контейнера:

    podman container checkpoint criu-test
    
  9. Перезагрузите систему;

  10. Восстановите контейнер:

    podman container restore --keep criu-test
    
  11. Отправьте запросы контейнеру:

curl <IP-address>:8080
2
curl <IP-address>:8080
3
curl <IP-address>:8080
4

Результат в выводе начинается не со значения 0, а продолжается со значения, сохраненного при создании контрольной точки.

Благодаря этому можно легко сохранить полное состояние контейнера перед перезагрузкой.

Сокращение времени запуска с помощью восстановления контейнера#

Можно использовать миграцию контейнера, чтобы сократить время запуска контейнеров, для инициализации которых требуется определенное время. Используя контрольную точку, можно восстановить контейнер несколько раз на одном хосте или на разных. Сценарий в этой главе основан на контейнере из раздела «Создание и восстановление контрольных точек локально».

  1. Создайте контрольную точку для контейнера и экспортируйте образ в файл tar.gz:

    podman container checkpoint criu-test --export /tmp/chkpt.tar.gz
    
  2. Восстановите контейнер из файла tar.gz:

    podman container restore --import /tmp/chkpt.tar.gz --name counter1
    podman container restore --import /tmp/chkpt.tar.gz --name counter2
    podman container restore --import /tmp/chkpt.tar.gz --name counter3
    

    Опция --name (-n) определяет новое имя для контейнеров, восстановленных из экспортируемой контрольной точки.

  3. Раскройте ID и имена каждого контейнера:

    podman ps -a --format "{{.ID}} {{.Names}}"
    

    Пример вывода команды:

    a8b2e50d463c counter3
    faabc5c27362 counter2
    2ce648af11e5 counter1
    
  4. Отобразите IP-адрес каждого контейнера:

    podman inspect counter1 --format "{{.NetworkSettings.IPAddress}}"
    <IP-address-1>
    
    podman inspect counter2 --format "{{.NetworkSettings.IPAddress}}"
    <IP-address-2>
    
    podman inspect counter3 --format "{{.NetworkSettings.IPAddress}}"
    <IP-address-3>
    
  5. Отправьте запросы каждому из контейнеров:

    curl <IP-address-1>:8080
    2
    curl <IP-address-2>:8080
    2
    curl <IP-address-3>:8080
    2
    

    Вывод содержит значение 2 для каждого контейнера, поскольку они восстановлены с одной контрольной точки.

Миграция контейнеров между системами#

Можно переносить запущенные контейнеры из одной системы в другую, не теряя состояния приложений, работающих внутри. Данный сценарий основывается на контейнере из раздела «Создание и восстановление контрольных точек локально» с тегом counter.

Важно

Перенос контейнеров между системами с помощью команд podman container checkpoint и podman container restore поддерживается, если конфигурации систем полностью совпадают. А именно:

  • версия podman;

  • OCI времени выполнения (runc/crun);

  • сетевой стек (CNI/Netavark);

  • версия сgroups;

  • версия ядра;

  • дополнительные возможности процессора.

Следующие шаги опциональны, если контейнер помещен в реестр. Podman автоматически загрузит его, если он недоступен локально. В данном сценарии не используется реестр, для экспорта потребуется ранее построенный и имеющий тег counter контейнер. Для более подробной информации обратитесь к разделу «Создание и восстановление контрольных точек контейнера локально».

  • Экспортируйте ранее созданный контейнер:

    podman save --output counter.tar counter
    
  • Скопируйте экспортируемый образ контейнера в систему назначения (other_host):

    scp counter.tar other_host:
    
  • Импортируйте контейнер в систему назначения:

    ssh other_host podman load --input counter.tar
    

    Теперь целевая система для миграции контейнера имеет тот же образ, который хранится в локальном хранилище.

Сценарий#

  1. Запустите контейнер от имени пользователя с административными полномочиями:

    podman run --name criu-test --detach counter
    
  2. Раскройте IP-адрес контейнера:

    podman inspect criu-test --format "{{.NetworkSettings.IPAddress}}"
    
  3. Отправьте запросы на контейнер:

    curl <IP-address>:8080
    0
    curl <IP-address>:8080
    1
    
  4. Создайте контрольную точку контейнера и экспортируйте ее образ в файл tar.gz:

    podman container checkpoint criu-test --export /tmp/chkpt.tar.gz
    
  5. Скопируйте архив контрольной точки на целевой хост (other_host):

    scp /tmp/chkpt.tar.gz other_host:/tmp/
    
  6. Восстановите контрольную точку на целевом хосте:

    podman container restore --import /tmp/chkpt.tar.gz
    
  7. Отправьте запрос контейнеру на целевом хосте (other_host):

    curl <IP-address>:8080
    2
    

В результате контейнер с тем же состоянием был перенесен из одной системы в другую.