web-dev-qa-db-ja.com

複数の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:latestcontainer_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 execまたはdocker runを使用してリスト内の各コンテナーにコマンドを適用できるように、特定の条件を満たす実行中のDockerコンテナーのリストを保存するタスクをどのように実行しますか?

このオンラインについては驚くほど少ないです。

5
DMCoding

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パラメーター)を実行します。 volumes_fromの呼び出しでlinksおよびdocker_containerを使用できます。詳細は モジュール のオンラインドキュメントを確認してください。

6
dawud