Остановка всех существующих docker контейнеров с помощью ansible - PullRequest
1 голос
/ 08 мая 2020

Я создаю роль ansible для обновления ОС и конфигурации виртуальных машин, на которых я размещаю различные docker контейнеры.

В начале роли я хочу остановить все docker контейнеров, если есть. Я нашел эту ветку введите здесь описание ссылки , но она немного старше, поэтому я пытаюсь открыть новый вопрос. Надеюсь, что все в порядке.

Самый простой способ - это:

- name: Stop docker containers
  shell: |
    docker stop $(docker ps -aq)

К сожалению, я получаю сообщение об ошибке, если на хосте нет контейнера docker. А работать с ignore_errors: yes, я думаю, было бы не лучшим решением. Я попробовал этот способ

- name: Get info on docker host and list images
  docker_host_info:
    containers: yes
  register: containers_to_stop

- name: Stop docker containers
  shell: |
    docker stop $(docker ps -aq)
  when: containers_to_stop.containers != 0

, но все тот же, что и в первой части. Я получаю сообщение об ошибке, если на хосте нет контейнера docker.

Так же, как и в связанном потоке, я пытаюсь использовать модуль docker_container следующим образом:

- name: Get info on docker host and list images
  docker_host_info:
    containers: yes
  register: containers_to_stop

- name: Stop running docker containers
  docker_container:
    name: '{{ item.Names }}'
    image: '{{ item.Image }}'
    state: stopped
  loop: '{{ containers_to_stop.containers }}'

К сожалению, модуль «docker_host_info» не работает нормально, потому что все мои docker имена контейнеров начинаются с «/». Я отладил это для всех вас:

failed: [app01] (item={u'Status': u'Up 12 minutes', u'Command': u'./replace_props_and_start.sh', u'Names': [u'/image-name'], u'Created': 1588071879, u'Image': u'image-name', u'Ports': [{u'IP': u'0.0.0.0', u'Type': u'tcp', u'PublicPort': 8091, u'PrivatePort': 80}], u'Id': u'ad5b0b3d6d623e2ac1d0a2ead9fbbf8a5ce5bca58492410a31035fd160de149a'}) => {"ansible_loop_var": "item", "changed": false, "item": {"Command": "./replace_props_and_start.sh", "Created": 1588071879, "Id": "ad5b0b3d6d623e2ac1d0a2ead9fbbf8a5ce5bca58492410a31035fd160de149a", "Image": "image-name", "Names": ["/image-name"], "Ports": [{"IP": "0.0.0.0", "PrivatePort": 80, "PublicPort": 8091, "Type": "tcp"}], "Status": "Up 12 minutes"}, "msg": "Error creating container: 400 Client Error: Bad Request (\"Invalid container name (['/image-name']), only [a-zA-Z0-9][a-zA-Z0-9_.-] are allowed\")"}

Итак, мой контейнер называется / image-name, а не image-name в каталоге, который ansible создает для меня. Итак, ошибка очевидна, но как я могу ее исправить?

Может быть, это проблема модуля, и мне нужно от go до ansible разработчиков?

С уважением, Дэвид

Ответы [ 2 ]

4 голосов
/ 08 мая 2020

К сожалению, модуль «docker_host_info» не работает нормально, потому что все мои docker имена контейнеров будут начинаться с «/".

Это не (вся) проблема; проблема в том, что в значении, возвращаемом docker_host_info, names является списком. Присмотритесь к этому сообщению об ошибке:

400 Client Error: Bad Request (\"Invalid container name (['/image-name']), only [a-zA-Z0-9][a-zA-Z0-9_.-] are allowed\")"}

Видите, как вы передаете ['/image-name'] в качестве имени контейнера? Вам нужно будет сделать что-то вроде этого:

- name: Get info on docker host and list images
  docker_host_info:
    containers: yes
  register: containers_to_stop

- name: Stop running docker containers
  docker_container:
    name: '{{ item.Names.0[1:] }}'
    image: '{{ item.Image }}'
    state: stopped
  loop: '{{ containers_to_stop.containers }}'

В приведенном выше коде мы запрашиваем первый элемент в списке Names (item.Names.0), а затем выбираем все но первый символ (поэтому /something становится something).

2 голосов
/ 08 мая 2020

Следующее устройство отлично выполняет свою работу на моем домашнем компьютере. Как указано в документации модуля docker_container , вы можете идентифицировать работающий контейнер, используя его короткую или длинную строку идентификатора как name. Длинное Id ( с заглавной I ) доступно в выводе docker_host_info в списке containers.

---
- hosts: localhost
  gather_facts: false

  tasks:
    - name: Get running containers
      docker_host_info:
        containers: yes
      register: docker_info

    - name: Stop running containers
      docker_container:
        name: "{{ item }}"
        state: stopped
      loop: "{{ docker_info.containers | map(attribute='Id') | list }}"

Демо-запуск :

# Show we have no running containers
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

# Spawn some test containers for demo
$ for i in $(seq 1 5); do docker run -d --rm centos:8 bash -c "while true; do sleep 1; done"; done
a492efab9ec7dace786b610f3b93c335fbb84f041f7954557e971a5cbb0905a0
8cd55145c7cb267b37d2af346571797e283cac75777c531caeb88df7ec2e57d6
f009140260f5daee6efc6fba8dd8f73f9c83e31e7f1e09d48681b0738bc86f50
e7af30b1ade41fbc65b3db8e4146497ee736065103af769331d9df4e8e39b131
643e6831b958e0410bb148aeaec29dfeec6fa2773af5fb286ad74ab0368f2e50

# Make sure containers are running
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
643e6831b958        centos:8            "bash -c 'while true…"   9 seconds ago       Up 7 seconds                            quizzical_allen
e7af30b1ade4        centos:8            "bash -c 'while true…"   10 seconds ago      Up 9 seconds                            frosty_khayyam
f009140260f5        centos:8            "bash -c 'while true…"   12 seconds ago      Up 10 seconds                           ecstatic_ramanujan
8cd55145c7cb        centos:8            "bash -c 'while true…"   14 seconds ago      Up 12 seconds                           focused_sammet
a492efab9ec7        centos:8            "bash -c 'while true…"   15 seconds ago      Up 13 seconds                           agitated_jones

# Stop containers with playbook
$ ansible-playbook test.yml 

PLAY [localhost] **************************************************************************************************************************************************************************************************

TASK [Get running containers] *************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Stop running containers] ************************************************************************************************************************************************************************************
changed: [localhost] => (item=643e6831b958e0410bb148aeaec29dfeec6fa2773af5fb286ad74ab0368f2e50)
changed: [localhost] => (item=e7af30b1ade41fbc65b3db8e4146497ee736065103af769331d9df4e8e39b131)
changed: [localhost] => (item=f009140260f5daee6efc6fba8dd8f73f9c83e31e7f1e09d48681b0738bc86f50)
changed: [localhost] => (item=8cd55145c7cb267b37d2af346571797e283cac75777c531caeb88df7ec2e57d6)
changed: [localhost] => (item=a492efab9ec7dace786b610f3b93c335fbb84f041f7954557e971a5cbb0905a0)

PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

# Verify containers are stopped
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

# Check that playbook succeeds without containers running
$ ansible-playbook test.yml 

PLAY [localhost] **************************************************************************************************************************************************************************************************

TASK [Get running containers] *************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Stop running containers] ************************************************************************************************************************************************************************************

PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...