በአውስትራሊያ ውስጥ ከናጊዮስ ወደ Icinga2 መሰደድ

ሰላም.

እኔ linux sysadmin ነኝ ፣ እ.ኤ.አ. በ 2015 በገለልተኛ የባለሙያ ቪዛ ከሩሲያ ወደ አውስትራሊያ ተዛወርኩ ፣ ግን ጽሑፉ ለአሳማ ትራክተር እንዴት እንደሚጀመር አይሆንም ። ቀድሞውኑ በቂ እንደዚህ ያሉ ጽሑፎች አሉ (ነገር ግን ፍላጎት ካለ, ስለዚህ ጉዳይ እጽፋለሁ), ስለዚህ በአውስትራሊያ ውስጥ እንደ ሊኑክስ-ኦፕስ-መሐንዲስ በሠራሁበት ሥራ እንዴት ከአንድ ሥርዓት ስደት እንደጀመርኩ መናገር እፈልጋለሁ. ለሌላው ክትትል. በተለይ - Nagios => Icinga2.

ጽሑፉ በከፊል ቴክኒካል እና በከፊል ከሰዎች ጋር የመግባባት እና ከባህላዊ እና የአሰራር ዘዴዎች ልዩነት ጋር የተያያዙ ችግሮች ናቸው.

እንደ አለመታደል ሆኖ የ"ኮድ" መለያ የአሻንጉሊት እና የያምል ኮድን አያጎላም, ስለዚህ "plaintext" መጠቀም ነበረብኝ.

በዲሴምበር 21, 2016 ጠዋት ላይ ችግርን የሚያመለክት ምንም ነገር የለም። እኔም እንደተለመደው ሀብርን አንብቤ ባልታወቀ ሰው በስራ ቀን የመጀመሪያ አጋማሽ ላይ ቡና እየጠጣሁ ተደናቅፌያለሁ ይህ ዓምድ.

ናጊዮስ በኩባንያዬ ውስጥ ብቻ ጥቅም ላይ እየዋለ ስለነበር፣ ሁለት ጊዜ ሳላስብ፣ በ Redmine ውስጥ ትኬት ፈጠርኩ እና አገናኙን ወደ አጠቃላይ ውይይት ወረወርኩት፣ ምክንያቱም አስፈላጊ እንደሆነ ስለቆጠርኩት። ውጥኑ በአውስትራሊያ ውስጥም ቢሆን የሚያስቀጣ ነው፣ስለዚህም መሪ መሐንዲሱ ይህን ችግር ስላወቅኩኝ በእኔ ላይ አኑሮታል።

ቅጽበታዊ ገጽ እይታ ከ Redmineበአውስትራሊያ ውስጥ ከናጊዮስ ወደ Icinga2 መሰደድ

በእኛ ክፍል ውስጥ ሀሳባችንን ከመግለፃችን በፊት ፣ ምርጫው ግልፅ ቢሆንም ፣ ቢያንስ አንድ አማራጭ ማቅረብ የተለመደ ነው ፣ ስለሆነም አሁን ምን ዓይነት የክትትል ስርዓቶች አስፈላጊ እንደሆኑ በመፈለግ ጀመርኩ ፣ ምክንያቱም በሩሲያ በመጨረሻው የሥራ ቦታዬ ነበረኝ ። በራሱ በራሱ የተጻፈ ስርዓት ፣ በጣም ጥንታዊ ፣ ግን ግን በጣም የሚሰራ እና ለእሱ የተሰጡትን ሁሉንም ተግባራት የሚያከናውን ነው። ፒቲን፣ ሴንት ፒተርስበርግ ፖሊ ቴክኒክ ዩኒቨርሲቲ እና የሜትሮ ደንብ። አይ፣ የምድር ውስጥ ባቡር ይሳባል። ይህ የግል ነው (የ 11 ዓመታት ሥራ) እና ለተለየ ጽሑፍ ብቁ ነው ፣ ግን አሁን አይደለም።

አሁን ባለሁበት ቦታ በመሠረተ ልማት ውቅር ላይ ለውጦችን ለማድረግ ስለ ሕጎች ትንሽ። አሻንጉሊት፣ ጂትላብ እና መሠረተ ልማትን እንደ ኮድ እንጠቀማለን፣ ስለዚህ፡-

  • በምናባዊ ማሽኖች ላይ ያሉ ፋይሎችን በእጅ በመቀየር በSSH በኩል ምንም አይነት ለውጥ የለም። ለሶስት አመታት ስራ, ለዚህ ብዙ ጊዜ ካፕ ተቀብያለሁ, የመጨረሻው ከሳምንት በፊት ነበር እና የመጨረሻው ጊዜ አይመስለኝም. ደህና ፣ በእውነቱ - በማዋቀር ውስጥ አንድ መስመር ያስተካክሉ ፣ አገልግሎቱን እንደገና ያስጀምሩ እና ችግሩ እንደተፈታ ይመልከቱ - 10 ሰከንዶች። በጊትላብ ውስጥ አዲስ ቅርንጫፍ ይፍጠሩ ፣ ለውጦቹን ይግፉ ፣ r10k በ Puppetmaster ላይ እስኪሰራ ይጠብቁ ፣ Puppet --environment=mybranch ን ያሂዱ እና ሁሉም ነገር እስኪሰራ ድረስ ጥቂት ደቂቃዎችን ይጠብቁ - ቢያንስ 5 ደቂቃዎች።
  • ማንኛቸውም ለውጦች የሚደረጉት የውህደት ጥያቄን በ Gitlab በመፍጠር ነው እና ቢያንስ በአንድ የቡድን አባል መጽደቅ አለበት። በቡድን መሪ ውሳኔ ዋና ለውጦች ሁለት ወይም ሶስት ማፅደቅ ያስፈልጋቸዋል።
  • ሁሉም ለውጦች በአንድ ወይም በሌላ መልኩ ጽሑፋዊ ናቸው (ምክንያቱም የአሻንጉሊት መግለጫዎች፣ ስክሪፕቶች እና ሂራ ዳታዎች ጽሁፍ ስለሆኑ) ሁለትዮሽ በጣም ተስፋ የቆረጡ እና እንደዚህ ያሉ ፋይሎችን ለማጽደቅ ጥሩ ምክንያቶች ያስፈልጋሉ።

ስለዚህ እኔ ያጤንኳቸው አማራጮች፡-

  • ሙኒን - በመሠረተ ልማት ውስጥ ከ 10 በላይ አገልጋዮች ካሉ ፣ አስተዳደሩ ወደ ገሃነም ይቀየራል (ከ ይህ ዓምድ. ለማጣራት ብዙም ፍላጎት ስላልነበረኝ ቃሌን ወሰድኩት)።
  • ዛቢቢክስ - ለረጅም ጊዜ በቅርበት እየተመለከትኩ ነበር ፣ ወደ ሩሲያ ተመልሼ ነበር ፣ ግን ከዚያ ለተግባሮቼ ከባድ ነበር። እዚህ - ፑፕትን እንደ ውቅረት አስተዳዳሪ እና Gitlab እንደ የስሪት ቁጥጥር ስርዓት በመጠቀማቸው ምክንያት መጣል ነበረበት። በዚያን ጊዜ, እኔ እንደተረዳሁት, Zabbix ሁሉንም ውቅር በመረጃ ቋቱ ውስጥ ያከማቻል, እና ስለዚህ አሁን ባለው ሁኔታ ውቅሩን እንዴት ማስተዳደር እና ለውጦችን እንዴት እንደሚከታተል ግልጽ አልነበረም.
  • ፕሮሜቲየስ በዲፓርትመንቱ ውስጥ ባለው ስሜት በመመዘን የምንጨርሰው ነው ፣ ግን በዚያን ጊዜ እኔ አላስተዋውቀውም እና በእውነቱ የሚሰራ ናሙና (የፅንሰ-ሀሳብ ማረጋገጫ) ማሳየት አልቻልኩም ፣ ስለሆነም እምቢ ማለት ነበረብኝ።
  • እንዲሁም የስርዓቱን ሙሉ ለሙሉ ማሻሻያ የሚያስፈልጋቸው ወይም ገና በልጅነታቸው የተተዉ እና በተመሳሳይ ምክንያት ውድቅ የተደረጉ ሌሎች በርካታ አማራጮች ነበሩ።

በመጨረሻ፣ Icinga2 ላይ የተቀመጥኩት በሶስት ምክንያቶች ነው።

1 - ከ Nrpe ጋር ተኳሃኝ (ከናጊዮስ ትእዛዝን የሚያረጋግጥ የደንበኛ አገልግሎት)። ይህ በጣም አስፈላጊ ነበር ፣ ምክንያቱም በዚያን ጊዜ 135 (አሁን በ 2019 165 የሚሆኑት አሉ) በራስ የተፃፉ አገልግሎቶች / ቼኮች ያሏቸው ቨርቹዋል ማሽኖች ነበሩ ፣ እና ይህንን ሁሉ እንደገና ማድረጉ ከባድ ሄሞሮይድስ ይሆናል።
2 - ሁሉም የማዋቀሪያ ፋይሎች ጽሑፍ ናቸው, ይህም ይህን ጉዳይ ለማረም ቀላል ያደርገዋል, የተጨመረውን ወይም የተወገደውን የማየት ችሎታ ያለው የውህደት ጥያቄዎችን ይፍጠሩ.
3 የቀጥታ እና በማደግ ላይ ያለ የOpenSource ፕሮጀክት ነው። እኛ OpenSourceን በጣም እንወዳለን እና ችግሮችን ለመፍታት የፑል ጥያቄዎችን እና ጉዳዮችን በመፍጠር ለእሱ የሚሆን አስተዋፅዖ እናደርጋለን።

ስለዚህ እንሂድ Icinga2.

መጀመሪያ ያጋጠመኝ ነገር የባልደረባዎቼን ቅልጥፍና ነው። ሁሉም ሰው ለ Nagios/Nagios ጥቅም ላይ ይውላል (ምንም እንኳን እዚህም ቢሆን እንዴት እንደሚጠራው መስማማት አልቻሉም) እና የCheckMK በይነገጽ። በicinga ውስጥ ፣ በይነገጹ ሙሉ በሙሉ የተለየ ይመስላል (ይህ የተቀነሰ ነበር) ፣ ግን በትክክል ለማንኛውም ግቤት ማጣሪያዎችን በመጠቀም ማየት የሚፈልጉትን በተለዋዋጭ ማዋቀር ይቻላል (ይህ ተጨማሪ ነበር ፣ ግን በተለይ የታገልኩት)።

ማጣሪያዎችበአውስትራሊያ ውስጥ ከናጊዮስ ወደ Icinga2 መሰደድ

የማሸብለል አሞሌው መጠን ከጥቅል መስክ መጠን ጋር ያለውን ጥምርታ ይገምቱ።

በሁለተኛ ደረጃ ፣ ሁሉም ሰው መላውን መሠረተ ልማት በአንድ ማሳያ ላይ ለማየት ይጠቅማል ፣ ምክንያቱም CheckMk ከበርካታ Nagios አስተናጋጆች ጋር እንዲሰሩ ይፈቅድልዎታል ፣ ግን የ Icinga በይነገጽ እንዴት እንደሆነ አላወቀም (በተጨባጭ አደረገ ፣ ግን ከዚህ በታች ባለው ላይ)። አማራጩ ትሩክ የሚባል ነገር ነበር፣ ነገር ግን ዲዛይኑ ከጠቆመው (እኔ ሳልሆን) በስተቀር በቡድኑ ውስጥ ያሉትን ሁሉ እንዲተፋ አድርጓል።

ወደ እቶን Thruk - የቡድኑ አንድ ውሳኔበአውስትራሊያ ውስጥ ከናጊዮስ ወደ Icinga2 መሰደድ

ከጥቂት ቀናት የሃሳብ ማወዛወዝ በኋላ ፣ በምርት ዞኑ ውስጥ አንድ ዋና አስተናጋጅ እና ሁለት ባሪያዎች - አንዱ በዴቭ / ፈተና እና አንድ የውጭ አስተናጋጅ በሌላ አቅራቢ ውስጥ ሲገኝ የክላስተር ክትትል ሀሳብ አቀረብኩ። አገልግሎቶች ከደንበኛ ወይም ከውጭ ተመልካቾች እይታ. ይህ ውቅር ሁሉንም ችግሮች በአንድ የድር በይነገጽ እንዳየው አስችሎኛል እና በጥሩ ሁኔታ ሰርቷል ፣ ግን አሻንጉሊት ... በአሻንጉሊት ላይ ያለው ችግር ዋና አስተናጋጁ አሁን በስርዓቱ ውስጥ ስላሉት ሁሉም አስተናጋጆች እና አገልግሎቶች / ቼኮች ማወቅ ነበረበት እና ነበረበት። በዞኖች (dev-test፣ staging-prod፣ ext) መካከል ያሰራጫቸው፣ ነገር ግን በIcinga API ለውጦችን መግፋት ሁለት ሰከንዶች ይወስዳል፣ ነገር ግን የሁሉም አስተናጋጆች የአሻንጉሊት ማውጫ ማጠናቀር ሁለት ደቂቃዎችን ይወስዳል። ይህ አሁንም በእኔ ላይ ተወቃሽ እየተደረገ ነው, ምንም እንኳን ሁሉም ነገር እንዴት እንደሚሰራ እና ለምን ብዙ ጊዜ እንደሚወስድ ቀደም ብዬ ብዙ ጊዜ ብገልጽም.

ሦስተኛው - የበረዶ ቅንጣቶች ስብስብ (የበረዶ ቅንጣቶች) - ከአጠቃላይ ስርዓቱ የተበላሹ ነገሮች, ምክንያቱም ልዩ የሆነ ነገር ስላላቸው, አጠቃላይ ደንቦች በእነሱ ላይ አይተገበሩም. በፊት ለፊት ጥቃት ተፈቷል - ጭንቀቶች ካሉ ፣ ግን በእውነቱ ሁሉም ነገር በሥርዓት ነው ፣ ከዚያ በጥልቀት መቆፈር እና ለምን እንደሚያስጠነቅቀኝ ማወቅ አለብን ፣ ምንም እንኳን ባይሆንም። ወይም በተገላቢጦሽ - ለምን Nagios ደነገጠ, ነገር ግን Icinga አይደለም.

አራተኛ፣ ናጊዮስ ከእኔ በፊት ለሦስት ዓመታት ያህል እዚህ ሠርቷል እናም መጀመሪያ ላይ በእኔ አዲስ ፋንግግል ከተሰራው የሂፕስተር ሲስተም የበለጠ በእሱ ላይ እምነት ነበረው ፣ ስለሆነም ኢሲንጋ ድንጋጤን ባነሳ ቁጥር ናጊዮስ በተመሳሳይ ጉዳይ እስኪደሰት ድረስ ማንም ምንም አላደረገም። ግን በጣም አልፎ አልፎ Icinga ከናጊዮስ በፊት እውነተኛ ማንቂያዎችን ሰጠ እና እኔ ይህንን እንደ ከባድ ችግር እቆጥረዋለሁ ፣ ይህም በማጠቃለያ ክፍል ውስጥ እናገራለሁ ።

በዚህ ምክንያት የኮሚሽኑ ሥራ ከ 5 ወራት በላይ ዘግይቷል (እ.ኤ.አ. ሰኔ 28 ቀን 2018 ታቅዶ ነበር ፣ በእውነቱ - ታኅሣሥ 3, 2018) ፣ በዋነኛነት በ‹‹ፔሪቲ ቼክ› ምክንያት - በናጊዮስ ውስጥ ብዙ አገልግሎቶች ሲኖሩ ያ ርኩሰት። ባለፉት ሁለት ዓመታት ውስጥ ማንም ሰው ምንም ነገር ያልሰማው ነገር ግን አሁን ያለምክንያት ይነቅፋሉ እና ለምን በእኔ ፓኔል ውስጥ እንዳልሆኑ ማስረዳት ነበረብኝ እና ወደ Icinga ማከል ነበረብኝ ወደ "ፔርቲቲ ቼክ ተጠናቋል" " (በናጊዮስ ውስጥ ያሉ ሁሉም አገልግሎቶች/ቼኮች በ Icinga ውስጥ ካሉ አገልግሎቶች/ቼኮች ጋር ይዛመዳሉ)

ትግበራ
የመጀመሪያው እንደ የአሻንጉሊት ስታይል ኮድ vs ዳታ ጦርነት ነው። ሁሉም መረጃዎች፣ እዚህ በአጠቃላይ ሁሉም ነገር፣ በሂራ ውስጥ መሆን አለበት እና ሌላ ምንም ነገር የለም። ሁሉም ኮድ በ.pp ፋይሎች ውስጥ ነው። ተለዋዋጮች፣ ማጠቃለያዎች፣ ተግባራት - ሁሉም ነገር ወደ ፒ.ፒ.
በውጤቱም፣ ለኤስ ኤስ ኤል የምስክር ወረቀቶች ጤና እና ትክክለኛነት ክትትል የሚያስፈልጋቸው በርካታ ቨርቹዋል ማሽኖች (በመጻፍ ጊዜ 165) እና 68 የድር መተግበሪያዎች አሉን። ነገር ግን በታሪካዊ ሄሞሮይድ ምክንያት የመተግበሪያ ክትትል መረጃ ከተለየ የጂትላብ ማከማቻ ተወስዷል እና የውሂብ ቅርጸቱ ከፑፕት 3 ጀምሮ አልተቀየረም, ይህም ተጨማሪ የማዋቀር ችግር ይፈጥራል.

የአሻንጉሊት ኮድ ለመተግበሪያዎች፣ ዓይኖችዎን የተላጡ ያድርጉ

define profiles::services::monitoring::docker_apps(
  Hash $app_list,
  Hash $apps_accessible_from,
  Hash $apps_access_list,
  Hash $webhost_defaults,
  Hash $webcheck_defaults,
  Hash $service_overrides,
  Hash $targets,
  Hash $app_checks,
  )
{
#### APPS ####
  $zone = $name
  $app_list.each | String $app_name, Hash $app_data |
  {

    $notify_group = { 'notify_group' => ($webcheck_defaults[$zone]['notify_group'] + pick($app_data['notify_group'], {} )) } # adds notifications for default group (systems) + any group defined in int/pm_docker_apps.eyaml

    $data = merge($webhost_defaults, $apps_accessible_from, $app_data)

    $site_domain = $app_data['site_domain']

    $regexp = pick($app_data['check_regex'], 'html')        # Pick a regex to check

    $check_url = $app_data['check_url'] ? {
      undef   => { 'http_uri' => '/' },
      default => { 'http_uri' => $app_data['check_url'] }
    }

    $check_regex = $regexp ?{
      'absent' => {},
      default  => {'http_expect_body_regex' => $regexp}
    }

    $site_domain.each | String $vhost, Hash $vdata | {        # Split an app by domains if there are two or more
      $vhost_name = {'http_vhost' => $vhost}

      $vars = $data['vars'] + $vhost_name + $check_regex + $check_url

      $web_ipaddress = is_array($vdata['web_ipaddress']) ? {  # Make IP-address an array if it's not, because askizzy has 2 ips and it's an array
        true  => $vdata['web_ipaddress'],
        false => [$vdata['web_ipaddress']],
      }

      $access_from_zones = [$zone] + $apps_access_list[$data['accessible_from']] # Merge default zone (where the app is defined) and extra zones if they exist
      $web_ipaddress.each | String $ip_address | {            # For each IP (if we have multiple)
        $suffix = length($web_ipaddress) ? {                  # If we have more than one - add IP as a suffix to this hostname to avoid duplicating resources
          1       => '',
          default => "_${ip_address}"
        }
        $octets = split($ip_address, '.')
        $ip_tag = "${octets[2]}.${octets[3]}" # Using last octet only causes a collision between nginx-vip 203.15.70.94 and ext. ip 49.255.194.94

        $access_from_zones.each | $zone_prefix |{
          $zone_target = $targets[$zone_prefix]

          $nginx_vip_name = "${zone_prefix}_nginx-vip-${ip_tag}" # If it's a host for ext - prefix becomes 'ext_' (ext_nginx-vip...)
          $nginx_host_vip = {
            $nginx_vip_name => {
              ensure        => present,
              target        => $zone_target,
              address       => $ip_address,
              check_command => 'hostalive',
              groups        => ['nginx_vip',],
            }
          }

          $ssl_vars = $app_checks['ssl']
          $regex_vars = $app_checks['http'] + $vars + $webcheck_defaults[$zone] + $notify_group

          if !defined( Profiles::Services::Monitoring::Host[$nginx_vip_name] ) {
          ensure_resources('profiles::services::monitoring::host', $nginx_host_vip)
          }

          if !defined( Icinga2::Object::Service["${nginx_vip_name}_ssl"] ) {
            icinga2::object::service {"${nginx_vip_name}_ssl":
              ensure         => $data['ensure'],
              assign         => ["host.name == $nginx_vip_name",],
              groups         => ['webchecks',],
              check_command  => 'ssl',
              check_interval => $service_overrides['ssl']['check_interval'],
              target         => $targets['services'],
              apply          => true,
              vars           => $ssl_vars
            }
          }
          if $regexp != 'absent'{
            if !defined(Icinga2::Object::Service["${vhost}${$suffix} regex"]){
              icinga2::object::service {"${vhost}${$suffix} regex":
                ensure          => $data['ensure'],
                assign          => ["match(*_nginx-vip-${ip_tag}, host.name)",],
                groups          => ['webchecks',],
                check_command   => 'http',
                check_interval  => $service_overrides['regex']['check_interval'],
                target          => $targets['services'],
                enable_flapping => true,
                apply           => true,
                vars            => $regex_vars
              }
            }
          }
        }
      }
    }
  }
}

የአስተናጋጆች እና አገልግሎቶች ውቅረት ኮድ እንዲሁ አስፈሪ ይመስላል፡-

ክትትል/config.pp


class profiles::services::monitoring::config(
  Array $default_config,
  Array $hostgroups,
  Hash $hosts = {},
  Hash $host_defaults,
  Hash $services,
  Hash $service_defaults,
  Hash $service_overrides,
  Hash $webcheck_defaults,
  Hash $servicegroups,
  String $servicegroup_target,
  Hash $user_defaults,
  Hash $users,
  Hash $oncall,
  Hash $usergroup_defaults,
  Hash $usergroups,
  Hash $notifications,
  Hash $notification_defaults,
  Hash $notification_commands,
  Hash $timeperiods,
  Hash $webhost_defaults,
  Hash $apps_access_list,
  Hash $check_commands,
  Hash $hosts_api = {},
  Hash $targets = {},
  Hash $host_api_defaults = {},
)
{

  # Profiles::Services::Monitoring::Hostgroup <<| |>> # will be enabled when we move to icinga completely
#### APPS ####
  case $location {
    'int', 'ext': {
      $apps_by_zone = {}
    }
    'pm': {
      $int_apps         = hiera('int_docker_apps')
      $int_app_defaults = hiera('int_docker_app_common')

      $st_apps          = hiera('staging_docker_apps')
      $srs_apps         = hiera('pm_docker_apps_srs')
      $pm_apps          = hiera('pm_docker_apps') + $st_apps + $srs_apps
      $pm_app_defaults  = hiera('pm_docker_app_common')

      $apps_by_zone = {
        'int' => $int_apps,
        'pm'  => $pm_apps,
      }

      $app_access_by_zone = {
        'int' => {'accessible_from' => $int_app_defaults['accessible_from']},
        'pm'  => {'accessible_from' => $pm_app_defaults['accessible_from']},
      }
    }

    default: {
      fail('Please ensure the node has $location fact set (int, pm, ext)')
    }
  }

  file { '/etc/icinga2/conf.d/':
    ensure  => directory,
    recurse => true,
    purge   => true,
    owner   => 'icinga',
    group   => 'icinga',
    mode    => '0750',
    notify  => Service['icinga2'],
  }

  $default_config.each | String $file_name |{
    file {"/etc/icinga2/conf.d/${file_name}":
      ensure => present,
      source => "puppet:///modules/profiles/services/monitoring/default_config/${file_name}",
      owner  => 'icinga',
      group  => 'icinga',
      mode    => '0640',
    }
  }

  $app_checks = {
    'ssl' => $services['webchecks']['checks']['ssl']['vars'],
    'http' => $services['webchecks']['checks']['http_regexp']['vars']
  }

  $apps_by_zone.each | String $zone, Hash $app_list | {
    profiles::services::monitoring::docker_apps{$zone:
      app_list             => $app_list,
      apps_accessible_from => $app_access_by_zone[$zone],
      apps_access_list     => $apps_access_list,
      webhost_defaults     => $webhost_defaults,
      webcheck_defaults    => $webcheck_defaults,
      service_overrides    => $service_overrides,
      targets              => $targets,
      app_checks           => $app_checks,
    }
  }

####    HOSTS    ####

  # Profiles::Services::Monitoring::Host <<| |>> # This is for spaceship invasion when it's ready.
  $hosts_has_large_disks = query_nodes('mountpoints.*.size_bytes >= 1099511627776')

  $hosts.each | String $hostgroup, Hash $list_of_hosts_with_settings | {           # Splitting site lists by hostgroups - docker_host/gluster_host/etc
    $list_of_hosts_in_group = $list_of_hosts_with_settings['hosts']
    $hostgroup_settings     = $list_of_hosts_with_settings['settings']
    $merged_hostgroup_settings = deep_merge($host_defaults, $list_of_hosts_with_settings['settings'])
    $list_of_hosts_in_group.each | String $host_name, Hash $host_settings |{  # Splitting grouplists by hosts
      # Is this host in the array $hosts_has_large_disks ? If so set host.vars.has_large_disks
      if ( $hosts_has_large_disks.reduce(false) | $found, $value| { ( $value =~ "^${host_name}" ) or $found } ) {
        $vars_has_large_disks = { 'has_large_disks' => true }
      } else {
        $vars_has_large_disks = {}
      }
      $host_data = deep_merge($merged_hostgroup_settings, $host_settings)
      $hostgroup_settings_vars = pick($hostgroup_settings['vars'], {})
      $host_settings_vars = pick($host_settings['vars'], {})
      $host_notify_group = delete_undef_values($host_defaults['vars']['notify_group'] + $hostgroup_settings_vars['notify_group'] + $host_settings_vars['notify_group'])
      $host_data_vars = delete_undef_values(deep_merge($host_data['vars'] , {'notify_group' => $host_notify_group}, $vars_has_large_disks)) # Merging vars separately

      $hostgroups = delete_undef_values([$hostgroup] + $host_data['groups'])

      profiles::services::monitoring::host{$host_name:
        ensure             => $host_data['ensure'],
        display_name       => $host_data['display_name'],
        address            => $host_data['address'],
        groups             => $hostgroups,
        target             => $host_data['target'],
        check_command      => $host_data['check_command'],
        check_interval     => $host_data['check_interval'],
        max_check_attempts => $host_data['max_check_attempts'],
        vars               => $host_data_vars,
        template           => $host_data['template'],
      }
    }
  }
  if !empty($hosts_api){                                                                # All hosts managed by API
    $hosts_api.each | String $zone, Hash $hosts_api_zone | {                            # Split api hosts by zones
      $hosts_api_zone.each | String $hostgroup, Hash $list_of_hosts_with_settings | {   # Splitting site lists by hostgroups - docker_host/gluster_host/etc
        $list_of_hosts_in_group = $list_of_hosts_with_settings['hosts']
        $hostgroup_settings     = $list_of_hosts_with_settings['settings']
        $merged_hostgroup_settings = deep_merge($host_api_defaults, $list_of_hosts_with_settings['settings'])
        $list_of_hosts_in_group.each | String $host_name, Hash $host_settings |{        # Splitting grouplists by hosts
          # Is this host in the array $hosts_has_large_disks ? If so set host.vars.has_large_disks
          if ( $hosts_has_large_disks.reduce(false) | $found, $value| { ( $value =~ "^${host_name}" ) or $found } ) {
            $vars_has_large_disks = { 'has_large_disks' => true }
          } else {
            $vars_has_large_disks = {}
          }
          $host_data = deep_merge($merged_hostgroup_settings, $host_settings)
          $hostgroup_settings_vars = pick($hostgroup_settings['vars'], {})

          $host_settings_vars = pick($host_settings['vars'], {})
          $host_api_notify_group = delete_undef_values($host_defaults['vars']['notify_group'] + $hostgroup_settings_vars['notify_group'] + $host_settings_vars['notify_group'])
          $host_data_vars = delete_undef_values(deep_merge($host_data['vars'] , {'notify_group' => $host_api_notify_group}, $vars_has_large_disks))
          $hostgroups = delete_undef_values([$hostgroup] + $host_data['groups'])

          if defined(Profiles::Services::Monitoring::Host[$host_name]){
            $hostname = "${host_name}_from_${zone}"
          }
          else
          {
            $hostname = $host_name
          }
          profiles::services::monitoring::host{$hostname:
            ensure             => $host_data['ensure'],
            display_name       => $host_data['display_name'],
            address            => $host_data['address'],
            groups             => $hostgroups,
            target             => "${host_data['target_base']}/${zone}/hosts.conf",
            check_command      => $host_data['check_command'],
            check_interval     => $host_data['check_interval'],
            max_check_attempts => $host_data['max_check_attempts'],
            vars               => $host_data_vars,
            template           => $host_data['template'],
          }
        }
      }
    }
  }

#### END OF HOSTS ####

####   SERVICES   ####

  $services.each | String $service_group, Hash $s_list |{             # Service_group and list of services in that group
    $service_list = $s_list['checks']                                 # List of actual checks, separately from SG settings
    $service_list.each | String $service_name, Hash $data |{

      $merged_defaults = merge($service_defaults, $s_list['settings']) # global service defaults + service group defaults
      $merged_data = merge($merged_defaults, $data)

      $settings_vars = pick($s_list['settings']['vars'], {})
      $this_service_vars = pick($data['vars'], {})
      $all_service_vars = delete_undef_values($service_defaults['vars'] + $settings_vars + $this_service_vars)

      # If we override default check_timeout, but not nrpe_timeout, make nrpe_timeout the same as check_timeout
      if ( $merged_data['check_timeout'] and ! $this_service_vars['nrpe_timeout'] ) {
        # NB: Icinga will convert 1m to 60 automatically!
        $nrpe = { 'nrpe_timeout' => $merged_data['check_timeout'] }
      } else {
        $nrpe = {}
      }

      # By default we use nrpe and all commands are run via nrpe. So vars.nrpe_command = $service_name is a default value
      # If it's server-side Icinga command - we don't need 'nrpe_command'
      # but there is no harm to have that var and the code is shorter

      if $merged_data['check_command'] == 'nrpe'{
        $check_command = $merged_data['vars']['nrpe_command'] ? {
          undef   => { 'nrpe_command' => $service_name },
          default => { 'nrpe_command' => $merged_data['vars']['nrpe_command'] }
        }
      }else{
        $check_command = {}
      }

      # Assembling $vars from Global Default service settings, servicegroup settings, this particular check settings and let's not forget nrpe settings.
      if $all_service_vars['graphite_template'] {
        $graphite_template = {'check_command' => $all_service_vars['graphite_template']}
      }else{
        $graphite_template = {'check_command' => $service_name}
      }
      $service_notify = [] + pick($settings_vars['notify_group'], []) + pick($this_service_vars['notify_group'], []) # pick is required everywhere, otherwise becomes "The value '' cannot be converted to Numeric"

      $service_notify_group = $service_notify ? {
        []      => $service_defaults['vars']['notify_group'],
        default => $service_notify
      } # Assing default group (systems) if no other groups are defined

      $vars = $all_service_vars + $nrpe + $check_command + $graphite_template + {'notify_group' => $service_notify_group}

      # This needs to be merged separately, because merging it as part of MERGED_DATA overwrites arrays instead of merging them, so we lose some "assign" and "ignore" values

      $assign = delete_undef_values($service_defaults['assign'] + $s_list['settings']['assign'] + $data['assign'])
      $ignore = delete_undef_values($service_defaults['ignore'] + $s_list['settings']['ignore'] + $data['ignore'])

      icinga2::object::service {$service_name:
        ensure             => $merged_data['ensure'],
        apply              => $merged_data['apply'],
        enable_flapping    => $merged_data['enable_flapping'],
        assign             => $assign,
        ignore             => $ignore,
        groups             => [$service_group],
        check_command      => $merged_data['check_command'],
        check_interval     => $merged_data['check_interval'],
        check_timeout      => $merged_data['check_timeout'],
        check_period       => $merged_data['check_period'],
        display_name       => $merged_data['display_name'],
        event_command      => $merged_data['event_command'],
        retry_interval     => $merged_data['retry_interval'],
        max_check_attempts => $merged_data['max_check_attempts'],
        target             => $merged_data['target'],
        vars               => $vars,
        template           => $merged_data['template'],
      }
    }
  }
#### END OF SERVICES ####

#### OTHER BORING STUFF ####

  $servicegroups.each | $servicegroup, $description |{
    icinga2::object::servicegroup{ $servicegroup:
      target       => $servicegroup_target,
      display_name => $description
    }
  }

  $hostgroups.each| String $hostgroup |{
    profiles::services::monitoring::hostgroup { $hostgroup:}
  }

  $notifications.each | String $name, Hash $settings |{

    $assign = pick($notification_defaults['assign'], []) + $settings['assign']
    $ignore = pick($notification_defaults['ignore'], []) + $settings['ignore']

    $merged_settings = $settings + $notification_defaults

    icinga2::object::notification{$name:
      target       => $merged_settings['target'],
      apply        => $merged_settings['apply'],
      apply_target => $merged_settings['apply_target'],
      command      => $merged_settings['command'],
      interval     => $merged_settings['interval'],
      states       => $merged_settings['states'],
      types        => $merged_settings['types'],
      assign       => delete_undef_values($assign),
      ignore       => delete_undef_values($ignore),
      user_groups  => $merged_settings['user_groups'],
      period       => $merged_settings['period'],
      vars         => $merged_settings['vars'],
    }
  }

  # Merging notification settings for users with other settings
  $users_oncall = deep_merge($users, $oncall)
  # Magic. Do not touch.
  create_resources('icinga2::object::user', $users_oncall, $user_defaults)
  create_resources('icinga2::object::usergroup', $usergroups, $usergroup_defaults)
  create_resources('icinga2::object::timeperiod',$timeperiods)
  create_resources('icinga2::object::checkcommand', $check_commands)
  create_resources('icinga2::object::notificationcommand', $notification_commands)

  profiles::services::sudoers { 'icinga_runs_ping_l2':
    ensure            => present,
    sudoersd_template => 'profiles/os/redhat/centos7/sudoers/icinga.erb',
  }

}

አሁንም በዚህ ኑድል ላይ እየሰራሁ እና በተቻለ መጠን እያሻሻልኩ ነው። ሆኖም፣ በHiera ውስጥ ቀላል እና ለመረዳት የሚቻል አገባብ እንድንጠቀም የፈቀደልን ይህ ኮድ ነው፡-

መረጃ

profiles::services::monitoring::config::services:
  perf_checks:
    settings:
      check_interval: '2m'
      assign:
        - 'host.vars.type == linux'
    checks:
      procs: {}
      load: {}
      memory: {}
      disk:
        check_interval: '5m'
        vars:
          notification_period: '24x7'
      disk_iops:
        vars:
          notifications:
            - 'silent'
      cpu:
        vars:
          notifications:
            - 'silent'
      dns_fqdn:
        check_interval: '15m'
        ignore:
          - 'xenserver in host.groups'
        vars:
          notifications:
            - 'silent'
      iftraffic_nrpe:
        vars:
          notifications:
            - 'silent'
  logging:
    settings:
      assign:
        - 'logserver in host.groups'
    checks:
       rsyslog: {}
      nginx_limit_req_other: {}
      nginx_limit_req_s2s: {}
      nginx_limit_req_s2x: {}
      nginx_limit_req_srs: {}
     logstash: {}
      logstash_api:
        vars:
          notifications:
            - 'silent'

ሁሉም ቼኮች በቡድን የተከፋፈሉ ናቸው፣ እያንዳንዱ ቡድን እነዚህን ቼኮች የት እና ለምን ያህል ጊዜ እንደሚያስኬድ፣ ምን አይነት ማሳወቂያዎች እና ለማን እንደሚላክ ነባሪ የእይታ ቅንጅቶች አሉት።

በእያንዳንዱ ቼክ ውስጥ ማንኛውንም አማራጭ መሻር ይችላሉ, እና ይህ ሁሉ በመጨረሻ የሁሉም ቼኮች ነባሪ ቅንብሮችን ይጨምራል. ስለዚህ, እንደዚህ ያሉ ኑድልሎች በ config.pp ውስጥ ተጽፈዋል - ሁሉም ነባሪ ቅንጅቶች ከቡድን ቅንጅቶች ጋር እና ከዚያም ከእያንዳንዱ ግለሰብ ቼክ ጋር ይዋሃዳሉ.

እንዲሁም፣ በጣም አስፈላጊ ለውጥ በቅንብሮች ውስጥ ተግባራትን የመጠቀም ችሎታ ነበር፣ ለምሳሌ፣ http_regexን ለመፈተሽ ወደብ፣ አድራሻ እና ዩአርኤል የመቀየር ተግባር።

http_regexp:
  assign:
    - 'host.vars.http_regex'
    - 'static_sites in host.groups'
  check_command: 'http'
  check_interval: '1m'
  retry_interval: '20s'
  max_check_attempts: 6
  http_port: '{{ if(host.vars.http_port) { return host.vars.http_port } else { return 443 } }}'
  vars:
    notification_period: 'host.vars.notification_period'
    http_vhost: '{{ if(host.vars.http_vhost) { return host.vars.http_vhost } else { return host.name } }}'
    http_ssl: '{{ if(host.vars.http_ssl) { return false } else { return true } }}'
    http_expect_body_regex: 'host.vars.http_regex'
    http_uri: '{{ if(host.vars.http_uri) { return host.vars.http_uri } else { return "/" } }}'
    http_onredirect: 'follow'
    http_warn_time: 8
    http_critical_time: 15
    http_timeout: 30
    http_sni: true

ይህ ማለት - በአስተናጋጁ ፍቺ ውስጥ ተለዋዋጭ ካለ http_port - ተጠቀምበት፣ አለዚያ 443. ለምሳሌ የጃበር ዌብ በይነገጽ በ9090፣ እና ዩኒፊ - 7443 ላይ ይንጠለጠላል።
http_vhost ማለት ዲ ኤን ኤስን ችላ ይበሉ እና አድራሻውን ይውሰዱ።
ዩሪ በአስተናጋጁ ውስጥ ከተገለጸ ፣ ከዚያ ይከተሉት ፣ ካልሆነ “/” ይውሰዱት።

ከ http_ssl ጋር አንድ አስቂኝ ታሪክ ወጣ - ይህ ኢንፌክሽን በፍላጎት ማጥፋት አልፈለገም። በዚህ መስመር ውስጥ ለረጅም ጊዜ ሞኝ ነበርኩ፣ በአስተናጋጁ ፍቺ ውስጥ በተለዋዋጭ ወደ እኔ እስኪገባኝ ድረስ፡-

http_ssl: false

በአገላለጽ ተተካ

if(host.vars.http_ssl) { return false } else { return true }

እንዴት የሐሰት እና በመጨረሻው ላይ ይወጣል

if(false) { return false } else { return true }

ማለትም የኤስኤስኤል ቼክ ሁል ጊዜ ንቁ ነው። አገባብ በመቀየር ተፈትቷል፡-

http_ssl: no

ግኝቶች:

ምርቶች

  • ካለፉት 7-8 ወራት ወይም አንድ ጊዜ ያለፈበት እና ለአደጋ የተጋለጠ በመሆኑ አሁን አንድ ሳይሆን ሁለት የክትትል ስርዓት አለን።
  • የአስተናጋጆች/አገልግሎቶች(ቼኮች) የመረጃ አወቃቀሩ አሁን (በእኔ አስተያየት) የበለጠ ሊነበብ የሚችል እና ለመረዳት የሚቻል ነው። ለሌሎች፣ በጣም ግልጽ ሆኖ አልተገኘም፣ ስለዚህ ሁሉም እንዴት እንደሚሰራ እና የት እንደሚስተካከል ለማስረዳት ሁለት ገጾችን በአካባቢያዊው ዊኪ ላይ ማስገባት ነበረብኝ።
  • ተለዋዋጮችን እና ተግባራትን በመጠቀም ቼኮችን በተለዋዋጭ ማዋቀር ይቻላል ለምሳሌ http_regexp ን ለመፈተሽ የተፈለገውን ስርዓተ-ጥለት፣ የመመለሻ ኮድ፣ ዩአርኤል እና ወደብ በአስተናጋጅ ቅንብሮች ውስጥ ሊዘጋጁ ይችላሉ።
  • ብዙ ፓነሎች (ዳሽቦርዶች) አሉ ፣ ለእያንዳንዳቸው የራስዎን የታዩ ማንቂያዎች ዝርዝር መወሰን እና ይህንን ሁሉ በአሻንጉሊት እና በማዋሃድ ጥያቄዎች ማስተዳደር ይችላሉ።

Cons:

  • የቡድኑ አባላት ቅልጥፍና - ናጊዮስ ሰርቷል፣ ሰርቷል እና ሰርቷል፣ እና ይሄ የእርስዎ ኢሲንጋ ያለማቋረጥ አስቸጋሪ እና ቀርፋፋ ነው። ታሪክን እንዴት ማየት ይቻላል? ኧረ ጉድ ነው፣ አይዘምንም ... (ዋናው ችግር የማንቂያው ታሪክ በራስ-ሰር አለመዘመን ነው፣ በF5 ብቻ)
  • የስርዓት መጨናነቅ - በድር በይነገጽ ውስጥ "ዝማኔ" ላይ ጠቅ ሳደርግ (አሁን አረጋግጥ) - የማስፈጸሚያው ውጤት በማርስ ላይ ባለው የአየር ሁኔታ ላይ የተመሰረተ ነው, በተለይም በአስር ሰኮንዶች የሚፈጅ ውስብስብ አገልግሎቶች. የዚህ ዓይነቱ ውጤት የተለመደ ነው. በአውስትራሊያ ውስጥ ከናጊዮስ ወደ Icinga2 መሰደድ
  • በአጠቃላይ ፣ የሁለት ስርዓቶች ጎን ለጎን የሚሰሩ የግማሽ አመታዊ ስታቲስቲክስ መረጃዎች እንደሚያመለክቱት ናጊዮስ ሁል ጊዜ ከ Icinga በበለጠ ፍጥነት ይሠራ ነበር ፣ እና ይህ በጣም አበሳጨኝ። የሆነ ነገር በጊዜ ቆጣሪዎች የተዘበራረቀ መስሎ ይታየኛል እና በየአምስት ደቂቃው ቼክ በእውነቱ አንድ ጊዜ በ 5:30 ወይም እንደዚህ ያለ ነገር ይሄዳል።
  • አገልግሎቱን በማንኛውም ጊዜ ዳግም ካስጀመሩት (systemctl icinga2 ን እንደገና ካስጀመሩት)፣ በዚያን ጊዜ በሂደት ላይ የነበሩ ሁሉም ቼኮች ወሳኝ ማንቂያ ይፈጥራሉ። በማያ ገጹ ላይ እና ከጎን በኩል ሁሉም ነገር የወደቀ ይመስላል (የተረጋገጠ ስህተት).

በአጠቃላይ ግን ይሰራል.

ምንጭ: hab.com

በDDoS ጥበቃ፣ VPS VDS አገልጋዮች ለጣቢያዎች አስተማማኝ ማስተናገጃ ይግዙ 🔥 አስተማማኝ የድር ጣቢያ ማስተናገጃ በዲዶኤስ ጥበቃ፣ በቪፒኤስ ቪዲኤስ አገልጋዮች ይግዙ | ProHoster