1.3. 示例:自动扩展应用程序


之前描述的功能也可用于扩展应用程序;例如,一种由一次运行的多个实例提供的动态网页。在这种情况下,可以配置 neutron 来提供 负载平衡即服务, 从而在实例之间平均分配流量。

在以下示例中,编排会再次检查遥测数据,并在检测到高 CPU 使用量时增加实例数量,或者在 CPU 使用量低于集合值时减少实例数量。

  1. 创建描述 负载均衡器 环境属性的模板。在 /etc/heat/templates/lb-env.yaml 中输入以下值:

    heat_template_version: 2014-10-16
    description: A load-balancer server
    parameters:
      image:
        type: string
        description: Image used for servers
      key_name:
        type: string
        description: SSH key to connect to the servers
      flavor:
        type: string
        description: flavor used by the servers
      pool_id:
        type: string
        description: Pool to contact
      user_data:
        type: string
        description: Server user_data
      metadata:
        type: json
      network:
        type: string
        description: Network used by the server
    
    resources:
      server:
        type: OS::Nova::Server
        properties:
          flavor: {get_param: flavor}
          image: {get_param: image}
          key_name: {get_param: key_name}
          metadata: {get_param: metadata}
          user_data: {get_param: user_data}
          networks:
            - port: { get_resource: port }
    
      member:
        type: OS::Neutron::PoolMember
        properties:
          pool_id: {get_param: pool_id}
          address: {get_attr: [server, first_address]}
          protocol_port: 80
    
      port:
        type: OS::Neutron::Port
        properties:
          network: {get_param: network}
          security_groups:
            - base
    
    outputs:
      server_ip:
        description: IP Address of the load-balanced server.
        value: { get_attr: [server, first_address] }
      lb_member:
        description: LB member details.
        value: { get_attr: [member, show] }
    Copy to Clipboard Toggle word wrap
  2. 为要运行 Web 应用的实例创建另一个模板。以下模板会创建一个负载均衡器并使用现有的网络。确保根据您的环境替换参数,并将模板保存到文件中,如 /root/lb-webserver-rhel7.yaml

    heat_template_version: 2014-10-16
    description: AutoScaling RHEL 7 Web Application
    parameters:
      image:
        type: string
        description: Image used for servers
        default: RHEL 7
      key_name:
        type: string
        description: SSH key to connect to the servers
        default: admin
      flavor:
        type: string
        description: flavor used by the web servers
        default: m2.tiny
      network:
        type: string
        description: Network used by the server
        default: private
      subnet_id:
        type: string
        description: subnet on which the load balancer will be located
        default: 9daa6b7d-e647-482a-b387-dd5f855b88ef
      external_network_id:
        type: string
        description: UUID of a Neutron external network
        default: db17c885-77fa-45e8-8647-dbb132517960
    
    resources:
      webserver:
        type: OS::Heat::AutoScalingGroup
        properties:
          min_size: 1
          max_size: 3
          cooldown: 60
          desired_capacity: 1
          resource:
            type: file:///etc/heat/templates/lb-env.yaml
            properties:
              flavor: {get_param: flavor}
              image: {get_param: image}
              key_name: {get_param: key_name}
              network: {get_param: network}
              pool_id: {get_resource: pool}
              metadata: {"metering.stack": {get_param: "OS::stack_id"}}
              user_data:
                str_replace:
                  template: |
                    #!/bin/bash -v
    
                    yum -y install httpd php
                    systemctl enable httpd
                    systemctl start httpd
                    cat <<EOF > /var/www/html/hostname.php
                    <?php echo "Hello, My name is " . php_uname('n'); ?>
                    EOF
                  params:
                    hostip: 192.168.122.70
                    fqdn: sat6.example.com
                    shortname: sat6
    
      web_server_scaleup_policy:
        type: OS::Heat::ScalingPolicy
        properties:
          adjustment_type: change_in_capacity
          auto_scaling_group_id: {get_resource: webserver}
          cooldown: 60
          scaling_adjustment: 1
    
      web_server_scaledown_policy:
        type: OS::Heat::ScalingPolicy
        properties:
          adjustment_type: change_in_capacity
          auto_scaling_group_id: {get_resource: webserver}
          cooldown: 60
          scaling_adjustment: -1
    
      cpu_alarm_high:
        type: OS::Ceilometer::Alarm
        properties:
          description: Scale-up if the average CPU > 95% for 1 minute
          meter_name: cpu_util
          statistic: avg
          period: 60
          evaluation_periods: 1
          threshold: 95
          alarm_actions:
            - {get_attr: [web_server_scaleup_policy, alarm_url]}
          matching_metadata: {'metadata.user_metadata.stack': {get_param: "OS::stack_id"}}
          comparison_operator: gt
    
      cpu_alarm_low:
        type: OS::Ceilometer::Alarm
        properties:
          description: Scale-down if the average CPU < 15% for 1 minute
          meter_name: cpu_util
          statistic: avg
          period: 60
          evaluation_periods: 1
          threshold: 15
          alarm_actions:
            - {get_attr: [web_server_scaledown_policy, alarm_url]}
          matching_metadata: {'metadata.user_metadata.stack': {get_param: "OS::stack_id"}}
          comparison_operator: lt
    
      monitor:
        type: OS::Neutron::HealthMonitor
        properties:
          type: TCP
          delay: 5
          max_retries: 5
          timeout: 5
    
      pool:
        type: OS::Neutron::Pool
        properties:
          protocol: HTTP
          monitors: [{get_resource: monitor}]
          subnet_id: {get_param: subnet_id}
          lb_method: ROUND_ROBIN
          vip:
            protocol_port: 80
    
      lb:
        type: OS::Neutron::LoadBalancer
        properties:
          protocol_port: 80
          pool_id: {get_resource: pool}
    
      lb_floating:
        type: OS::Neutron::FloatingIP
        properties:
          floating_network_id: {get_param: external_network_id}
          port_id: {get_attr: [pool, vip, port_id]}
    
    outputs:
      scale_up_url:
        description: >
          This URL is the webhook to scale up the autoscaling group.  You
          can invoke the scale-up operation by doing an HTTP POST to this
          URL; no body nor extra headers are needed.
        value: {get_attr: [web_server_scaleup_policy, alarm_url]}
      scale_dn_url:
        description: >
          This URL is the webhook to scale down the autoscaling group.
          You can invoke the scale-down operation by doing an HTTP POST to
          this URL; no body nor extra headers are needed.
        value: {get_attr: [web_server_scaledown_policy, alarm_url]}
      pool_ip_address:
        value: {get_attr: [pool, vip, address]}
        description: The IP address of the load balancing pool
      website_url:
        value:
          str_replace:
            template: http://serviceip/hostname.php
            params:
              serviceip: { get_attr: [lb_floating, floating_ip_address] }
        description: >
          This URL is the "external" URL that can be used to access the
          website.
      ceilometer_query:
        value:
          str_replace:
            template: >
              ceilometer statistics -m cpu_util
              -q metadata.user_metadata.stack=stackval -p 60 -a avg
            params:
              stackval: { get_param: "OS::stack_id" }
        description: >
          This is a Ceilometer query for statistics on the cpu_util meter
          Samples about OS::Nova::Server instances in this stack.  The -q
          parameter selects Samples according to the subject's metadata.
          When a VM's metadata includes an item of the form metering.X=Y,
          the corresponding Ceilometer resource has a metadata item of the
          form user_metadata.X=Y and samples about resources so tagged can
          be queried with a Ceilometer query term of the form
          metadata.user_metadata.X=Y.  In this case the nested stacks give
          their VMs metadata that is passed as a nested stack parameter,
          and this stack passes a metadata of the form metering.stack=Y,
          where Y is this stack's ID.
    Copy to Clipboard Toggle word wrap
  3. 更新遥测集合间隔。默认情况下,Telemetry 每 10 分钟轮询实例,以进行 CPU 数据。在本例中,将 /etc/ceilometer/pipeline.yaml 中的间隔更改为 60 秒:

    - name: cpu_source
    interval: 60
    meters:
    - "cpu"
    sinks:
    - cpu_sink
    Copy to Clipboard Toggle word wrap
    注意

    不建议在生产环境中使用 60 秒的轮询周期,因为更高的轮询间隔可能会导致 control plane 的负载增加。

  4. 重启所有 OpenStack 服务以应用更新的 Telemetry 设置:

    # openstack-service restart
    Copy to Clipboard Toggle word wrap
    注意

    此步骤将导致 OpenStack 部署简单中断。

  5. 运行 编配脚本。这将构建环境,并使用模板来部署实例:

    # heat stack-create webfarm -f /root/lb-webserver-rhel7.yaml
    Copy to Clipboard Toggle word wrap

    /root/lb-webserver-rhel7.yaml 替换为实际路径和文件名。

您可以在 Dashboard 的 Orchestration Stacks Webfarm 下监控堆栈的创建。创建堆栈后,您会看到多个有用的信息,特别是:

  • 用于触发手动扩展或缩减事件的 URL。
  • 浮动 IP 地址,即网站的 IP 地址。
  • Telemetry 命令显示整个堆栈的 CPU 负载,您可以使用它来检查扩展是否按预期工作。

这是页面在 Dashboard 中是什么样子:

heat stack output

打开 Network Load Balancers 来查看负载均衡器:

load balancer

单击 Members。此页面显示负载平衡池的成员;它们是网站流量可以分发到的实例。请注意,在创建了对应的实例并且安装和配置了 Apache 之前,成员将没有 Active 状态。

当 web 服务器启动时,实例将显示为负载均衡器的活动成员:

load balancer member active

现在,您可以通过 http://IP/hostname.php 访问 Web 应用。您可以看到类似如下的输出:

Hello, My name is we-zrwm-t4ezkpx34gxu-qbg5d7dqbc4j-server-mzdvigk2jugl
Copy to Clipboard Toggle word wrap

现在,您可以通过从仪表板中的堆栈概述运行 Telemetry 命令来查看堆栈的 CPU 性能数据。该命令类似如下:

# ceilometer statistics -m cpu_util -q metadata.user_metadata.stack=8f86c3d5-15cf-4a64-b9e8-70215498c046 -p 60 -a avg
Copy to Clipboard Toggle word wrap

1.3.1. 测试自动扩展应用程序

要手动触发应用程序扩展,请在 仪表板中使用来自堆栈概述的 REST 扩展 URL,或者通过在初始部署实例上运行资源密集型命令来生成负载。

  • 要使用 REST API,您需要一个能够执行 HTTP POST 请求的工具,如 REST Easy Firefox add oncurl。复制 扩展 URL,并将其粘贴到 REST Easy 表单中:

    scale up

    或者将其用作 curl 命令行中的参数:

    $ curl -X POST "scale-up URL"
    Copy to Clipboard Toggle word wrap
  • 为人为生成负载,请为实例分配一个浮动 IP,使用 SSH 登录该实例,再运行 命令,使 CPU 处于忙碌状态。例如:

    $ dd if=/dev/zero of=/dev/null &
    Copy to Clipboard Toggle word wrap
    重要

    检查 CPU 用量是否超过 95%,例如使用 top 命令。如果 CPU 使用率不够高,请多次并行运行 dd 命令,或使用其它方法保持 CPU 忙碌。

下一次 Telemetry 从堆栈收集 CPU 数据时,扩展事件将在 Orchestration Stacks Webfarm Events 触发并出现。将创建一个新的 Web 服务器实例,并添加到负载平衡器中。完成此操作后,实例就会变为活动状态,您会注意到网站 URL 通过负载均衡器路由到堆栈中的两个实例。

注意

创建可能需要几分钟时间,因为实例必须初始化、安装和配置 Apache,以及部署的应用程序。这由 HAProxy 监控,确保在实例上可用该网站标记为 active。

这是在创建新实例时,负载均衡池的成员列表是什么样子:

scale up load balancer

重要

在决定是否创建额外的实例被创建时,将考虑 heat 堆栈中的实例的平均 CPU 使用量。由于第二个实例很可能具有正常的 CPU 使用量,因此它将平衡第一个实例。但是,如果第二个实例变得忙碌,并且第一个实例的平均 CPU 使用量超过 95%,则将创建另一个(third)实例。

1.3.2. 自动缩放故障应用程序

这与 第 1.2.2 节 “自动缩放实例” 类似,当堆栈的平均 CPU 使用量低于预定义的值时,会触发 scale-down 策略,在 第 1.3.1 节 “测试自动扩展应用程序” 中描述的示例中为 15%。另外,通过这种方式从堆栈中删除实例时,也会从负载平衡器中自动移除它。然后,网站流量会在实例的其余部分中自动分发。

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat