【问题标题】:Ansible: docker related command doesn't work inside playbook, but does work once run directlyAnsible:与 docker 相关的命令在 playbook 中不起作用,但一旦直接运行就起作用
【发布时间】:2019-10-12 05:19:11
【问题描述】:

我的剧本中有以下任务:

- 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

一旦我运行剧本,这个任务似乎成功完成,但如果我检查 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还没有...

命令有什么问题?

【问题讨论】:

    标签: bash postgresql docker ansible


    【解决方案1】:

    使用docker exec 根本不合适。通常,您希望在执行以下任务时避免使用它:如果容器被删除并重新创建,您使用 docker exec 完成的任何本地设置都将丢失。当您尝试使用其 API 对某种服务器进行更改时,您通常只需调用其 API,而不是在服务器主机上获取 root shell 然后执行操作,但后一步是 docker exec 所做的.

    standard 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 启动任务并立即转到下一个任务,而无需检查它是否成功(请参阅 Asynchronous Actions and Polling) ,所以你实际上并不知道docker exec 任务是否成功。我的猜测是什么都没有发生,因为它无法连接到数据库,但你永远不会看到这个错误。

    【讨论】:

      猜你喜欢
      • 2014-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-31
      • 1970-01-01
      • 2013-12-09
      相关资源
      最近更新 更多