Ansible 挂起处理程序中的操作,但可以正常处理任务中的操作(重新加载 pf)

Ansible hangs on action in handler, but works fine with action in task (reloading pf)

我正在尝试重新加载 pf 作为角色的一部分,以便在将新的 pf.conf 复制到系统后配置 FreeBSD 服务器。当我将此步骤作为一项任务作为其自己的剧本的一部分独立执行时,它可以完美运行。但是,当我具有与处理程序完全相同的操作时,ansible 总是在该处理程序执行期间挂起。

成功的玩法:

   - hosts: tag_Name_web ; all ec2 instances tagged with web
     gather_facts: True


   vars:
       ansible_python_interpreter: /usr/local/bin/python2.7
       ansible_become_pass: xxx

   tasks:

      - name: copy pf.conf
        copy:
          src: pf.template
          dest: /etc/pf.conf
        become: yes
        become_method: su

      - name: reload pf
        shell: /sbin/pfctl -f /etc/pf.conf
        become: yes
        become_method: su

      - name: echo
        shell: echo "test"
        become: yes
        become_method: su

(我将回声作为测试包括在内,因为我认为它可能会成功,因为重新加载是该游戏所做的最后一件事,但它运行良好)。

失败的处理程序是:

# handlers file for jail_host
- name: Start iocage
  command: service iocage start

- name: Reload sshd
  service: name=sshd state=reloaded

- name: Reload pf
  shell: "/sbin/pfctl -f /etc/pf.conf"

处理程序肯定会被调用,它开始工作,然后就挂起。 (当我在系统上 运行 pfctl -sa 时,它告诉我新的 pf.conf 实际上已经重新加载了。所以它正在工作,它永远不会返回,因此使其余的 ansible 运行 不会发生)。

下面是处理程序 运行ning 的调试输出,但我没有看到任何我能理解的错误。据我所知没有超时;在我按 Ctrl-C 之前,我让它 运行 了 30 分钟。

RUNNING HANDLER [JoergFiedler.freebsd-jail-host : Reload pf] *******************
Using module file /usr/local/lib/python2.7/site-packages/ansible/modules/core/commands/command.py
<54.244.77.100> ESTABLISH SSH CONNECTION FOR USER: ec2-user
<54.244.77.100> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o 'IdentityFile="/usr/local/etc/ansible/xxx_aws.pem"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=ec2-user -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/ansible-ssh-%h-%p-%r 54.244.77.100 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo ~/.ansible/tmp/ansible-tmp-1487698172.0-93173364920700 `" && echo ansible-tmp-1487698172.0-93173364920700="` echo ~/.ansible/tmp/ansible-tmp-1487698172.0-93173364920700 `" ) && sleep 0'"'"''
<54.244.77.100> PUT /tmp/tmpBrFVdu TO /home/ec2-user/.ansible/tmp/ansible-tmp-1487698172.0-93173364920700/command.py
<54.244.77.100> SSH: EXEC sftp -b - -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o 'IdentityFile="/usr/local/etc/ansible/xxx_aws.pem"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=ec2-user -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/ansible-ssh-%h-%p-%r '[54.244.77.100]'
<54.244.77.100> ESTABLISH SSH CONNECTION FOR USER: ec2-user
<54.244.77.100> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o 'IdentityFile="/usr/local/etc/ansible/xxx_aws.pem"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=ec2-user -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/ansible-ssh-%h-%p-%r 54.244.77.100 '/bin/sh -c '"'"'chmod u+x /home/ec2-user/.ansible/tmp/ansible-tmp-1487698172.0-93173364920700/ /home/ec2-user/.ansible/tmp/ansible-tmp-1487698172.0-93173364920700/command.py && sleep 0'"'"''
<54.244.77.100> ESTABLISH SSH CONNECTION FOR USER: ec2-user
<54.244.77.100> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o 'IdentityFile="/usr/local/etc/ansible/xxx_aws.pem"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=ec2-user -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/ansible-ssh-%h-%p-%r -tt 54.244.77.100 '/bin/sh -c '"'"'su  root -c '"'"'"'"'"'"'"'"'/bin/sh -c '"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'echo BECOME-SUCCESS-cntrcxqxlwicicvwtinmaadrnzzzujfp; /usr/local/bin/python2.7 /home/ec2-user/.ansible/tmp/ansible-tmp-1487698172.0-93173364920700/command.py; rm -rf "/home/ec2-user/.ansible/tmp/ansible-tmp-1487698172.0-93173364920700/" > /dev/null 2>&1'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"''"'"'"'"'"'"'"'"' && sleep 0'"'"''

我也试过很多其他方法重载pf..使用服务模块,使用命令:service pf reload,它们的效果完全一样。我还尝试使处理程序异步,

- name: Reload pf
  shell: "/sbin/pfctl -f /etc/pf.conf"
  async: 1
  poll: 0

没有变化。

有没有人知道为什么我在处理程序中的角色失败了,而直接玩任务却成功了?更重要的是,我怎样才能让处理程序正常工作?

提前致谢!

(我应该注意我使用的是 Ansible 2.2.1)。

也许您的处理程序中需要以下内容?

become: yes
become_method: su

这似乎是 PF 的问题,而不是 ansible 的问题,再试一次你的剧本,但这次在你的 pf.rules 上使用它:

pass all

您确实也可以通过登录实例进行测试,只需 运行:

/sbin/pfctl -Fa -f /etc/pf.conf.all 

其中 /etc/pf.conf.all 包含 pass all,它不应将您注销或您当前的会话应保持活动状态。

可能发生的情况是,您的 pf 规则在应用时是 dropping/flushing 现有连接,因此您的 SSH (ansible) 挂起。