https://bobcares.com/blog/move-docker-container-to-another-host/
https://stackoverflow.com/questions/28734086/how-to-move-docker-containers-between-different-hosts

Задача

Нужно мигрировать контейнеры docker (инсталляцию AWX) на новый хост. Инсталляция содержит 5 контейнеров, развернутых с помощью docker compose.
Контейнеры имеют смонтированные volumes, а также имеют файлы, установленные непосредственно в контейнер.

Предварительно, на целевом хосте настроена аутентификация по ключу, пользователь добавлен в группу sudo, а в /etc/sudoers прописано %sudo ALL=(ALL) NOPASSWD:ALL.
Скрипт просматривает конфигурацию контейнеров awx, берет оттуда настройки mounts, создает на удаленном хосте такие же и копирует данные.

#!/bin/bash
remote_host=awx
user=usik.ma
#pass=password
rsync_path="sudo rsync"
containers=`docker container ls --format "{{json .Names}}" | grep awx_ | sed 's/\"//g'`
for container in $(echo $containers)
do
  echo "container - $container"
  docker container stop $container
  mounts=`docker container inspect $container --format "{{ range .Mounts }}{{ .Type }}:{{ .Name }}:{{ .Source }}:{{ .Destination }} {{ end }}"`
  for mount in `echo $mounts`
  do
    mount_type=`echo $mount | cut -d: -f1`
    case $mount_type in
     bind)
          echo "type - bind"
          echo $mount
          bind_src=`echo $mount | cut -d: -f3`
          echo "Bind SRC - $bind_src"
          rsync -aRvvP --rsync-path="$rsync_path" $bind_src $user@$remote_host:/
          ;;
     volume)
          echo "type - Volume"
          echo $mount
          vol_name=`echo $mount | cut -d: -f2`
#          echo $pass | ssh -tt $user@$remote_host "sudo docker volume create $vol_name"
          ssh $user@$remote_host "sudo docker volume create $vol_name"
          vol_local_mountpoint=`docker volume inspect $vol_name --format "{{json .Mountpoint}}" | sed 's/\"//g'`
#          vol_remote_mountpoint=`echo $pass | ssh -tt $user@$remote_host "sudo docker volume inspect $vol_name --format '{{json .Mountpoint}}' | sed 's/\"//g'"`
          vol_remote_mountpoint=`ssh $user@$remote_host "sudo docker volume inspect $vol_name --format '{{json .Mountpoint}}' | sed 's/\"//g'"`
          vol_remote_mountpoint=`echo $vol_remote_mountpoint | sed 's/^[^\/]*\//\//'`
          echo "local mountpoint - $vol_local_mountpoint; remote mountpoint - $vol_remote_mountpoint"
          rsync -avvP --rsync-path="$rsync_path" $vol_local_mountpoint $user@$remote_host:$vol_remote_mountpoint
          ;;
    esac
  done
  docker container start $container
done
while read -r line; do docker commit $line; done < <(docker container ls --format "{{json .ID}} {{json .Names}}_current" | grep awx_ | sed 's/\"//g')
#while read -r line; do docker save $line | ssh -C awx docker load; done < <(docker images --format "{{json .Repository}}" | grep _current | sed 's/\"//g')
while read -r line; do docker save $line | ssh -C awx docker load; done < <(docker images --format "{{json .Repository}}" | sed 's/\"//g')
while read -r line; do docker image rm $line; done < <(docker images --format "{{json .Repository}}" | grep _current | sed 's/\"//g')

А теперь можно создать контейнеры из скопированных имиджей с помощью команды docker create, либо воспользоваться docker compose. Файл лежит тут: /opt/awx/awxcompose/docker-compose.yml. Переносим его на новый хост:

rsync -avvP --rsync-path="rsync sudo" /opt/awx/awxcompose/docker-compose.yml $user@$remote_host:/opt/awx/awxcompose/docker-compose.yml

Редактируем его, указывая в качестве имиджей - те, что были созданы, а также указывая restart: always. У меня пролучилось примерно так:

version: '2'
services:

  web:
    image: awx_web_current
    container_name: awx_web
    depends_on:
      - rabbitmq
      - memcached
      - postgres
    ports:
      - "80:8052"
    hostname: awxweb
    user: root
    restart: always
    volumes:
      - "/opt/awx/awxcompose/SECRET_KEY:/etc/tower/SECRET_KEY"
      - "/opt/awx/awxcompose/environment.sh:/etc/tower/conf.d/environment.sh"
      - "/opt/awx/awxcompose/credentials.py:/etc/tower/conf.d/credentials.py"
    environment:
      http_proxy: 
      https_proxy: 
      no_proxy: 

  task:
    image: awx_task_current
    container_name: awx_task
    depends_on:
      - rabbitmq
      - memcached
      - web
      - postgres
    hostname: awx
    user: root
    restart: always
    volumes:
      - "/opt/awx/awxcompose/SECRET_KEY:/etc/tower/SECRET_KEY"
      - "/opt/awx/awxcompose/environment.sh:/etc/tower/conf.d/environment.sh"
      - "/opt/awx/awxcompose/credentials.py:/etc/tower/conf.d/credentials.py"
    environment:
      http_proxy: 
      https_proxy: 
      no_proxy: 

  rabbitmq:
    image: awx_rabbitmq_current
    container_name: awx_rabbitmq
    restart: always
    environment:
      RABBITMQ_DEFAULT_VHOST: "awx"
      RABBITMQ_DEFAULT_USER: "guest"
      RABBITMQ_DEFAULT_PASS: "PTB4h5Zt1m1BSu8J"
      RABBITMQ_ERLANG_COOKIE: cookiemonster
      http_proxy: 
      https_proxy: 
      no_proxy: 

  memcached:
    image: "awx_memcached_current"
    container_name: awx_memcached
    restart: always
    environment:
      http_proxy: 
      https_proxy: 
      no_proxy: 

  postgres:
    image: awx_postgres_current
    container_name: awx_postgres
    restart: always
    volumes:
      - /opt/awx/pgsql_db:/var/lib/postgresql/data:Z
    environment:
      POSTGRES_USER: awx
      POSTGRES_PASSWORD: aZKX3FzQ7RdIfGGM
      POSTGRES_DB: awx
      PGDATA: /var/lib/postgresql/data/pgdata
      http_proxy: 
      https_proxy: 
      no_proxy: 

После этого переходим в папку c файликом docker-compose.yml и запускаем наши контейнеры:

cd /opt/awx/awxcompose/ 
docker-compose up -d

После запуска остановим контейнеры и перезагрузимся, чтобы убедиться, что они нормально стартуют:

docker stop $(docker ps -a -q)
sudo reboot
Enter your comment. Wiki syntax is allowed:
 
  • linux_faq/docker_migrate_to_another_host.txt
  • Last modified: 2019/08/21 07:00
  • by admin