You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WSL Ubuntu 20.04下Ansible service模块启动Apache2失败的排查与解决

问题现象

使用sudo service命令启动Apache2服务可正常运行,但使用Ansible的service模块启动apache2时收到“Service is in unknown state”的错误提示。已将Ansible升级至最新版本,运行环境为WSL Ubuntu 20.04.3 LTS,SSH配置正常,apt、command、shell等其他Ansible ad-hoc命令均可正常运行。

问题根因

问题源于Ansible的service_mgr.py文件中is_systemd_managed_offline(module)方法存在逻辑bug,会让Ansible误判当前服务管理器为systemd,但实际环境使用的是sysv init服务管理器。

原有bug逻辑如下:

if module.get_bin_path('systemctl'):
            # check if /sbin/init is a symlink to systemd
            # on SUSE, /sbin/init may be missing if systemd-sysvinit package is not installed.
            if os.path.islink('/sbin/init') and os.path.basename(os.readlink('/sbin/init')) == 'systemd':
                return True
        return False

WSL Ubuntu 20.04 LTS中默认存在/sbin/init指向systemd的软链接:

/sbin/init -> /lib/systemd/systemd*

正常情况下service_mgr.py的服务管理器检测逻辑如下:

elif collected_facts.get('ansible_system') == 'Linux':
            # FIXME: mv is_systemd_managed
            if self.is_systemd_managed(module=module):
                service_mgr_name = 'systemd'
            elif module.get_bin_path('initctl') and os.path.exists("/etc/init/"):
                service_mgr_name = 'upstart'
            elif os.path.exists('/sbin/openrc'):
                service_mgr_name = 'openrc'
            elif self.is_systemd_managed_offline(module=module):
                service_mgr_name = 'systemd'
            elif os.path.exists('/etc/init.d/'):
                service_mgr_name = 'sysvinit'

        if not service_mgr_name:
            # if we cannot detect, fallback to generic 'service'
            service_mgr_name = 'service'

由于上述软链接存在,Ansible执行到is_systemd_managed_offline对应的elif分支时就会停止判断,不会继续执行后续的sysvinit检测逻辑。可通过命令确认实际服务管理器为sysv init:

$ ps -p 1 -o comm=
init
解决方案

临时规避方案

调用Ansible service模块时添加use参数,强制Ansible使用service而非systemd作为服务管理器即可解决问题。注:该bug仍会导致Ansible setup模块误判当前WSL Ubuntu 20.04.3 LTS的服务管理器为systemd。

源码修复方案

可调整service_mgr.py中elif的判断顺序,将is_systemd_managed_offline分支移到elif列表末尾,将/etc/init.d存在性的判断提前,调整后代码如下:

elif collected_facts.get('ansible_system') == 'Linux':
            # FIXME: mv is_systemd_managed
            if self.is_systemd_managed(module=module):
                service_mgr_name = 'systemd'
            elif module.get_bin_path('initctl') and os.path.exists("/etc/init/"):
                service_mgr_name = 'upstart'
            elif os.path.exists('/sbin/openrc'):
                service_mgr_name = 'openrc'
            elif os.path.exists('/etc/init.d/'):
                service_mgr_name = 'sysvinit'
            elif self.is_systemd_managed_offline(module=module):
                service_mgr_name = 'systemd'

建议后续Ansible版本修复该Linux服务管理器检测的逻辑bug,针对WSL Ubuntu等WSL发行版做适配。

内容的提问来源于stack exchange,提问作者fbinliu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 09:09:13