在多个Docker容器中运行Ansible命令

我需要针对多个正在运行的容器运行一个命令。 例如,假设我的应用程序需要在收到代码更新后针对数据库运行数据结构更新。 为此,我们要运行docker build <project_dir> -t latest ,然后docker stop; docker rm; docker run docker stop; docker rm; docker run docker stop; docker rm; docker run 。 在这个阶段,我们可以假定我们已经更新了容器的核心代码,但是我们仍然需要使用应用程序自己的工具来运行数据库更新。

从本质上讲,我需要一些方法来获取正在运行的容器列表,按照某些条件进行过滤,并将这些容器ID注册到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 

由于我们并不是真的想为这种types的操作使用活动容器,所以更好的select是启动一个新的一次性容器,而这个容器只作用于相同的数据:

 - 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 execdocker 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 

有趣的部分是:

  1. 收集给定主机中的容器列表(本例中为localhost )。 我已经使用了简单的shell调用来使用awk来过滤输出。 结果存储在一个寄存器中。 由于input是一个列表,这将直接导致如何检索数据,下面会详细介绍。 取消注释之间的debug任务,比较存储在寄存器中的数据与没有列表的数据。

  2. 迭代寄存器的结果(容器ID)并使用docker_container模块运行一个操作( command参数)。 您可以在docker_container调用中使用linksvolumes_from 。 查看模块的在线文档以获取详细信息。