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