Docker

在多個 docker 容器中執行 Ansible 命令

  • December 5, 2016

我需要對多個正在執行的容器執行命令。例如,假設我的應用程序需要在接收到程式碼更新後對數據庫執行資料結構更新。為此,我們要執行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

此任務將儲存使用my-image:latestto的正在執行的容器列表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

令人驚訝的是,這在網上很少見。

給定以下範例輸出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_from``docker_container

引用自:https://serverfault.com/questions/818611