Puppet Exec资源异常:指定用户执行命令失败排查求助
问题分析与解决方案
问题描述
我正在为Cassandra编写Puppet类,通过Exec资源统一集群配置。修改拓扑策略后需要重建keyspace,但第三个repairkeyspace的Exec资源总是以root(非指定的someuser)身份执行,前两个Exec则能正常以someuser执行。尝试调整notify等配置均无效。
代码片段
class ogone_cassandra::alter_keyspace () { # lint:ignore:140chars exec { 'system_auth': path => '/usr/bin', provider => shell, user => 'someuser', group => 'cassandra', command => "cqlsh --ssl -u someuser -p $PSW --execute \"ALTER KEYSPACE system_auth WITH REPLICATION = {'class' : 'NetworkTopologyStrategy', 'par1' : 2, 'par2' : 2, 'ams1' : 1};\"", unless => "nodetool --ssl -u someuser -pw $PSW describecluster | grep -e 'system_auth -> Replication class: NetworkTopologyStrategy' 2>/dev/null", require => Exec['::cassandra::schema connection test'], notify => Exec['repairkeyspace'], } exec { 'system_distributed': path => '/usr/bin', provider => shell, user => 'someuser', group => 'cassandra', command => "cqlsh --ssl -u someuser -p $PSW --execute \"ALTER KEYSPACE system_distributed WITH REPLICATION = {'class' : 'NetworkTopologyStrategy', 'par1' : 2, 'par2' : 2, 'ams1' : 1};\"", unless => "nodetool --ssl -u someuser -pw $PSW describecluster | grep -e 'system_distributed -> Replication class: NetworkTopologyStrategy' 2>/dev/null", require => Exec['::cassandra::schema connection test'], notify => Exec['repairkeyspace'], } # lint:endignore exec { 'repairkeyspace': path => '/usr/bin', provider => shell, user => 'someuser', group => 'cassandra', command => 'nodetool --ssl -u someuser -pw $PSW repair --full', refreshonly => true, } }
可能原因及解决办法
1. 同名资源冲突
检查整个Puppet代码库中是否存在其他Exec['repairkeyspace']定义。Puppet中同名资源会被后定义的覆盖,如果其他地方的repairkeyspace没有指定user和group,就会默认以root执行。
- 解决办法:重命名当前的
repairkeyspace资源(比如改为cassandra_repair_keyspaces),确保全局唯一;或者删除/修改其他冲突的资源定义。
2. Puppet版本bug(refreshonly触发时忽略用户参数)
部分旧版本Puppet(如5.x及更早)在处理refreshonly => true的Exec资源时,当被notify触发执行,可能会忽略user和group参数,默认使用root身份运行。
- 验证方法:临时移除
refreshonly => true,手动触发Puppet运行,观察repairkeyspace是否以someuser执行。如果正常,说明是版本问题。 - 解决办法:
- 升级Puppet到较新版本(推荐6.x及以上);
- 替换
refreshonly为基于标记文件的触发逻辑,比如:
同时在exec { 'repairkeyspace': path => '/usr/bin', provider => shell, user => 'someuser', group => 'cassandra', command => 'nodetool --ssl -u someuser -pw $PSW repair --full && touch /tmp/cassandra_repair_done', onlyif => '[ ! -f /tmp/cassandra_repair_done ]', }system_auth和system_distributed的command末尾添加rm -f /tmp/cassandra_repair_done,确保修改keyspace后触发repair。
3. Shell Provider的环境切换问题
使用provider => shell时,Puppet会调用/bin/sh -c执行命令,可能存在用户环境切换不彻底的情况。
- 解决办法:手动通过
su指定用户执行命令,绕过Puppet的user参数:
注意确保exec { 'repairkeyspace': path => '/usr/bin', provider => shell, command => "su - someuser -c 'nodetool --ssl -u someuser -pw $PSW repair --full'", refreshonly => true, }root用户无需密码即可切换到someuser。
4. 变量作用域问题
$PSW变量可能仅在root的环境中可用,当以someuser执行时无法读取,导致命令失败,但这不会直接导致执行身份变化。不过如果命令执行失败,Puppet可能会有异常行为,建议验证变量是否正确传递:
- 解决办法:将
$PSW定义为类参数,或确保someuser的环境中能获取到该变量;或者使用Hiera存储敏感信息并引用。
内容的提问来源于stack exchange,提问作者altheron_crust
相关产品推荐
相关产品推荐

