使用Terraform实现SAE应用自动弹性

在分布式应用管理中,弹性伸缩是很重要的运维能力,它能够根据实例状态自动增加或减少实例数量,即扩容或缩容,从而提高资源利用率、降低资源成本。本文介绍如何通过Terraform为SAE应用启停弹性策略。

前提条件

  • 安装Terraform。支持Terraform 0.13及以上版本。
  • 配置阿里云账号信息。

    选择一种阿里云认证方式,为Terraform的执行提供认证信息。本文以环境变量认证方式为例:

    export ALICLOUD_ACCESS_KEY="************"
    export ALICLOUD_SECRET_KEY="************"
    export ALICLOUD_REGION="cn-hangzhou"
    说明 为保障数据安全性,建议您按需为RAM用户授予SAE资源的操作权限。具体操作,请参见为RAM用户授权

背景信息

SAE自动弹性伸缩策略包括定时弹性伸缩策略、监控指标弹性伸缩策略和混合弹性伸缩策略。通过Terraform为SAE应用启用弹性策略的实质,是在创建应用时配置alicloud_sae_application_scaling_rule资源。如需停用弹性策略时,您需要同时删除弹性策略和应用。关于如何设置时间周期,请参见使用Crontab表达式

更多信息,请参见alicloud_sae_application_scaling_rule

适用场景

  • 定时弹性策略:适用于资源使用率有周期性规律的应用场景,多用于证券、医疗、政府和教育等行业。
  • 监控指标弹性策略:适用于突发流量和典型周期性流量的应用场景,多用于互联网、游戏和社交平台等行业。
  • 混合弹性策略:适用于兼备资源使用率有周期性规律和有突发流量、典型周期性流量的应用场景,多用于互联网、教育和餐饮等行业。

更多信息,请参见配置弹性伸缩策略

启用定时弹性策略

本示例以在华东1(杭州)地域下创建应用为例,介绍如何通过自定义配置,以镜像方式部署应用并为应用配置一条定时弹性策略。

弹性策略内容如下:周期设为每天,第一段触发点的开始时间为19:35,目标实例数为5个;第二段触发点的开始时间为20:35,目标实例数为2个。则在19:35至20:35之间,SAE依据所设的规则,将该应用的实例数保持为5个,在20:35至次日19:35之间,应用实例数保持为2个。

  1. 创建一个用于存放Terraform资源的项目文件夹,命名为terraform
  2. 执行以下命令,进入项目目录。
    cd terraform
  3. 创建名为main.tf的配置文件。
    内容如下:
    terraform {
      required_providers {
        alicloud = {
          source  = "hashicorp/alicloud"
          version = "~> 1.167.0"
        }
      }
    }
    
    # 命名空间
    resource "alicloud_sae_namespace" "default" {
      namespace_description = var.namespace_description
      namespace_id          = var.namespace_id
      namespace_name        = var.namespace_name
    }
    
    # VPC和安全组
    resource "alicloud_security_group" "sg" {
      name        = var.name
      description = var.description
      vpc_id      = module.vpc.VPC_ID
    }
    
    resource "alicloud_security_group_rule" "sg_rule" {
      type              = "ingress"
      ip_protocol       = "tcp"
      nic_type          = "intranet"
      policy            = "accept"
      port_range        = var.port_range
      priority          = 1
      security_group_id = alicloud_security_group.sg.id
      cidr_ip           = var.cidr_ip
    }
    
    module "vpc" {
      source  = "git::github.com/kubevela-contrib/terraform-modules.git//alibaba/vswitch"
      zone_id = var.zone_id
    }
    
    
    # 应用配置
    resource "alicloud_sae_application" "default" {
      app_name          = var.app_name
      app_description   = var.app_description
      deploy            = true
      image_url         = var.image_url
      namespace_id      = alicloud_sae_namespace.default.id
      vswitch_id        = module.vpc.VSWITCH_ID
      vpc_id            = module.vpc.VPC_ID
      security_group_id = alicloud_security_group.sg.id
      package_type      = var.package_type
      timezone          = "Asia/Beijing"
      replicas          = var.replicas
      cpu               = var.cpu
      memory            = var.memory
    }
    
    # 弹性伸缩策略
    resource "alicloud_sae_application_scaling_rule" "example" {
      app_id              = alicloud_sae_application.default.id
      scaling_rule_name   = "example-value"
      scaling_rule_enable = true
      scaling_rule_type   = "timing"
      scaling_rule_timer {
        begin_date = "2022-04-20"
        end_date   = "2022-05-31"
        period     = "* * *"
        schedules {
          at_time      = "19:35"
          target_replicas = 5
        }
        schedules {
          at_time      = "20:35"
          target_replicas = 2
        }
      }
    }
    
    
    # 命名空间描述
    variable "namespace_description" {
      description = "Namespace Description"
      default     = "a namespace"
    }
    # 命名空间名称
    variable "namespace_name" {
      description = "Namespace Name"
      type = string
    }
    # 命名空间ID
    variable "namespace_id" {
      description = "Namespace ID"
      type = string
    }
    
    output "namespace_id" {
      value = var.namespace_id
      description = "Namespace ID"
    }
    # 安全组名称
    variable "name" {
      default     = "tf"
      description = "The name of the security group rule"
      type        = string
    }
    
    # 安全组描述
    variable "description" {
      default     = "The description of the security group rule"
      description = "The description of the security group rule"
      type        = string
    }
    
    # 端口范围
    variable "port_range" {
      default     = "1/65535"
      description = "The port range of the security group rule"
      type        = string
    }
    
    # CIDR地址
    variable "cidr_ip" {
      description = "cidr blocks used to create a new security group rule"
      type        = string
      default     = "0.0.0.0/0"
    }
    
    # 地域内可用区
    variable "zone_id" {
      description = "Availability Zone ID"
      type        = string
      default     = "cn-hongkong-b"
    }
    
    # 应用名称
    variable "app_name" {
      description = "The name of the application"
      type        = string
    }
    
    # 应用描述
    variable "app_description" {
      default     = "description created by Terraform"
      description = "The description of the application"
      type        = string
    }
    
    # 应用部署方式
    variable "package_type" {
      default     = "Image"
      description = "The package type of the application"
      type        = string
    }
    
    # 实例CPU规格
    variable "cpu" {
      default     = "500"
      description = "The cpu of the application, in unit of millicore"
      type        = string
    }
    
    # 实例内存规格
    variable "memory" {
      default     = "1024"
      description = "The memory of the application, in unit of MB"
      type        = string
    }
    
    # 应用实例数
    variable "replicas" {
      default     = "1"
      description = "The replicas of the application"
      type        = string
    }
    
    # SLB端口
    variable "port" {
      description = "The port of SLB"
      type        = string
      default = "8000"
    }
    
    # 镜像地址
    variable "image_url" {
      description = "The image url of the application, like `registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-slim:0.9`"
      type        = string
    }
    
    output "app_id" {
      description = "The id of the application"
      value       = alicloud_sae_application.default.id
    }
    
    output "app_name" {
      description = "The name of the application"
      value       = var.app_name
    }
  4. 执行以下命令,初始化配置。
    terraform init
  5. 依次执行以下命令,创建应用。
    1. 执行以下命令,部署应用。
      terraform apply
    2. 根据提示依次输入应用的各项信息。
      • app_name:应用名称。输入app-scaling
      • image_url:镜像地址。输入registry.cn-hangzhou.aliyuncs.com/****/****:01
        您可以登录容器镜像服务控制台,在目标实例仓库的基本信息页面查看镜像地址。格式如下:
        registry.<regionId>.aliyuncs.com/<命令空间名称>/<镜像仓库名称>:<镜像版本号>
      • namespace_name:命名空间名称。输入demo
      • namespace_id:命名空间ID。输入cn-hangzhou:demo
      预期输出:
      ...
      
      Plan: 7 to add, 0 to change, 0 to destroy.
      
      Changes to Outputs:
        + app_id       = (known after apply)
        + app_name     = "app-scaling"
        + namespace_id = "cn-hangzhou:demo"
      alicloud_sae_namespace.default: Creating...
      module.vpc.alicloud_vpc.vpc[0]: Creating...
      alicloud_sae_namespace.default: Creation complete after 4s [id=cn-hangzhou:demo]
      module.vpc.alicloud_vpc.vpc[0]: Creation complete after 6s [id=vpc-bp1e2c4vcopwnmnef****]
      ...
      alicloud_sae_application_scaling_rule.example: Creating...
      alicloud_sae_application_scaling_rule.example: Creation complete after 1s [id=f8982c19-0f91-4510-a26a-9644e97c****:example-value]
      
      Apply complete! Resources: 7 added, 0 changed, 0 destroyed.
      
      Outputs:
      
      app_id = "f8982c19-0f91-4510-a26a-9644e97c****"
      app_name = "app-scaling"
      namespace_id = "cn-hangzhou:demo"
    已成功创建启用了弹性定时策略的应用app-scaling。您可以登录SAE控制台,在目标应用基本信息页面的实例部署信息页签查看弹性策略与应用实例的运行状态。

启用监控指标弹性策略

本示例基于配置了定时弹性策略的main.tf文件,仅将资源alicloud_sae_application_scaling_rule的内容从定时弹性策略替换为监控指标弹性策略,其余内容保持不变。具体操作,请参见启用定时弹性策略

示例代码如下:
  • 更新前(定时弹性策略)
    resource "alicloud_sae_application_scaling_rule" "example" {
      app_id              = alicloud_sae_application.default.id
      scaling_rule_name   = "example-value"
      scaling_rule_enable = true
      scaling_rule_type   = "timing"
      scaling_rule_timer {
        begin_date = "2022-04-20"
        end_date   = "2022-05-31"
        period     = "* * *"
        schedules {
          at_time      = "19:35"
          target_replicas = 5
        }
        schedules {
          at_time      = "20:35"
          target_replicas = 2
        }
      }
    }
  • 更新后(监控指标弹性策略)
    resource "alicloud_sae_application_scaling_rule" "metrics" {
      app_id              = alicloud_sae_application.default.id
      scaling_rule_name   = "metric-dev"
      scaling_rule_enable = true
      scaling_rule_type   = "metric"
      scaling_rule_metric {
        max_replicas = 50
        min_replicas = 3
        metrics {
          metric_type                       = "CPU"
          metric_target_average_utilization = 1
        }
        scale_up_rules {
          step                         = 10
          disabled                     = false
          stabilization_window_seconds = 0
        }
        scale_down_rules {
          step                         = 10
          disabled                     = false
          stabilization_window_seconds = 10
        }
      }
    }
    本示例的弹性策略内容如下:当CPU使用率超过1%时扩容,应用最大实例数为50个;当CPU使用率低于1%时缩容,应用最小实例数为3个。
    说明 示例代码为显示测试效果,设置了较低的CPU使用率,您在实际操作过程中可以按需设置合理的参数值。

执行修改后的Terraform资源,应用将启用指标监控弹性策略。您可以登录SAE控制台,在目标应用基本信息页面的实例部署信息页签查看弹性策略与应用实例的运行状态。

启用混合弹性策略

本示例基于配置了定时弹性策略的main.tf文件,仅将资源alicloud_sae_application_scaling_rule的内容从定时弹性策略替换为混合弹性策略,其余内容保持不变。具体操作,请参见启用定时弹性策略

示例代码如下:
  • 更新前(定时弹性策略)
    resource "alicloud_sae_application_scaling_rule" "example" {
      app_id              = alicloud_sae_application.default.id
      scaling_rule_name   = "example-value"
      scaling_rule_enable = true
      scaling_rule_type   = "timing"
      scaling_rule_timer {
        begin_date = "2022-04-20"
        end_date   = "2022-05-31"
        period     = "* * *"
        schedules {
          at_time      = "19:35"
          target_replicas = 5
        }
        schedules {
          at_time      = "20:35"
          target_replicas = 2
        }
      }
    }
  • 更新后(混合弹性策略)
    resource "alicloud_sae_application_scaling_rule" "metrics" {
      app_id              = alicloud_sae_application.default.id
      scaling_rule_name   = "metric-dev"
      scaling_rule_enable = true
      scaling_rule_type   = "mix"
    
      scaling_rule_timer {
        begin_date = "2022-04-20"
        end_date   = "2022-05-31"
        period     = "* * *"
        schedules {
          at_time      = "19:45"
          max_replicas = 50
          min_replicas = 10
        }
        schedules {
          at_time      = "20:45"
          max_replicas = 40
          min_replicas = 3
        }
    
      }
      scaling_rule_metric {
        max_replicas = 40
        min_replicas = 3
        metrics {
          metric_type                       = "CPU"
          metric_target_average_utilization = 1
        }
        scale_up_rules {
          step                         = 10
          disabled                     = false
          stabilization_window_seconds = 0
        }
        scale_down_rules {
          step                         = 10
          disabled                     = false
          stabilization_window_seconds = 10
        }
      }
    }
    本示例的弹性策略内容如下:
    • 一般时间段:当CPU使用率超过1%时扩容,应用最大实例数为40个;当CPU使用率低于1%时缩容,应用最小实例数为3个。
    • 特殊时间段:基于CPU阈值,在2022年04月20日至2022年05月31日执行定时弹性伸缩策略。
      • 在19:45至20:45之间,应用最小实例数为10个,应用最大实例数为50个。
      • 在20:45至次日20:45之间,应用最小实例数为3个,应用最大实例数为40个。
    说明 示例代码为显示测试效果,设置了较低的CPU使用率,您在实际操作过程中可以按需设置合理的参数值。

执行修改后的Terraform资源,应用将启用混合弹性策略。您可以登录SAE控制台,在目标应用基本信息页面的实例部署信息页签查看弹性策略与应用实例的运行状态。

删除弹性策略和应用

本示例以在华东1(杭州)地域下的应用app-scaling为例,介绍如何停用弹性策略并删除应用。

  1. 在目标项目目录内执行以下命令,运行配置文件。
    terraform destroy
  2. 根据提示依次输入应用的各项信息,删除应用。
    • app_name:输入app-scaling
    • image_url:输入registry.cn-hangzhou.aliyuncs.com/****/****:01
      镜像地址格式如下:
      registry.<regionId>.aliyuncs.com/<命令空间名称>/<镜像仓库名称>:<镜像版本号>

      您可以登录容器镜像服务控制台,在目标实例仓库的基本信息页面查看镜像地址。

    • namespace_id:命名空间ID。输入cn-hangzhou:demo
    • namespace_name:命名空间名称。输入demo
    预期输出:
    ...
    
    module.vpc.alicloud_vpc.vpc[0]: Refreshing state... [id=vpc-bp1e2c4vcopwnmnef****]
    alicloud_sae_namespace.default: Refreshing state... [id=cn-hangzhou:demo]
    ...
    alicloud_sae_application_scaling_rule.metrics: Refreshing state... [id=f8982c19-0f91-4510-a26a-9644e97c****:metric-dev]
    
    Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
      - destroy
    
    ...
    
    Plan: 0 to add, 0 to change, 7 to destroy.
    
    Changes to Outputs:
      - app_id       = "f8982c19-0f91-4510-a26a-9644e97c****" -> null
      - app_name     = "app-scaling" -> null
      - namespace_id = "cn-hangzhou:demo" -> null
    alicloud_security_group_rule.sg_rule: Destroying... [id=sg-bp13cgwyi5o2h0g8****:ingress:tcp:1/65535:intranet:0.0.0.0/0:accept:1]
    
    module.vpc.alicloud_vpc.vpc[0]: Destroying... [id=vpc-bp1e2c4vcopwnmnef****]
    module.vpc.alicloud_vpc.vpc[0]: Destruction complete after 6s
    
    Destroy complete! Resources: 7 destroyed.
    已成功停用弹性策略并删除应用app-scaling