Мне нужно запустить команду для нескольких запущенных контейнеров. Например, предположим, что моему приложению необходимо выполнить обновление структуры данных для базы данных после получения обновлений кода. Для этого мы хотим запустить docker build <project_dir> -t latest
, затем docker stop; docker rm; docker run
. На этом этапе мы можем предположить, что обновили основной код контейнера, но нам все еще нужно запустить это обновление базы данных, используя собственные инструменты приложения.
По сути, мне нужен способ получить список запущенных контейнеров, отфильтрованный по некоторым критериям, и зарегистрировать эти идентификаторы контейнеров в Ansible. Затем для каждого контейнера запускаем команду.
Как это:
- name: Get list of running containers
docker:
image: my-image:latest
state: running
register: container_ids
Эта задача будет хранить список запущенных контейнеров, которые используют my-image:latest
к container_ids
. Затем выполняем команду:
- name: Exec the database update
cmd: "docker exec -it {{ item }} my-app-db-update.sh"
with: container_ids
Поскольку на самом деле мы не хотим использовать активные контейнеры для этого типа операций, лучшим вариантом было бы запустить новый одноразовый контейнер, работающий с теми же данными:
- name: Run the database update
cmd: "docker run --rm --volumes-from {{ item }} --link:mydb:db my-app sh -c 'my-app-db-update.sh'"
with: container_ids
Это всего лишь псевдокод - на самом деле он не будет работать. Как мне выполнить задачу по хранению списка запущенных контейнеров докеров, которые соответствуют определенным критериям, чтобы затем я мог применить команду к каждому контейнеру в списке, используя либо docker exec
или docker run
?
В Интернете об этом на удивление мало.
Учитывая следующий пример вывода из docker ps
:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7e21761c9c44 busybox "top" 22 minutes ago Up 22 minutes agitated_yonath
7091d9c7cc56 nginx "nginx -g 'daemon off" 23 minutes ago Up 23 minutes 80/tcp, 443/tcp fervent_blackwell
Эта инструкция даст вам представление о том, как собирать необходимые данные и как выполнять действия, повторяющиеся в предоставленном списке. Это очень простой пример, и вам придется адаптировать его к вашим потребностям. Это специально:
---
- hosts: localhost
gather_facts: no
tasks:
- name: gather list of containers
shell: docker ps | awk '/{{ item }}/{print $1}'
register: list_of_containers
with_items:
- busybox
#- name: debug
# debug: msg="{{ list_of_containers }}"
- name: run action in container(s)
docker_container:
name: temp-container
image: busybox
command: uptime
cleanup: yes
detach: yes
register: result_of_action
with_items:
- list_of_containers.results.stdout_lines
Интересные части:
Соберите список контейнеров на данном хосте (localhost
в моем примере). Я использовал простой shell
вызов, чтобы иметь возможность использовать awk
чтобы отфильтровать вывод. Результат сохраняется в регистре. Поскольку входные данные представляют собой список, это будет иметь прямое влияние на то, как получить данные обратно, подробнее ниже. Раскомментируйте debug
промежуточная задача - сравнить данные, хранящиеся в регистре, со списком и без него.
Перебирайте результаты реестра (идентификатор контейнера) и используйте docker_container
модуль для запуска действия (command
параметр). Ты можешь использовать links
и volumes_from
в твоем docker_container
призыв. Проверьте онлайн-документацию модуль для подробностей.