我需要针对多个正在运行的容器运行命令。例如,假设我的应用程序在收到代码更新后需要针对数据库运行数据结构更新。为此,我们需要运行docker build <project_dir> -t latest
,然后docker stop; docker rm; docker run
运行。在此阶段,我们可以假设我们已经更新了容器的核心代码,但我们仍然需要使用应用程序自己的工具运行该数据库更新。
本质上,我需要某种方法来获取正在运行的容器列表,按某些条件进行筛选,并使用 Ansible 注册这些容器 ID。然后,我们针对每个容器运行命令。
像这样:
- 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 容器列表的任务,以便我可以使用 或 将命令应用于列表中的每个docker exec
容器docker run
?
令人惊奇的是,网上关于此事的资料很少。
答案1
给出以下示例输出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
中间的任务,以比较有列表和没有列表时寄存器中存储的数据。遍历寄存器的结果(容器 ID)并使用模块
docker_container
运行操作(command
参数)。您可以在调用中使用links
和。查看在线文档volumes_from
docker_container
模块了解详情。