Ansible: команда, связанная с docker, не работает внутри playbook, но работает сразу после запуска - PullRequest
1 голос
/ 26 мая 2019

У меня в playbook следующая задача:

- name: install pg_stat_statements extension in the postgres container
  shell: docker exec octopus_postgres_{{ group_id }} /bin/bash -c 'psql -h localhost -U postgres -p 5433 -c "CREATE EXTENSION pg_stat_statements;"' #  && service postgres restart')"
  async: 10
  poll: 0

Как только я запускаю playbook, эта задача, кажется, успешно выполнена, но если я проверю базу данных postgres - в ней нет никаких изменений.Задача на самом деле не сработала.

Если я запускаю вышеупомянутую команду вручную на хосте через bash, все работает нормально, а база данных обновляется, например:

docker exec octopus_postgres_iaa /bin/bash -c 'psql -h localhost -U postgres -p 5433 -c "CREATE EXTENSION pg_stat_statements;"'

Хотяпытаясь проверить, что не так с задачей, я попробовал следующее:

- name: install pg_stat_statements extension in the postgres container
  shell: docker exec octopus_postgres_{{ group_id }} /bin/bash -c 'touch /1 && psql -h localhost -U postgres -p 5433 -c "CREATE EXTENSION pg_stat_statements;" && touch /2' #  && service postgres restart')"
  async: 10
  poll: 0

Я заметил, что файл /1 действительно был создан внутри контейнера, но файл /2 hasn 't ...

Что не так с командой?

1 Ответ

2 голосов
/ 26 мая 2019

Использование docker exec совсем не здесь.В общем, вы хотите избежать этого для таких задач: если контейнер будет удален и воссоздан, любая локальная настройка, которую вы выполнили с помощью docker exec, будет потеряна.Когда вы пытаетесь внести изменения в какой-либо сервер, используя его API, вы обычно просто вызываете его API, вместо того, чтобы получить корневую оболочку на хосте сервера и затем что-то делать, но этот последний шаг - то, что делает docker exec.

Стандарт postgres image поддерживает помещение фрагментов SQL в каталог /docker-entrypoint-initdb.d на стороне контейнера, который будет обработан при первом запуске контейнера (только).Очень типичное использование - монтировать каталог хост-системы со сценариями инициализации в этом каталоге.В Ansible это может выглядеть так:

- name: create pg_stat_statements extension file
  copy:
    dest: /docker/postgres/initdb/create-stat-statements.sql
    content: |-
      CREATE EXTENSION pg_stat_statements;

- name: start postgres container
  docker_container:
    image: 'postgres:11'
    name: octopus_postgres_{{ group_id }}
    published_ports: ['5433:5432']
    volumes:
      - '/docker/postgres/initdb:/docker-entrypoint-initdb.d'
      - '/docker/postgres/data:/var/lib/postgresql/data'

В качестве альтернативы вы можете управлять базой данных, как любая другая база данных PostgreSQL (локальная, размещенная в облаке, удаленная, ...), используя встроенные инструменты Ansible;в этом случае модуль postgresql_ext для создания расширений.

- name: enable pg_stat_statements PostgreSQL extension
  postgresql_ext:
    name: pg_stat_statements
    port: 5433

С точки зрения вашего первоначального утверждения, вероятно, происходят две вещи.Прежде всего, если вы используете путь docker exec для взаимодействия с контейнером, вам всегда нужно использовать порт, на котором работает сервер, а не какие-либо переназначенные порты из опции docker run -p или ее эквивалентов: в своем утверждении вынеобходимо использовать порт по умолчанию 5432, а не 5433. Во-вторых, поскольку вы запускаете задачу с async: 10, poll: 0, Ansible запускает задачу и сразу же переходит к следующей, даже не проверяя, успешно ли она выполнена (см. АсинхронныйДействия и опрос ), так что вы на самом деле не знаете, была ли успешно выполнена задача docker exec.Я предполагаю, что ничего не происходит, потому что не удается подключиться к базе данных, но вы никогда не увидите эту ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...