Linux 软件包安装

Linux 软件包安装

我管理着 100 多台服务器,有一些软件包需要更新。目前,我只有一个 shell 脚本,for loop在所有服务器上运行并执行命令。

有人知道最好的(或更好的)方法来做到这一点吗?

答案1

如果您运行着 100 多台服务器,那么您真的应该研究一下配置管理系统,例如 cfengine、puppet、bcfg2 等。配置良好的系统能够非常轻松地推出常规软件包升级,几乎不需要或根本不需要额外的脚本。

答案2

我所做的是创建我自己的内部 repo(非常简单):

  1. 创建可访问 Web 的目录
  2. 将 RPM 放在那里
  3. 运行“createrepo ./”
  4. 通过将以下文件添加到您的 /etc/yum.repos.d/ 目录来将您的客户端指向那里:
name=My Repo
baseurl=http://path/to/directory/above
gpgcheck=0

您现在可以从创建的目录安装 RPM。

请注意,此解决方案没有固有的安全性...它不检查软件包的签名状态。设置 gpg 签名的步骤并不难,详细说明如下:http://mindtrove.info/articles/hosting-a-yum-repository/

答案3

我们有一个与 Aleksandr 类似开发的工具(这里是用 python 编写的,我之前的工作是用 perl 编写的),而且这种方法效果很好。

我见过专为此类事情设计的工具,引起了我的兴趣,达督但我还没有时间开始使用它。它的设计考虑到了可扩展性,因此如果您的环境可能会继续增长,您可能需要看看它。Capistrano 也值得研究。

答案4

您可以并行执行命令,然后按所需的顺序依次收集输出,而无需使用 for 循环。我编写了以下 Ruby 脚本,并将其用于大量软件包安装、快速配置更改和其他任务,已经使用多年。它大大加快了速度:

脚本:on-all-nodes-run

#!/usr/bin/ruby

EXCEPT = [] 

require "open3"

SSH_OPTIONS = ["-o PreferredAuthentications=hostbased,gssapi,gssapi-with-mic",
               "-o ForwardX11=no",
               "-o BatchMode=yes",
               "-o SetupTimeOut=5",
               "-o ServerAliveInterval=5",
               "-o ServerAliveCountMax=2"
              ].join(" ")

SSH    = "/usr/bin/ssh #{SSH_OPTIONS}"
MKDIR  = "/bin/mkdir"

raise "give this command at least one argument" if ARGV.size < 1
COMMAND = ARGV[0..-1].join(' ')

output_o = {}
output_e = {}

FORMAT = "%Y-%m-%d_%H-%M-%S_#{(rand * 100).to_i}"

IO_CONNECTIONS_TO_REMOTE_PROCESSES = {}

def on_all_nodes(&block)
  1.upto(32) do |i| 
    next if EXCEPT.include? i
    node = "node#{i.to_s.rjust(2, '0')}"
    block.call(node)
  end
end


# Create processes
on_all_nodes do |node|
  stdin, stdout, stderr = Open3.popen3("#{SSH} #{node} \"#{COMMAND}\"")
  IO_CONNECTIONS_TO_REMOTE_PROCESSES[node] = [stdin, stdout, stderr]
end


has_remote_errors = false

# Collect results
on_all_nodes do |node|
  stdin, stdout, stderr = IO_CONNECTIONS_TO_REMOTE_PROCESSES[node]

  stdin.close

  e_thread = Thread.new do
    while line = stderr.gets
      line.chomp!
      STDERR.puts "#{node} ERROR: #{line}"
      has_remote_errors = true
    end
  end

  o_thread = Thread.new do
    first = true
    while line = stdout.gets
      line.chomp!
      puts "#{node}      : #{line}"
    end
  end

  # Let the threads finish
  t1 = nil
  t2 = nil
  while [t1, t2].include? nil
    if t1.nil?
      t1 = e_thread.join(0.1) # Gives 1/10 of a second to STDERR
    end
    if t2.nil?
      t2 = o_thread.join(0.1) # Give 1/10 of a second to STDOUT
    end
  end

end


exit(1) if has_remote_errors

其他备注

上述脚本依赖于主机的标准命名模式。它是节点01节点02...节点99。如果您的主机名称都不同,那么您可以在 /etc/hosts 中创建统一的别名。

因为您的服务器比我的多,所以您需要调整我的脚本以使用类似以下内容:N001 N002 ... N100

安装软件包后运行检查。我使用 Debian,但在 CentOS/RedHat 系统上,它会是这样的on-all-nodes-run yum info <package-name>

我用在所有节点上运行每个月几次,但某个节点不可避免地会宕机,最终会过期。因此,最重要的是,on-all-nodes-run当有机会重新启动时,我会重新映像节点(SystemImager,可能是 KickStart,...)。整个集群每年都会重新映像几次,每次发生故障的过期节点都会重新启动。

相关内容