From 887f63f0c4dea1fe421758a981c0d2dd44572cb4 Mon Sep 17 00:00:00 2001 From: danehans Date: Fri, 11 Apr 2014 16:14:38 +0000 Subject: [PATCH] Adds Support for Named HA Previously, only a single Named server was supported. This patch adds support for multiple Named servers (1 master and multiple slaves) for high availability. The patch also includes several fixes for proper operation of the dns_infrastructure_zone functionality. --- README.asciidoc | 24 ++++ configure_origin.pp.named_ha_broker_example | 40 ++++++ manifests/init.pp | 30 +++++ manifests/named.pp | 142 +++++++++++++------- manifests/update_conf_files.pp | 20 ++- templates/dhclient_conf.erb | 4 + templates/named/dynamic-zone.db.erb | 17 ++- templates/named/named.conf.erb | 11 +- templates/named/oo_infrastructure.conf.erb | 9 +- templates/named/oo_infrastructure.db.erb | 15 ++- templates/register_dns.erb | 8 ++ templates/resolv_conf.erb | 8 ++ templates/sysconfig_conf.erb | 8 ++ 13 files changed, 269 insertions(+), 67 deletions(-) create mode 100644 configure_origin.pp.named_ha_broker_example create mode 100644 templates/resolv_conf.erb create mode 100644 templates/sysconfig_conf.erb diff --git a/README.asciidoc b/README.asciidoc index d2a646b6..6a480f05 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -207,9 +207,33 @@ up separately, you are responsible for all necessary DNS entries. ==== named_ip_addr Default: IP of a named instance or current IP if installing on this node. This is used by every node to configure its primary name server. +This is also used by Named slave members to identify the primary +(aka master) Named server when named_ha is set to true. Default: the current IP (at install) +==== named_ha +Set to true to configure Named service high-availability (master/slave). + +Note: named_ha requires at least 2 broker servers for high-availability. + +Default: false + +==== named_members +An array of Named server IP addresses. Requires setting named_ha to true. +The array should start with the Named master IP address, followed by +Named Slave IP address(es). + +Default: undef + +=== named_master +Specifies whether the server is a Named master or slave. Available options +are true for Named master and false for Named slave. + +Note: Requires setting named_ha to true. + +Default: false + ==== bind_key When the nameserver is remote, use this to specify the HMAC-MD5 key for updates. This is the "Key:" field from the .private key file diff --git a/configure_origin.pp.named_ha_broker_example b/configure_origin.pp.named_ha_broker_example new file mode 100644 index 00000000..92bc7c64 --- /dev/null +++ b/configure_origin.pp.named_ha_broker_example @@ -0,0 +1,40 @@ +class { 'openshift_origin' : + # Components to install on this host: + roles => ['broker','named','activemq','datastore'], + + # BIND / named high-availability config + named_ha => true, + named_master => true, # Only 1 named_master is allowed when deploying named_ha + named_members => [, , ], # Array of Named servers + named_ip_addr => '', # Only needed on Named slaves and Node hosts. + # Specifies the Named master IP address + + # BIND / named config + # This is the key for updating the OpenShift BIND server + bind_key => '', + # The domain under which applications should be created. + domain => 'example.com', + # Apps would be named -.example.com + # This also creates hostnames for local components under our domain + register_host_with_named => true, + # Forward requests for other domains (to Google by default) + conf_named_upstream_dns => [''], + + # NTP Servers for OpenShift hosts to sync time + ntp_servers => [' iburst'], + + # The FQDNs of the OpenShift component hosts + broker_hostname => '.example.com', + named_hostname => '.example.com', + datastore_hostname => '.example.com', + activemq_hostname => '.example.com', + + # Auth OpenShift users created with htpasswd tool in /etc/openshift/htpasswd + broker_auth_plugin => 'htpasswd', + # Username and password for initial openshift user + openshift_user1 => 'openshift', + openshift_password1 => 'password', + + #Enable development mode for more verbose logs + development_mode => true, +} diff --git a/manifests/init.pp b/manifests/init.pp index 49e66b8e..bfbbb9d5 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -110,7 +110,26 @@ # [*named_ip_addr*] # Default: IP of a named instance or current IP if installing on this # node. This is used by every node to configure its primary name server. +# This is also used by Named slave members to identify the primary +# (aka master) Named server when named_ha is set to true. # Default: the current IP (at install) +# +# [*named_ha*] +# Default: false +# Set to true to configure Named service high-availability (master/slave). +# Note: named_ha requires at least 2 servers for high-availability. +# +# [*named_members*] +# Default: undef +# An array of Named server IP addresses. The array should start with the +# Named master IP address, followed by Named Slave IP address(es). +# Requires setting named_ha to true. +# +# [*named_master*] +# Default: false +# Specifies whether the server is a Named master or slave. Available options +# are true for Named master and false Named slave. Requires setting named_ha +# to true. # # [*bind_key*] # When the nameserver is remote, use this to specify the HMAC-MD5 key @@ -495,6 +514,9 @@ $activemq_hostname = "activemq.${domain}", $datastore_hostname = "mongodb.${domain}", $named_ip_addr = $ipaddress, + $named_ha = false, + $named_members = undef, + $named_master = false, $bind_key = '', $bind_krb_keytab = '', $bind_krb_principal = '', @@ -578,4 +600,12 @@ } } + if $named_ha and ! $named_members { + fail('named_members parameter is required when setting named_ha to true') + } + + if $named_ha and $named_master == false and $named_ip_addr == $ipaddress { + fail('named_ip_addr parameter must be set to the Named master IP address when named_master is false') + } + } diff --git a/manifests/named.pp b/manifests/named.pp index b37ce637..97889a09 100644 --- a/manifests/named.pp +++ b/manifests/named.pp @@ -17,17 +17,34 @@ include openshift_origin::params package { ['bind', 'bind-utils']: - ensure => present, + ensure => present, require => Class['openshift_origin::install_method'], } - file { 'dynamic zone': - path => "/var/named/dynamic/${openshift_origin::domain}.db", - content => template('openshift_origin/named/dynamic-zone.db.erb'), - owner => 'named', - group => 'named', - mode => '0644', - require => File['/var/named/dynamic'], + if ! $::openshift_origin::named_ha or $::openshift_origin::named_ha and $::openshift_origin::named_master { + file { '/var/named/dynamic': + ensure => directory, + owner => 'named', + group => 'named', + mode => '0750', + require => File['/var/named'], + } + file { 'dynamic zone': + ensure => present, + path => "/var/named/dynamic/${openshift_origin::domain}.db", + content => template('openshift_origin/named/dynamic-zone.db.erb'), + owner => 'named', + group => 'named', + mode => '0644', + require => File['/var/named/dynamic'], + } + exec { 'zone-reload': + path => ['/bin/', '/usr/bin/', '/usr/sbin/'], + command => "rndc freeze ${openshift_origin::domain}; rndc reload ${openshift_origin::domain}; rndc thaw ${openshift_origin::domain}", + refreshonly => true, + subscribe => File['dynamic zone'], + require => [File['/etc/rndc.key'],Service['named']], + } } exec { 'create rndc.key': @@ -58,12 +75,14 @@ require => Package['bind'], } - file { '/var/named/dynamic': - ensure => directory, - owner => 'named', - group => 'named', - mode => '0750', - require => File['/var/named'], + if $::openshift_origin::named_ha and ! $::openshift_origin::named_master { + file { '/var/named/slaves': + ensure => directory, + owner => 'named', + group => 'named', + mode => '0770', + require => File['/var/named'], + } } file { 'named key': @@ -85,16 +104,16 @@ } # create named/adddress mappings for infrastructure hosts - if "${openshift_origin::dns_infrastructure_zone}" != '' { + if $::openshift_origin::dns_infrastructure_zone != '' { file { 'infrastructure host configuration': - path => '/var/named/oo_infrastructure.conf', - owner => 'root', - group => 'named', - mode => '644', + path => '/var/named/oo_infrastructure.conf', + owner => 'root', + group => 'named', + mode => '644', content => template('openshift_origin/named/oo_infrastructure.conf.erb'), - replace => false, - require => File['/var/named'] + notify => Service['named'], + require => File['/var/named'], } file { 'named infrastructure key': @@ -106,25 +125,31 @@ require => File['/var/named'], } - file { 'infrastructure zone contents': - path => "/var/named/dynamic/${openshift_origin::dns_infrastructure_zone}.db", - owner => 'named', - group => 'named', - mode => '664', - content => template('openshift_origin/named/oo_infrastructure.db.erb'), - replace => false, - require => File['infrastructure host configuration'] + if ! $::openshift_origin::named_ha or $::openshift_origin::named_ha and $::openshift_origin::named_master { + file { 'infrastructure zone contents': + path => "/var/named/dynamic/${openshift_origin::dns_infrastructure_zone}.db", + owner => 'named', + group => 'named', + mode => '664', + content => template('openshift_origin/named/oo_infrastructure.db.erb'), + require => File['infrastructure host configuration'], + } + exec { 'infrastructure-zone-reload': + path => ['/bin/', '/usr/bin/', '/usr/sbin/'], + command => "rndc freeze ${openshift_origin::dns_infrastructure_zone}; rndc reload ${openshift_origin::dns_infrastructure_zone}; rndc thaw ${openshift_origin::dns_infrastructure_zone}", + refreshonly => true, + subscribe => File['infrastructure zone contents'], + require => [File['/etc/rndc.key'],Service['named']], + } } - } else { file { 'infrastructure host configuration (empty)': - ensure => present, - replace => false, - path => '/var/named/oo_infrastructure.conf', - owner => 'root', - group => 'named', - mode => '644', + ensure => present, + path => '/var/named/oo_infrastructure.conf', + owner => 'root', + group => 'named', + mode => '644', content => '// no openshift infrastructure zone', require => File['/var/named'] } @@ -141,25 +166,40 @@ protocol => 'udp', } + if $::openshift_origin::named_ha and ! $::openshift_origin::named_master { + $restorecon_files_real = [ + '/etc/rndc.key', + '/var/named/forwarders.conf', + '/etc/named.conf', + '/var/named', + '/var/named/slaves', + 'named key', + 'Named configs', + ] + } else { + $restorecon_files_real = [ + '/etc/rndc.key', + '/var/named/forwarders.conf', + '/etc/named.conf', + '/var/named', + '/var/named/dynamic', + 'dynamic zone', + 'named key', + 'Named configs', + ] + } + exec { 'named restorecon': command => '/sbin/restorecon -rv /etc/rndc.* /etc/named.* /var/named /var/named/forwarders.conf', - require => [ - File['/etc/rndc.key'], - File['/var/named/forwarders.conf'], - File['/etc/named.conf'], - File['/var/named'], - File['/var/named/dynamic'], - File['dynamic zone'], - File['named key'], - File['Named configs'], - Exec['create rndc.key'], - ], + require => [File[$restorecon_files_real],Exec['create rndc.key']], } service { 'named': - ensure => running, - subscribe => File['/etc/named.conf'], - enable => true, - require => Exec['named restorecon'], + ensure => running, + subscribe => File['/etc/named.conf'], + enable => true, + hasstatus => true, + hasrestart => true, + require => Exec['named restorecon'], } } diff --git a/manifests/update_conf_files.pp b/manifests/update_conf_files.pp index 04ac1a48..b63dcb0f 100644 --- a/manifests/update_conf_files.pp +++ b/manifests/update_conf_files.pp @@ -1,10 +1,11 @@ class openshift_origin::update_conf_files { - augeas { 'network-scripts': - context => "/files/etc/sysconfig/network-scripts/ifcfg-${::openshift_origin::conf_node_external_eth_dev}", - changes => [ - 'set PEERDNS no', - "set DNS1 ${::openshift_origin::named_ip_addr}", - ], + file { 'network-scripts': + ensure => present, + path => "/etc/sysconfig/network-scripts/ifcfg-${::openshift_origin::conf_node_external_eth_dev}", + content => template('openshift_origin/sysconfig_conf.erb'), + owner => 'root', + group => 'root', + mode => '0644', } file { 'dhcpclient': @@ -17,6 +18,11 @@ } file { '/etc/resolv.conf': - content => "search ${::openshift_origin::domain}\nnameserver ${::openshift_origin::named_ip_addr}" + ensure => present, + path => '/etc/resolv.conf', + content => template('openshift_origin/resolv_conf.erb'), + owner => 'root', + group => 'root', + mode => '0644', } } diff --git a/templates/dhclient_conf.erb b/templates/dhclient_conf.erb index 114a9e18..7816b715 100644 --- a/templates/dhclient_conf.erb +++ b/templates/dhclient_conf.erb @@ -1,3 +1,7 @@ +<% if scope.lookupvar('::openshift_origin::named_ha') -%> +prepend domain-name-servers <%= scope.lookupvar('::openshift_origin::named_members').join(', ') %>; +<% else -%> prepend domain-name-servers <%= scope.lookupvar('::openshift_origin::named_ip_addr') %>; +<% end -%> supersede host-name "<%= @hostname %>"; supersede domain-name "<%= scope.lookupvar('::openshift_origin::domain') %>"; diff --git a/templates/named/dynamic-zone.db.erb b/templates/named/dynamic-zone.db.erb index 50e2412d..6b823f5f 100644 --- a/templates/named/dynamic-zone.db.erb +++ b/templates/named/dynamic-zone.db.erb @@ -1,13 +1,24 @@ $ORIGIN . $TTL 1800 -<%= scope.lookupvar('::openshift_origin::domain') %> IN SOA ns1.<%= scope.lookupvar('::openshift_origin::domain') %>. hostmaster.<%= scope.lookupvar('::openshift_origin::domain') %>. ( +<%= scope.lookupvar('::openshift_origin::domain') %> IN SOA ns1.<%= scope.lookupvar('::openshift_origin::domain') %>. hostmaster.<%= scope.lookupvar('::openshift_origin::domain') %>. ( 2011112904 ; serial 60 ; refresh (1 minute) 15 ; retry (15 seconds) 1800 ; expire (30 minutes) 10 ; minimum (10 seconds) ) - NS ns1.<%= scope.lookupvar('::openshift_origin::domain') %>. +<% if scope.lookupvar('::openshift_origin::named_ha') then +scope.lookupvar('::openshift_origin::named_members').each_with_index do |named_member, index| -%> + NS ns<%= index + 1%>.<%= scope.lookupvar('::openshift_origin::domain') %>. +<% end -%> +<% end -%> +$ORIGIN <%= scope.lookupvar('::openshift_origin::domain') %>. +<% if scope.lookupvar('::openshift_origin::named_ha') then +scope.lookupvar('::openshift_origin::named_members').each_with_index do |named_member, index| -%> +ns<%= index + 1%> A <%= named_member %> +<% end -%> +<% else -%> + NS ns1.<%= scope.lookupvar('::openshift_origin::domain') %>. $ORIGIN <%= scope.lookupvar('::openshift_origin::domain') %>. ns1 A 127.0.0.1 - +<% end -%> diff --git a/templates/named/named.conf.erb b/templates/named/named.conf.erb index 3048be7b..843c9fb6 100644 --- a/templates/named/named.conf.erb +++ b/templates/named/named.conf.erb @@ -12,6 +12,9 @@ options { dump-file "/var/named/data/cache_dump.db"; statistics-file "/var/named/data/named_stats.txt"; memstatistics-file "/var/named/data/named_mem_stats.txt"; +<% if scope.lookupvar('::openshift_origin::named_ha') and scope.lookupvar('::openshift_origin::named_master') -%> + allow-transfer {<%= scope.lookupvar('::openshift_origin::named_members').join('; ') %>; }; +<% end -%> allow-query { any; }; recursion yes; @@ -43,10 +46,16 @@ include "/etc/named.rfc1912.zones"; include "<%= scope.lookupvar('::openshift_origin::domain') %>.key"; zone "<%= scope.lookupvar('::openshift_origin::domain') %>" IN { +<% if scope.lookupvar('::openshift_origin::named_master') or scope.lookupvar('::openshift_origin::named_ha') == false -%> type master; file "dynamic/<%= scope.lookupvar('::openshift_origin::domain') %>.db"; allow-update { key <%= scope.lookupvar('::openshift_origin::domain') %> ; } ; +<% else -%> + type slave; + file "slaves/<%= scope.lookupvar('::openshift_origin::domain') %>.db"; + masters { <%= scope.lookupvar('::openshift_origin::named_ip_addr') %>; }; +<% end -%> }; // create a place for openshift infrastructure ip/name mapping -include "oo_infrastructure.conf"; \ No newline at end of file +include "oo_infrastructure.conf"; diff --git a/templates/named/oo_infrastructure.conf.erb b/templates/named/oo_infrastructure.conf.erb index 01b2cbe9..fa2a7f97 100644 --- a/templates/named/oo_infrastructure.conf.erb +++ b/templates/named/oo_infrastructure.conf.erb @@ -1,8 +1,15 @@ // define a zone for infrastructure hosts +include "<%= scope.lookupvar('::openshift_origin::dns_infrastructure_zone') %>.key"; + zone "<%= scope.lookupvar('::openshift_origin::dns_infrastructure_zone') %>" IN { +<% if scope.lookupvar('::openshift_origin::named_master') or scope.lookupvar('::openshift_origin::named_ha') == false -%> type master; file "dynamic/<%= scope.lookupvar('::openshift_origin::dns_infrastructure_zone') %>.db"; allow-update { key <%= scope.lookupvar('::openshift_origin::dns_infrastructure_zone') %> ; } ; +<% else -%> + type slave; + file "slaves/<%= scope.lookupvar('::openshift_origin::dns_infrastructure_zone') %>.db"; + masters { <%= scope.lookupvar('::openshift_origin::named_ip_addr') %>; }; +<% end -%> }; - diff --git a/templates/named/oo_infrastructure.db.erb b/templates/named/oo_infrastructure.db.erb index dca16d81..444fe54b 100644 --- a/templates/named/oo_infrastructure.db.erb +++ b/templates/named/oo_infrastructure.db.erb @@ -7,11 +7,18 @@ $TTL 1800 1800 ; expire (30 minutes) 10 ; minimum (10 seconds) ) - NS ns1.<%= scope.lookupvar('::openshift_origin::dns_infrastructure_zone') %>. +<% if scope.lookupvar('::openshift_origin::named_ha') then +scope.lookupvar('::openshift_origin::named_members').each_with_index do |named_member, index| -%> + NS ns<%= index + 1%>.<%= scope.lookupvar('::openshift_origin::dns_infrastructure_zone') %>. +<% end -%> $ORIGIN <%= scope.lookupvar('::openshift_origin::dns_infrastructure_zone') %>. -ns1 IN A <%= scope.lookupvar('::ipaddress') %> - +<% scope.lookupvar('::openshift_origin::named_members').each_with_index do |named_member, index| -%> +ns<%= index + 1%> A <%= named_member %> +<% end -%> +<% else -%> + NS ns1.<%= scope.lookupvar('::openshift_origin::dns_infrastructure_zone') %>. +<% end -%> ;; add the remaining hosts <%- scope.lookupvar('::openshift_origin::dns_infrastructure_names').each do |rr| -%> <%= rr['hostname'].gsub(/\.#{scope.lookupvar('::openshift_origin::dns_infrastructure_zone')}$/, '') -%> IN A <%= rr['ipaddr'] %> -<%- end -%> \ No newline at end of file +<%- end -%> diff --git a/templates/register_dns.erb b/templates/register_dns.erb index 99c0afe5..21e99186 100644 --- a/templates/register_dns.erb +++ b/templates/register_dns.erb @@ -4,3 +4,11 @@ echo update add <%= scope.lookupvar('fqdn') %> 180 A <%= scope.lookupvar('::openshift_origin::node_ip_addr') %> echo send ) | nsupdate -y <%= scope.lookupvar('::openshift_origin::domain') %>:<%= scope.lookupvar('::openshift_origin::bind_key') %> +<% if scope.lookupvar('::openshift_origin::dns_infrastructure_zone') != '' %> +( + echo server <%= scope.lookupvar('::openshift_origin::named_ip_addr') %> + echo update delete <%= @hostname %>.<%= scope.lookupvar('::openshift_origin::dns_infrastructure_zone') %> A + echo update add <%= @hostname %>.<%= scope.lookupvar('::openshift_origin::dns_infrastructure_zone') %> 180 A <%= scope.lookupvar('::openshift_origin::node_ip_addr') %> + echo send +) | nsupdate -y <%= scope.lookupvar('::openshift_origin::dns_infrastructure_zone') %>:<%= scope.lookupvar('::openshift_origin::dns_infrastructure_key') %> +<% end-%> diff --git a/templates/resolv_conf.erb b/templates/resolv_conf.erb new file mode 100644 index 00000000..8762c716 --- /dev/null +++ b/templates/resolv_conf.erb @@ -0,0 +1,8 @@ +search <%= scope.lookupvar('::openshift_origin::domain') %> +<% if scope.lookupvar('::openshift_origin::named_ha') then +scope.lookupvar('::openshift_origin::named_members').each do |named_member| -%> +nameserver <%= named_member %> +<% end -%> +<% else -%> +nameserver <%= scope.lookupvar('::openshift_origin::named_ip_addr') %> +<% end -%> diff --git a/templates/sysconfig_conf.erb b/templates/sysconfig_conf.erb new file mode 100644 index 00000000..ed371b8f --- /dev/null +++ b/templates/sysconfig_conf.erb @@ -0,0 +1,8 @@ +set PEERDNS no +<% if scope.lookupvar('::openshift_origin::named_ha') then +scope.lookupvar('::openshift_origin::named_members').each_with_index do |named_member, index| -%> +set DNS<%= index + 1%> <%= named_member %> +<% end -%> +<% else -%> +set DNS1 <%= scope.lookupvar('::openshift_origin::named_ip_addr') -%> +<% end -%>