Executando um comando Ansible em vários contêineres docker

5

Eu preciso executar um comando contra vários contêineres em execução. Por exemplo, digamos que meu aplicativo precise executar uma atualização de estrutura de dados em relação a um banco de dados depois de receber atualizações de código. Para fazer isso, queremos executar docker build <project_dir> -t latest e, em seguida, docker stop; docker rm; docker run . Neste estágio, podemos supor que atualizamos o código principal do contêiner, mas ainda precisamos executar a atualização desse banco de dados usando o próprio conjunto de ferramentas do aplicativo.

Essencialmente, preciso de uma maneira de obter uma lista de contêineres em execução, filtrados por alguns critérios e registrar esses IDs de contêiner com Ansible. Então, para cada contêiner, executamos o comando.

Assim:

- name: Get list of running containers
  docker:
      image: my-image:latest
      state: running
      register: container_ids

Esta tarefa armazenaria a lista de contêineres em execução que usam my-image:latest to container_ids . Então nós executamos o comando:

- name: Exec the database update
  cmd: "docker exec -it {{ item }} my-app-db-update.sh"
  with: container_ids

Como realmente não queremos usar contêineres ativos para esse tipo de operação, a melhor opção seria iniciar um novo contêiner de uso único agindo nos mesmos dados:

- 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

O acima é apenas pseudo-código - não será executado. Como eu realizo a tarefa de armazenar uma lista de contêineres do Docker em execução que atendem a determinados critérios, para que eu possa aplicar um comando a cada contêiner na lista usando docker exec ou docker run ?

Há surpreendentemente pouco sobre isso on-line.

    
por DMCoding 04.12.2016 / 03:08

1 resposta

6

Dado o seguinte exemplo de saída de 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

Este manual fornecerá uma ideia de como capturar os dados de que você precisa e como executar ações repetidas na lista fornecida. É um exemplo muito simples e você terá que adaptá-lo às suas necessidades. Isso é de propósito:

---
- 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

As partes interessantes são:

  1. Reúna a lista de contêineres em um determinado host ( localhost no meu exemplo). Eu usei uma invocação simples de shell para poder usar awk para filtrar a saída. O resultado é armazenado em um registrador. Como a entrada é uma lista, isso terá uma conseqüência direta sobre como recuperar os dados, mais abaixo. Descomente a tarefa debug entre comparar os dados armazenados no registro com e sem uma lista.

  2. Itere os resultados do registro (ID do contêiner) e use o módulo docker_container para executar uma ação ( command parameter). Você pode usar links e volumes_from na sua invocação de docker_container . Verifique a documentação on-line do módulo para obter detalhes.

por 05.12.2016 / 23:54