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

DMC*_*ing 5 update containers ansible docker ansible-playbook

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

本质上,我需要某种方法来获取正在运行的容器列表,按某些条件进行过滤,然后将这些容器 ID 注册到 Ansible。然后对于每个容器,我们运行命令。

像这样:

- name: Get list of running containers
  docker:
      image: my-image:latest
      state: running
      register: container_ids
Run Code Online (Sandbox Code Playgroud)

此任务将存储使用my-image:latestto的正在运行的容器列表container_ids。然后我们执行命令:

- name: Exec the database update
  cmd: "docker exec -it {{ item }} my-app-db-update.sh"
  with: container_ids
Run Code Online (Sandbox Code Playgroud)

由于我们真的不想将活动容器用于此类操作,因此更好的选择是启动一个新的一次性容器来处理相同的数据:

- 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
Run Code Online (Sandbox Code Playgroud)

以上只是伪代码——它实际上不会运行。如何完成存储满足特定条件的正在运行的 docker 容器列表的任务,以便我可以使用docker exec或将命令应用于列表中的每个容器docker run

网上关于这方面的内容出乎意料地很少。

daw*_*wud 6

鉴于以下示例输出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
Run Code Online (Sandbox Code Playgroud)

本剧本将让您了解如何捕获所需的数据以及如何在提供的列表上运行迭代操作。这是一个非常简单的示例,您必须根据自己的需要进行调整。这是故意的:

---
- 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
Run Code Online (Sandbox Code Playgroud)

有趣的部分是:

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

  2. 迭代寄存器的结果(容器 ID)并使用docker_container模块运行操作(command参数)。您可以在调用中使用links和。有关详细信息,请查看模块的在线文档。volumes_fromdocker_container