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

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

我需要针对多个正在运行的容器运行命令。例如,假设我的应用程序在收到代码更新后需要针对数据库运行数据结构更新。为此,我们需要运行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

有趣的部分是:

  1. 收集给定主机中的容器列表(localhost在我的示例中)。我使用了一个简单的shell调用来awk过滤输出。结果存储在寄存器中。由于输入是一个列表,这将直接影响如何检索数据,更多信息见下文。取消注释debug中间的任务,以比较有列表和没有列表时寄存器中存储的数据。

  2. 遍历寄存器的结果(容器 ID)并使用模块docker_container运行操作(command参数)。您可以在调用中使用links和。查看在线文档volumes_fromdocker_container模块了解详情。

相关内容