繁体   English   中英

Ansible:与docker相关的命令在playbook中不起作用,但是一旦直接运行就起作用

[英]Ansible: docker related command doesn't work inside playbook, but does work once run directly

我的剧本中有以下任务:

- 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却没有...

命令有什么问题?

根本不使用docker exec 通常,对于诸如此类的任务,您要避免使用它:如果删除并重新创建了容器,则您使用docker exec完成的所有本地设置都将丢失。 当您尝试使用其API对某种类型的服务器进行更改时,通常只调用其API,而不是在服务器主机上获取root shell然后执行操作,但这是docker exec要做的。

标准的postgres映像支持将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'

另外,您可以使用Ansible的内置工具像其他任何PostgreSQL数据库一样管理该数据库(本地,云托管,远程等)。 在这种情况下,用于创建扩展的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任务成功完成。 我的猜测是什么也没发生,因为它无法连接到数据库,但是您永远不会看到此错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM