Я управляю более чем 100 серверами, и у меня есть пакет, который нужно обновить. В настоящее время у меня есть только сценарий оболочки, запускающий for loop
на всех серверах и выполняя команду.
Кто-нибудь знает лучший (или лучший) способ сделать это?
Если у вас более 100 серверов, вам действительно следует изучить систему управления конфигурацией, такую как cfengine, puppet, bcfg2 и т. Д. Хорошо сконфигурированная система сможет очень легко проводить регулярные обновления пакетов, с небольшими затратами или без них. дополнительные скрипты.
Я создал собственное внутреннее репо (что до боли просто):
name=My Repo baseurl=http://path/to/directory/above gpgcheck=0
Теперь вы можете установить RPM из созданного вами каталога.
Обратите внимание, что это решение не имеет встроенной безопасности ... оно не проверяет подписанный статус пакетов. Шаги по настройке подписей gpg несложны и подробно описаны в этом руководстве: http://mindtrove.info/articles/hosting-a-yum-repository/
У нас есть инструмент, разработанный аналогично Александру (написанный на python здесь, на perl на моей предыдущей работе), и этот подход, как правило, работает нормально.
Я видел инструмент, предназначенный именно для такого рода вещей, которые меня заинтересовали, ТакТук но у меня не было достаточно времени, чтобы пристегнуться и начать его использовать. Он разработан с учетом масштабируемости, поэтому, если ваша среда, вероятно, будет продолжать расти, вы можете взглянуть на нее. Капистрано тоже стоит исследовать.
Spacewalk - это исходная FOSS-версия Red Hat Satellite Server. Вы можете попробовать это, если вам нужны более надежные функции, чем может предоставить один скрипт.
Spacewalk: бесплатное управление системами Linux с открытым исходным кодом
Вместо цикла for вы можете выполнять команды параллельно, а затем последовательно собирать выходные данные в нужном вам порядке. Я написал следующий скрипт Ruby и использовал его в течение нескольких лет для массовой установки пакетов, быстрого изменения конфигурации и других задач. Это значительно ускоряет работу:
#!/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, ...). Образ всего кластера обновляется несколько раз в год и каждый раз, когда отказавший устаревший узел перезагружается.