繁体   English   中英

Puppet 7. 如何让多个配置文件订阅一些服务,其中单个配置文件由 Puppet 生成

[英]Puppet 7. How to let several profiles subscribe to some service of which the single config file is generated by Puppet

我们在Ubuntu 20.04上遇到了Puppet 7的问题

Attempt to override an already evaluated resource, defined at (file: .../modules/profiles/manifests/php/fpm_check.pp, line: 2), with new values (file: .../modules/profiles/manifests/php/fpm_pool.pp, line: 122)

Attempt to override an already evaluated resource, defined at (file: .../modules/profiles/manifests/datadog_agent/phpfpm.pp, line: 3), with new values (file: .../modules/profiles/manifests/php/fpm_pool.pp, line: 109)

所以,问题在主题中:

如何让多个配置文件订阅某个由 Puppet 生成单个配置文件的服务。

____附加信息:

模块/配置文件/清单/php/fpm_check.pp

class profiles::php::fpm_check() {
  profiles::php::fpm_check_instance{ 'singleton': urls => [] }
}

模块/配置文件/清单/datadog_agent/phpfpm.pp

class profiles::datadog_agent::phpfpm() {
 profiles::datadog_agent::integration_phpfpm {
  'singleton': instances => []
 }
}

模块/配置文件/清单/php/fpm_pool.pp

define profiles::php::fpm_pool(
  $deployroot,
  $short_fqdn,
  $fpm_port,
  $monitor_port,
  $php_value = {},
  $user = 'www-data',
  $group = 'www-data',
  $env_vars = {},
  $use_redis_for_php_sessions = false,
  $dd_apm_disable_integrations = 'guzzle',
  $max_execution_time = undef,
  ){
  require profiles::php::fpm
  require profiles::apache

  $fpm_log_dir = $profiles::php::fpm::log_dir
  $fpm_pool_dir = $profiles::php::fpm::pool_dir
  $fpm_service_name = $profiles::php::fpm::service_name

  if $use_redis_for_php_sessions {
    $redis_key_prefix = "SESSION-${regsubst(upcase($name), '\s+', '-')}:"

    $redis_session_settings = {
      'session.save_handler' => 'redis',
      'session.save_path'    => "'unix:///var/run/twemproxy.sock?timeout=120&prefix=${redis_key_prefix}'",
    }

    $php_value_final = merge($php_value, $redis_session_settings)
  } else {
    $php_value_final = $php_value
  }

  $datadog_env_vars = {
    'DD_TRACE_APP_NAME'        => $title,
    'DD_INTEGRATIONS_DISABLED' => $dd_apm_disable_integrations,
  }

  if $max_execution_time == undef {
    $php_admin_value = {}
  } else {
    $php_admin_value = {
      'max_execution_time' => $max_execution_time,
    }
  }

  phpfpm::pool{ $title:
    listen                  => "127.0.0.1:${fpm_port}",
    pm_max_children         => 150,
    pm_start_servers        => 5,
    pm_min_spare_servers    => 5,
    pm_max_spare_servers    => 10,
    service_name            => $fpm_service_name,
    pool_dir                => $fpm_pool_dir,

    access_log              => "${fpm_log_dir}/\$pool.access.log",
    access_format           => '"%R - [%t] \"%{HTTP_HOST}e\" \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%% %{HTTP_X_REQUEST_ID}e"',
    pm_status_path          => '/fpmstatus/$pool/status',
    ping_path               => '/fpmstatus/$pool/ping',
    ping_response           => 'pong',
    slowlog                 => "${fpm_log_dir}/\$pool.slow.log",
    request_slowlog_timeout => 60,
    php_value               => $php_value_final,
    user                    => $user,
    group                   => $group,
    env                     => merge($env_vars, $datadog_env_vars),
    php_admin_value         => $php_admin_value,
  }

  apache::vhost { "${title}-hystrix":
    manage_docroot               => false,
    docroot                      => '/var/www',
    servername                   => "${title}-hystrix.${short_fqdn}",
    port                         => 90,
    use_port_for_filenames       => true,
    use_servername_for_filenames => true,
    proxy_pass_match             => [
      {
        'path' => '^/$',
        'url'  => "fcgi://localhost:${fpm_port}${deployroot}/www/hystrix/HystrixDashboard.php",
      },
    ],
  }

  include profiles::datadog_agent::phpfpm
  include profiles::datadog_agent::phpapm

  $monitor_path = "/fpmstatus/${title}"
  $monitor_hostname = "${title}-fpm-stats"

  apache::vhost { "${title}-fpm-stats":
    manage_docroot         => false,
    docroot                => '/var/www',
    servername             => $monitor_hostname,
    port                   => $monitor_port,
    use_port_for_filenames => true,
    proxy_pass_match       => [
      {
        'path' => "^${monitor_path}/status$",
        'url'  => "fcgi://localhost:${fpm_port}${monitor_path}/status",
      },
      {
        'path' => "^${monitor_path}/ping$",
        'url'  => "fcgi://localhost:${fpm_port}${monitor_path}/ping",
      },
    ],
  }

  Profiles::Datadog_agent::Integration_phpfpm <| |> {
    instances +> [
      {
        'http_host'  => $monitor_hostname,
        'status_url' => "http://localhost:${monitor_port}${monitor_path}/status",
        'ping_url'   => "http://localhost:${monitor_port}${monitor_path}/ping",
        'tags'       => ["pool:${title}"],
      },
    ],
  }

  include profiles::php::fpm_check

  Profiles::Php::Fpm_check_instance <| |> {
    urls +> [ "http://localhost:${monitor_port}${monitor_path}/ping" ],
  }


  logrotate::rule { "${title}-fpmpool-access":
    path          => "${fpm_log_dir}/${title}.access.log",
    copytruncate  => true,
    mail          => false,
    missingok     => true,
    compress      => true,
    ifempty       => false,
    delaycompress => true,
    rotate        => 12,
    rotate_every  => 'weekly',
    postrotate    => "/usr/lib/php/${fpm_service_name}-reopenlogs",
  }

  logrotate::rule { "${title}-fpmpool-slow":
    path          => "${fpm_log_dir}/${title}.slow.log",
    copytruncate  => true,
    mail          => false,
    missingok     => true,
    compress      => true,
    ifempty       => false,
    delaycompress => true,
    rotate        => 12,
    rotate_every  => 'weekly',
    postrotate    => "/usr/lib/php/${fpm_service_name}-reopenlogs",
  }
}

这个问题围绕着您对已定义(而不是本机)类型的资源的使用,以及您对这些类型实例的属性的覆盖。

当 Puppet 构建目录时,它需要评估每个已定义类型的每个声明实例的主体中的 Puppet 代码,并且必须根据该实例的参数来执行此操作。 Puppet 尝试尽可能晚地推迟这些评估,以允许处理资源属性覆盖,但不一定有明确定义的总顺序,因为对已定义类型资源的评估通常会产生额外资源的声明。

因此,可能会在 Puppet 评估特定资源实例的主体后的某个时间,评估该实例属性的覆盖。 在这种情况下,Puppet 没有特别好的选择。 它无法重新评估受影响的资源,因此它必须继续使用使用与预期不同的参数评估的资源,或者放弃。 它保释而不是冒险错误配置目标机器。

为了使这些情况不太可能发生,请尽量减少对资源覆盖的使用,尤其是跨模块边界。 在这种追求中,它通常有助于

  • 使用 Hiera 和您的数据层次结构进行灵活定制,而不是程序清单代码;
  • 使您定义类型的资源细粒度; 并与之结合
  • 使用多个协同工作的资源,而不是大型的单一资源

或者,覆盖问题仅适用于定义的类型,因此您可以考虑将一些定义的类型转换为自定义(本机)类型。

关于从多个来源对同一个配置文件的贡献,您可能会发现puppetlabs/concat模块是您感兴趣的。 至少,它可以让您更好地理解我所说的细粒度资源和资源协同工作的含义。


单独但相关的是,从您的类命名来看,我认为您打算实现角色和配置文件模式。 在这种情况下,您的个人资料中的逻辑太多了。 配置文件应该聚合组件类,仅此而已。 特别是,配置文件很少适合自己声明资源——这就是组件类的作用。 同样,配置文件通常不应该涉及覆盖资源属性的业务,这是您遇到特殊问题的地方。

相反,首先为您的组件类提供声明正确资源属性所需的类参数,这样就不需要覆盖。 我个人的实践和通常的建议是,在需要自定义类参数值的地方,这是通过基于 Hiera 的数据绑定来完成的。 但是,如果您愿意,您可以通过在配置文件类中使用类似资源的类声明来驱动它(尽管这意味着同一目录中包含的任何其他类都不应声明这些相同的组件类)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM