Docker
在多個 docker 容器中執行 Ansible 命令
我需要對多個正在執行的容器執行命令。例如,假設我的應用程序需要在接收到程式碼更新後對數據庫執行資料結構更新。為此,我們要執行
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:latest
to的正在執行的容器列表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
有趣的部分是:
- 收集給定主機中的容器列表(
localhost
在我的範例中)。我使用了一個簡單的shell
呼叫來awk
過濾輸出。結果儲存在寄存器中。由於輸入是一個列表,這將對如何取回數據產生直接影響,更多內容見下文。取消註釋中間的debug
任務以比較寄存器中儲存的數據有和沒有列表。- 遍歷寄存器的結果(容器 ID)並使用
docker_container
模組執行操作(command
參數)。您可以在呼叫中使用links
和。查看模組的線上文件以獲取詳細資訊。volumes_from``docker_container