閱讀383 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Packer & Terraform 讓 ESS 更靈活

彈性伸縮(Elastic Scaling Service, ESS)根據用戶的業務需求和策略,自動調整對彈性計算資源的管理,使得在滿足業務需求高峰增長時無縫地增加 ECS 實例,並在業務需求下降時自動減少 ECS 實例以節約成本。

隨著業務量和功能的不斷增加,越來越多的用戶開始選擇 ESS 來實現對業務的彈性支撐服務。然而,ESS 隻能實現對 ECS 實例的自動調整,並不能讓業務隨著 ECS 實例的伸縮進行自動化調整。

針對以上的問題,開源工具 Packer 和 Terraform 提出了相應的解決方案。本文將向您展示如何利用 Packer 和 Terraform 實現對具體業務的彈性伸縮。方便起見,本文將以彈性伸縮 Jenkins 服務為例進行詳細說明。

ESS 的局限性

ESS 根據用戶業務的需求和策略,自動的調整 ECS 實例的數量,以實現業務的有效運行和對成本的有效控製。
ess-jenkins
然而,ESS 隻解決了業務所在機器 ECS 的彈性伸縮問題,對具體業務的彈性伸縮卻無法滿足。正如上圖所示,隨著 Jenkins 業務的不斷調整,ESS 根據 ECS 實例配置和相應的伸縮規則對 ECS 進行彈性伸縮,然後利用 Jenkins 部署腳本或者其他工具在擴展後的 ECS 上手動部署 Jenkins 服務,以達到擴展 Jenkins 服務的目的。如此一來,業務的管理和運維成本勢必隨著業務量的加大而不斷增加。

Packer & Terraform 讓 ESS 更靈活

麵對如上的尷尬的問題,我們引入了開源工具 Packer 和 Terraform:

首先,基於 Packer 快速定製 Jenkins 服務的鏡像,接著將定製化的鏡像作為 ESS 配置 ECS 實例配置的參數,最後基於 Terraform 和 ESS 的伸縮配置及伸縮規則實現麵向 Jenkins 服務的ESS。
ess-jenkins-packer

Packer 定製 Jenkins 服務鏡像

如上圖所示,首先利用 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-bitLinux 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

    # Set environment 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 鏡像

    # Execute packer build
    cd alicloud-template/packer
    packer build examples/alicloud/jenkins/alicloud.json
    

整個鏡像定製過程大約持續10分鍾,定製結束後,packer-provder將返回 imageId 以及其他鏡像信息。

Terraform 搭建 Jenkins ESS

1. 本地安裝 Terraform 和 terraform-provider

利用定製化的鏡像,基於 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-bitLinux 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.tgz
    

2. 編寫搭建 Jenkins ESS 的 Terraform 模板

terraform-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_imagesname_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_sizescaling_min_size,一次伸縮實例的數量 rule_adjust_size 等。

3. 搭建 Jenkins ESS

編寫完 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 的詳細信息。

4. 訪問 Jenkins 服務

登錄 ESS 控製台後,在相應 ESS 的“ECS 實例列表”頁麵即可查看已經伸縮的 ECS 實例,查看實例詳情即可獲取 Jenkins 實例的公網 IP,在瀏覽器中輸入 <public_ip>:8080/jenkins 即可訪問 Jenkins 服務。

寫在最後

隨著用戶的業務需求和策略的不斷變化,ESS 完美的解決了運行業務實例的自動伸縮,但卻無法解決對業務的自動伸縮。Packer 和 Terraform 的出現,結合 ESS 在解決實例自動伸縮的同時,有效地實現了用戶業務的自動伸縮,有效降低了用戶對業務的管理和運維成本,實現了整個業務流程的代碼化。

最後更新:2017-04-19 23:05:24

  上一篇:go 阿裏雲智能語音交互技術實踐幹貨分享
  下一篇:go 矽穀資深數據科學家教你認清探索性數據分析(EDA)的價值