有没有办法使用 Puppet 升级操作系统,而无需 exec 运行 yum?

有没有办法使用 Puppet 升级操作系统,而无需 exec 运行 yum?

我们将在下周将 RHEL 6.5 机器升级到 RHEL 6.6。我知道如何使用 Puppet 创建存储库,但除了使用exec运行之外yum -y update,有没有办法告诉 Puppet 将操作系统升级(或保留)到某个版本?例如,说明它应该更改系统以达到或保持以下标准:

operatingsystem => RedHat
operatingsystemmajrelease => 6
operatingsystemrelease => 6.6

答案1

TL;DR 这不是一个好主意。手动更新,或使用其他形式的自动化。

为什么这是个坏主意

我认为你根本不应该走这条路。

一般来说,使用 Puppet 确保操作系统更新已成功完成的想法是合理的,至少从学术角度来看是这样。Puppet 的目标是让您定义一个状态,并处理达到此状态的具体细节。

话虽如此,Puppet 需要一种(虚构的)distro类型,以便您可以指定

# pseudo code! Do not try at home or at all!
distro {
    'CentOS',
        version => '6.6';
}

您可以想象继续实现这种类型,并能够尝试执行同步操作以从当前版本转换为您所请求的版本。

然而,这样的过程可能极其复杂,并且几乎有无限的失败和系统损坏的可能性(无论是做错还是根本做错)。因此,它实际上并不适合任何形式的自动化。

具体到 Puppet,您可能希望向您的distro类型/提供程序添加逻辑,以便从各种奇怪的状态中恢复并实现干净的状态。光是想到这样的努力就让我头晕目眩。

什么会减少痛苦

编写一个 shell 脚本。如果机器数量太多,无法批量执行cssh(我可能会对几百个节点以下的机器执行此操作),请创建一个简单的包装器,它可以满足您的所有需求。使用 Puppet 部署它,是的,exec如果您希望 Puppet 触发更新,请使用资源。考虑

exec { 'echo /my/update/script | at now+10min': }

这样该进程就不是完成所有工作的实例puppet agent的父进程了。这可能会带来灾难性的后果。yum

yum尽管如此,如果可行的话,我还是会手动启动命令。

答案2

我同意通过 puppet 升级操作系统似乎很容易出错,而且最终结果难以预测。但如果您遵循以下三条规则,情况就并非如此:

  1. 以最高程度的标准化来管理机器,包括操作系统配置。要实现这一点,您必须严格通过 puppet 来管理它们。
    没有宠物,只有牛!
  2. 您至少有一个测试阶段。
  3. 您的部署机制确保您测试的精确的傀儡代码在下一阶段运行。
  4. 升级本身必须是傀儡运行的最后一步。
  5. 正如前面所讨论的,必要的重启命令不能是 puppet 进程的父进程。否则 puppet 运行至少会以错误结束。

我使用以下 puppet 代码将 ubuntu 机器从 12 升级到 14:

class os_upgrade {  
   # Script for automatic reboot after the puppet run
   file {'/tmp/reboot_after_puppetrun.sh' :
     content => "watch -g ls -l ${::puppet_vardir}/state;nohup /sbin/reboot\n",
     mode    => '0755',
   }  
   # Unattended upgrade
   exec { 'do-release-upgrade' :
     command   => '/usr/bin/do-release-upgrade -f DistUpgradeViewNonInteractive -m server',
     logoutput => true,
     onlyif    => "test $::operatingsystemrelease != '14.04'",
     notify    => Exec['reboot_after_upgrade'],
     timeout   => 1800,
   }  
   # Trigger the reboot as a background job to avoid puppet parentship
   exec { 'reboot_after_upgrade' :
     command     => "/usr/bin/nohup /tmp/reboot_after_puppetrun.sh&",
     refreshonly => true,
   }
}

为了满足第 4 点,您必须定义一个阶段并确保上述类别的归属正确。

site.pp

stage {'post': subscribe => Stage['main']}
node 'your_machine' {
  class { 'os_upgrade' :
    stage => 'post',
  }

相关内容