使用Ansible模块运行二进制进程时子进程未启动如何解决
Ansible执行安装程序后子进程未启动问题排查
问题场景
编写自定义Ansible模块实现以下逻辑:
- 下载自定义二进制安装程序
installer_binary - 给安装程序加执行权限后运行,安装程序会自动创建目录,并拉起后台子进程,执行链路为:
./installer_binary ---> testfolder/testbinary --config test.config
目标主机为Ubuntu系统,手动在主机上直接运行installer_binary功能正常,可成功拉起对应二进制进程;但通过Ansible playbook执行时,安装文件可正常提取,testbinary进程始终未启动。
现有实现
自定义模块run_binary.py代码
def add(self): filename = "installer.bin" installer_file = self.download_binary_file(url,filename) self.module.run_command(chmod +x installer_file) self.module.run_command('./' + installer_file) def download_file(self,url,local_filename): # NOTE the stream=True parameter below with requests.get(url, stream=True) as r: r.raise_for_status() with open(local_filename, 'wb') as f: for chunk in r.iter_content(chunk_size=8192): # If you have chunk encoded response uncomment if # and set chunk_size parameter to None. #if chunk: f.write(chunk) return local_filename
Playbook配置playbook.yml
- name: Add Collector hosts: host1 become: true become_user: ubuntu become_method: sudo tasks: - name: Running module test: action: run_binary
执行命令
ansible-playbook playbook.yml
排查步骤与修复方案
按优先级从高到低排查:
- 第一步:捕获安装程序的执行返回与输出,定位显性错误
当前调用module.run_command时没有捕获返回值,安装程序执行报错不会直接暴露。修改调用代码,捕获返回码、标准输出、错误输出,执行失败时直接抛出日志:# 替换为安装文件实际所在目录的绝对路径 install_path = "/home/ubuntu" installer_abs_path = f"{install_path}/{filename}" rc, stdout, stderr = self.module.run_command( f"./{installer_file}", cwd=install_path, # 显式指定工作目录 environ_update={"HOME": "/home/ubuntu"} # 补全必要环境变量 ) if rc != 0: self.module.fail_json( msg="Installer execute failed", rc=rc, stdout=stdout, stderr=stderr ) - 第二步:修复工作目录不匹配问题
手动执行安装程序时,是在安装包所在的目录下运行,程序可以通过相对路径找到资源、创建目录、拉起子进程;但Ansible模块执行时默认工作目录不是安装文件所在目录,未显式指定cwd参数时,相对路径解析会出错,直接导致子进程启动失败。调用run_command时必须显式传入cwd参数,值为安装文件所在目录的绝对路径。 - 第三步:修复会话退出连带杀死子进程的问题
module.run_command执行结束后会关闭对应的进程会话,如果安装程序拉起的子进程没有做标准的守护进程化(双fork脱离会话组),会收到SIGHUP信号被连带杀死。手动执行时如果是交互登录会话,安装程序可能绑定tty会话不会立刻触发信号,但Ansible的非交互执行会话关闭时会直接清理所有子进程。
修复方式是执行安装程序时用setsid让进程脱离当前会话:self.module.run_command(f"setsid ./{installer_file}", cwd=install_path) - 第四步:修复路径与权限问题
当前下载文件、执行文件用的都是相对路径,Ansible执行时的文件落点可能和预期不一致,所有文件操作都要改成绝对路径;另外sudo切换用户时默认不会加载用户全量环境变量,必要时在run_command的environ_update参数里补上程序依赖的PATH、HOME等环境变量。 - 第五步:执行后校验进程状态
安装程序执行完后,可以加一步校验逻辑,调用ps aux | grep testbinary确认进程是否存在,不存在时直接抛出错误方便定位。
内容的提问来源于stack exchange,提问作者Anubhav Singh
相关产品推荐
相关产品推荐

