【问题标题】:Ansible: How do I execute tasks in ansible playbook in parallel with some time gapAnsible:如何在有时间间隔的情况下并行执行 ansible playbook 中的任务
【发布时间】:2019-11-28 14:13:47
【问题描述】:

让我试着解释一下我的需求:

作为我们应用程序常规部署的一部分,我们有一个 SQL 脚本(它将更改表、添加表或更新等),例如,它需要在一个区域的 3 个模式和另一个区域的 5 个模式上运行。应用程序在 AWS 中,数据库是 Arora db(RDS)- MySQL。此架构可能需要 30 分钟到 3 小时之间的任何时间。

此 SQL 脚本需要并行运行,每次架构运行之间有 2 分钟的延迟。

这是我到目前为止所取得的成就:

  1. 具有 DB 详细信息的文件 - dbdata.yml
---

conn_details:
    - { host: localhost, user: root, password: "Password1!" }
    - { host: localhost, user: root, password: "Password1!" }
  1. 剧本:
- hosts: localhost

  vars:
    script_file: "{{ path }}"
  vars_files:
    - dbdata.yml
  tasks:
  - name: shell command to execute script in parallel
    shell: |
      sleep 30s
      "mysql -h {{ item.host }} -u {{ item.user }} -p{{ item.password }} < {{ script_file }} >> /usr/local/testscript.log"
    with_items: "{{ conn_details }}"
    register: sql_query_output
    async: 600
    poll: 0

  - name: Wait for sql execution to finish
    async_status:
      jid: "{{ item.ansible_job_id }}"
    register: _jobs
    until: _jobs.finished
    delay: 20  # Check every 20 seconds. Adjust as you like.
    retries: 10
    with_items: "{{ sql_query_output.results }}"

第一部分 - 并行执行脚本,这还包括每次执行前 30 秒的时间间隔。

第二部分 - 从注册输出中选择 ansible 作业 id 并检查作业是否完成。

请注意:在包含 30 秒睡眠之前,此剧本运行良好。

我们在执行时有以下错误输出:

ansible-playbook parallel_local.yml --extra-vars "path=RDS_script.sql"
 [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'


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

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************
ok: [localhost]

TASK [sample command- ansible-playbook my_sqldeploy.yml --extra-vars "path=/home/NICEONDEMAND/bsahu/RDS_create_user1.sql"] ****************************************************************************************
changed: [localhost] => (item={u'host': u'localhost', u'password': u'Password1!', u'user': u'root'})
changed: [localhost] => (item={u'host': u'localhost', u'password': u'Password1!', u'user': u'root'})

TASK [Wait for creation to finish] ********************************************************************************************************************************************************************************
FAILED - RETRYING: Wait for creation to finish (10 retries left).
FAILED - RETRYING: Wait for creation to finish (9 retries left).
failed: [localhost] (item={'ansible_loop_var': u'item', u'ansible_job_id': u'591787538842.77844', 'item': {u'host': u'localhost', u'password': u'Password1!', u'user': u'root'}, u'started': 1, 'changed': True, 'failed': False, u'finished': 0, u'results_file': u'/root/.ansible_async/591787538842.77844'}) => {"ansible_job_id": "591787538842.77844", "ansible_loop_var": "item", "attempts": 3, "changed": true, "cmd": "sleep 30s\n\"mysql -h localhost -u root -pPassword1! < RDS_script.sql >> /usr/local/testscript.log\"\n", "delta": "0:00:30.073191", "end": "2019-11-28 17:01:57.632285", "finished": 1, "item": {"ansible_job_id": "591787538842.77844", "ansible_loop_var": "item", "changed": true, "failed": false, "finished": 0, "item": {"host": "localhost", "password": "Password1!", "user": "root"}, "results_file": "/root/.ansible_async/591787538842.77844", "started": 1}, "msg": "non-zero return code", "rc": 127, "start": "2019-11-28 17:01:27.559094", "stderr": "/bin/sh: line 1: mysql -h localhost -u root -pPassword1! < RDS_script.sql >> /usr/local/testscript.log: No such file or directory", "stderr_lines": ["/bin/sh: line 1: mysql -h localhost -u root -pPassword1! < RDS_script.sql >> /usr/local/testscript.log: No such file or directory"], "stdout": "", "stdout_lines": []}
failed: [localhost] (item={'ansible_loop_var': u'item', u'ansible_job_id': u'999397686792.77873', 'item': {u'host': u'localhost', u'password': u'Password1!', u'user': u'root'}, u'started': 1, 'changed': True, 'failed': False, u'finished': 0, u'results_file': u'/root/.ansible_async/999397686792.77873'}) => {"ansible_job_id": "999397686792.77873", "ansible_loop_var": "item", "attempts": 1, "changed": true, "cmd": "sleep 30s\n\"mysql -h localhost -u root -pPassword1! < RDS_script.sql >> /usr/local/testscript.log\"\n", "delta": "0:00:30.120136", "end": "2019-11-28 17:01:58.694713", "finished": 1, "item": {"ansible_job_id": "999397686792.77873", "ansible_loop_var": "item", "changed": true, "failed": false, "finished": 0, "item": {"host": "localhost", "password": "Password1!", "user": "root"}, "results_file": "/root/.ansible_async/999397686792.77873", "started": 1}, "msg": "non-zero return code", "rc": 127, "start": "2019-11-28 17:01:28.574577", "stderr": "/bin/sh: line 1: mysql -h localhost -u root -pPassword1! < RDS_script.sql >> /usr/local/testscript.log: No such file or directory", "stderr_lines": ["/bin/sh: line 1: mysql -h localhost -u root -pPassword1! < RDS_script.sql >> /usr/local/testscript.log: No such file or directory"], "stdout": "", "stdout_lines": []}

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

关于如何克服这个问题的任何建议。提前感谢所有帮助。

【问题讨论】:

  • 能否请您检查执行 playbook 的用户是否有权创建日志文件。似乎剧本正在搜索丢失的日志文件。 ```RDS_script.sql >> /usr/local/testscript.log: 没有这样的文件或目录", "stderr_lines": ["/bin/sh: line 1: mysql -h localhost -u root -pPassword1! > /usr/local/testscript.log: 没有那个文件或目录"]````
  • 嗨,Ravi,我最初确实检查过这个。日志文件已创建。在任务的 2 个部分中,第一个并行运行 shell 命令的部分成功执行。它是验证 ansible 作业是否已完成的第二部分。
  • 你能用调试模式分享剧本执行的输出吗? (只需在剧本执行命令末尾加上“-vvv”并执行)
  • 现在可以工作了。我在外壳部分犯了一个小错误。我需要从执行 sql 文件的 shell 脚本行中删除“”
  • 很高兴听到这个消息

标签: parallel-processing ansible execution


【解决方案1】:

我的错。我犯了一个愚蠢的错误,正在制造麻烦。我需要从执行 sql 文件的行中删除“”。复制下面正确的yaml文件

- hosts: localhost

  vars:
    script_file: "{{ path }}"
  vars_files:
    - dbdata.yml
  tasks:
  - name: sample command- ansible-playbook my_sqldeploy.yml --extra-vars "path=/home/NICEONDEMAND/bsahu/RDS_create_user1.sql"
    shell: |
      sleep 30s
      mysql -h {{ item.host }} -u {{ item.user }} -p{{ item.password }} < {{ script_file }} >> /usr/local/testscript.log
    with_items: "{{ conn_details }}"
    register: sql_query_output
    async: 600
    poll: 0

  - name: Wait for creation to finish
    async_status:
      jid: "{{ item.ansible_job_id }}"
    register: _jobs
    until: _jobs.finished
    delay: 20  # Check every 5 seconds. Adjust as you like.
    retries: 10
    with_items: "{{ sql_query_output.results }}"

感谢大家的帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    相关资源
    最近更新 更多