弹性伸缩(Elastic Scaling Service, ESS)根据用户的业务需求和策略,自动调整对弹性计算资源的管理,使得在满足业务需求高峰增长时无缝地增加 ECS 实例,并在业务需求下降时自动减少 ECS 实例以节约成本。
随着业务量和功能的不断增加,越来越多的用户开始选择 ESS 来实现对业务的弹性支撑服务。然而,ESS 只能实现对 ECS 实例的自动调整,并不能让业务随着 ECS 实例的伸缩进行自动化调整。
针对以上的问题,开源工具 Packer 和 Terraform 提出了相应的解决方案。本文将向您展示如何利用 Packer 和 Terraform 实现对具体业务的弹性伸缩。方便起见,本文将以弹性伸缩 Jenkins 服务为例进行详细说明。
ESS 根据用户业务的需求和策略,自动的调整 ECS 实例的数量,以实现业务的有效运行和对成本的有效控制。 然而,ESS 只解决了业务所在机器 ECS 的弹性伸缩问题,对具体业务的弹性伸缩却无法满足。正如上图所示,随着 Jenkins 业务的不断调整,ESS 根据 ECS 实例配置和相应的伸缩规则对 ECS 进行弹性伸缩,然后利用 Jenkins 部署脚本或者其他工具在扩展后的 ECS 上手动部署 Jenkins 服务,以达到扩展 Jenkins 服务的目的。如此一来,业务的管理和运维成本势必随着业务量的加大而不断增加。
面对如上的尴尬的问题,我们引入了开源工具 Packer 和 Terraform:
Packer A free and open source tool for creating golden images for multiple platforms from a single source configuration.Alibaba/packer-provider : https://github.com/alibaba/packer-provider
Terraform A open source tool for building, changing, and versioning infrastructure safely and efficiently.Alibaba/terraform-provider : https://github.com/alibaba/terraform-provider
首先,基于 Packer 快速定制 Jenkins 服务的镜像,接着将定制化的镜像作为 ESS 配置 ECS 实例配置的参数,最后基于 Terraform 和 ESS 的伸缩配置及伸缩规则实现面向 Jenkins 服务的ESS。
如上图所示,首先利用 ECS Image 和 Jenkins 部署脚本基于 Packer 快速定制安装有 Jenkins 服务的镜像,此次的定制需要借助于 Packer 和 Alibaba/packer-provider,所以在定制前需要在开发环境中安装 Packer 和 面向 Alicloud 的 packer-provider。下面是定制镜像的详细步骤:
安装 Packer 访问 Packer 下载页面 下载 MAC v1.0.0 版(可根据本地的开发环境自行选择版本)的 Packer 安装包,然后在将其放置在本地的 /bin 目录下(由于 Packer 和 Terraform 都是 Go 语言编写的,方便起见,将它们都存放在 Go 工作目录的 bin 目录下),解压后设置环境变量即完成安装。 cd $<GOPATH>/bin wget https://releases.hashicorp.com/packer/1.0.0/packer_1.0.0_darwin_amd64.zip unzip packer_1.0.0_darwin_amd64.zip # 验证是否安装成功 packer -version 安装 packer-provider为了安装方便,避免源码安装,目前已经提供了三种操作系统的 packer-provider 安装包 Mac 64-bit,Linux 64-bit 以及 Windows 64-bit,下载即可完成安装。 cd $<GOPATH>/bin wget https://github.com/alibaba/packer-provider/releases/download/V1.1/packer-builder-alicloud-ecs_darwin-amd64.tgz tar -xzf packer-builder-alicloud-ecs_darwin-amd64.tgz设置环境变量运行 Packer 前需要设置环境变量 AK
export ALICLOUD_ACCESS_KEY="access key value"export ALICLOUD_SECRET_KEY="secret key value"
编写 Packer Jenkins 模板,自定义 Jenkins 镜像的属性 packer-provider 已经提供了定制 Jenkins 镜像的模板,下图是模板的一部分,详见附件。 { "variables": { "access_key": "{{env `ALICLOUD_ACCESS_KEY`}}", "secret_key": "{{env `ALICLOUD_SECRET_KEY`}}" }, "builders": [{ "type":"alicloud-ecs", "access_key":"{{user `access_key`}}", "secret_key":"{{user `secret_key`}}", "region":"cn-beijing", "image_name":"packer_jenkins", "source_image":"ubuntu_14_0405_64_40G_base_20170222.vhd", "ssh_username":"root", "instance_type":"ecs.n1.medium", "io_optimized":"true", "image_force_delete":"true", "ssh_password":"Test12345" }], "provisioners": [{ "type": "file", "source": "examples/alicloud/jenkins/jenkins.sh", "destination": "/root/" },{ "type": "shell", "inline": [ "cd /root/", "chmod 755 jenkins.sh", "./jenkins.sh" ] }] }下载模板,编辑模板文件 alicloud-template/packer/examples/alicloud/jenkins/alicloud.json,可自定义镜像属性,如修改镜像名称 image_name,源镜像 source_image ,镜像 SSH 登录密码 ssh_password 等.
运行 Jenkins 模板,定制 Jenkins 镜像
cd alicloud-template/packerpacker build examples/alicloud/jenkins/alicloud.json
整个镜像定制过程大约持续10分钟,定制结束后,packer-provder将返回 imageId 以及其他镜像信息。
利用定制化的镜像,基于 terraform-provider 即可实现对 Jenkins ESS 的快速搭建。首先在开发环境中安装 Terraform 和面向 Alicloud 的 terraform-provider,它们也是由 Go 语言编写的。
安装 Terraform 和 Packer 类似,访问 Terraform 下载页面 下载 MAC v1.0.0 版(可根据本地的开发环境自行选择版本)的 Packer 安装包,然后在将其放置在本地的 /bin 目录下(由于 Packer 和 Terraform 都是 Go 语言编写的,方便起见,将它们都存放在 Go 工作目录的 bin 目录下),解压后设置环境变量即完成安装。 cd $<GOPATH>/bin wget https://releases.hashicorp.com/terraform/0.9.2/terraform_0.9.2_darwin_amd64.zip unzip terraform_0.9.2_darwin_amd64.zip # 验证是否安装成功 terraform -version 安装 terraform-provider 和 packer-provider 类似,terraform-provider 也提供了三种操作系统的安装包Mac 64-bit,Linux 64-bit 以及 Windows 64-bit ,下载即可完成安装。 cd $<GOPATH>/bin wget https://github.com/alibaba/terraform-provider/releases/download/V1.0.5/terraform-provider-alicloud_darwin-amd64.tgz tar -xzf terraform-provider-alicloud_darwin-amd64.tgzterraform-provider 提供了快速搭建 ESS 的模板,在这基础上,我们利用已经定制化的镜像只需要修改 ESS 模板中的少量配置,即可快速搭建面向 Jenkins 服务的 ESS,如下是模板中的文件 main.tf,模板详见附件。
data "alicloud_images" "ecs_image" { most_recent = true name_regex = "^centos_6\\w{1,5}[64].*" } resource "alicloud_security_group" "sg" { name = "${var.security_group_name}" description = "tf-sg" } resource "alicloud_security_group_rule" "ssh-in" { type = "ingress" ip_protocol = "tcp" nic_type = "internet" policy = "accept" port_range = "22/22" priority = 1 security_group_id = "${alicloud_security_group.sg.id}" cidr_ip = "0.0.0.0/0" } resource "alicloud_ess_scaling_group" "scaling" { min_size = "${var.scaling_min_size}" max_size = "${var.scaling_max_size}" scaling_group_name = "tf-scaling" removal_policies = "${var.removal_policies}" } resource "alicloud_ess_scaling_configuration" "config" { scaling_group_id = "${alicloud_ess_scaling_group.scaling.id}" enable = "${var.enable}" image_id = "${data.alicloud_images.ecs_image.images.0.id}" instance_type = "${var.ecs_instance_type}" io_optimized = "optimized" security_group_id = "${alicloud_security_group.sg.id}" } resource "alicloud_ess_scaling_rule" "rule" { scaling_group_id = "${alicloud_ess_scaling_group.scaling.id}" adjustment_type = "TotalCapacity" adjustment_value = "${var.rule_adjust_size}" cooldown = 60 } resource "alicloud_ess_schedule" "run" { scheduled_action = "${alicloud_ess_scaling_rule.rule.ari}" launch_time = "${var.schedule_launch_time}" scheduled_task_name = "tf-run" }根据新定制的镜像修改 Terraform 模板文件,具体操作步骤如下:
修改 ESS 模板 main.tf 编辑文件 alicloud-template/terraform/examples/alicloud-ess-schedule/main.tf,将资源 alicloud_images 的 name_regex 参数设置为定制化镜像的名称,即上文中提到的 image_name,接着,由于 Jenkins 服务需要开通 8080 端口,所以需要设置 ECS 实例的安全组规则,为了方便起见,只需要将资源 alicloud_security_group_rule 的参数 port_range 修改为 "8080/8080" 即可,除此之外,您还可以设置伸缩组的其他属性,如伸缩组名称 scaling_group_name,ECS 实例类型 instance_type 等。修改 ESS 模板变量 variable.tf 为了可以尽快的看到伸缩效果,我们可以设置伸缩定时任务的执行时间为未来 2 分钟。编辑文件 terraform/examples/alicloud-ess-schedule/variable.tf,修改变量 schedule_launch_time,此变量按照ISO8601标准表示,并使用UTC时间,格式为:YYYY-MM-DDThh:mmZ,由于北京时区是东八区,领先 UTC 八个小时,因此可根据未来本地未来两分钟的时间,利用公式:UTC = 本地时间 - 8 来进行设置。除此之外,您还可以设置最大最小伸缩实例的数量 scaling_max_size 和 scaling_min_size,一次伸缩实例的数量 rule_adjust_size 等。编写完 ESS 的 Terraform 模板后,即可利用 terrafrom 实现对 Jenkins ESS 的快速搭建:
# execute terraform template cd alicloud-template/terraform/examples/alicloud-ess-schedule # preview resource terraform plan # create resource terraform apply整个搭建过程不超过 30 秒,搭建结束后,等待 ESS 定时任务的自动执行,执行结束后 ESS 将会扩展出指定数量的安装有 Jenkins 服务的 ECS。登录 ESS 控制台 即可查看 ESS 的详细信息。
登录 ESS 控制台后,在相应 ESS 的“ECS 实例列表”页面即可查看已经伸缩的 ECS 实例,查看实例详情即可获取 Jenkins 实例的公网 IP,在浏览器中输入 <public_ip>:8080/jenkins 即可访问 Jenkins 服务。
随着用户的业务需求和策略的不断变化,ESS 完美的解决了运行业务实例的自动伸缩,但却无法解决对业务的自动伸缩。Packer 和 Terraform 的出现,结合 ESS 在解决实例自动伸缩的同时,有效地实现了用户业务的自动伸缩,有效降低了用户对业务的管理和运维成本,实现了整个业务流程的代码化。
相关资源:pack-datomic:Datomic Packer和Terraform设置-源码