通過Packer,您只需在JSON設定檔中指明構建鏡像所需的基本資料、以及需要安裝到鏡像中的軟體及配置,即可自動化構建ECS鏡像。

什麼是Packer

Packer是HashiCorp推出的一款鏡像工具,旨在通過簡易的方式自動化構建鏡像。由於構建鏡像的過程以一份JSON設定檔為準,您無需擔心多次構建的鏡像存在不一致。Packer還能為測試和更新鏡像帶來使用便利,降低營運和管理鏡像的時間成本。更多詳情,請訪問Packer官網

鏡像構建方式對比

目前,阿里雲支援以下構建鏡像的方式:

表 1. 構建鏡像的方式對比
構建方式列舉 工具與依賴 優點 缺點
使用快照建立自訂鏡像 支援通過ECS控制台或者API建立,前提是您必須已經建立了一份系統硬碟快照。
  • 易上手。
  • 可多次利用計算資源。
  • 可以根據即時生產環境建立鏡像。
  • 基於阿里雲公用鏡像建立,安全可靠。
  • 隨鏡像內需預裝的軟體及其配置擴充變得複雜。
  • 難以確保人工操作是否準確無誤和前後一致。
  • 後期維護成本高。
使用執行個體建立自訂鏡像 支援通過ECS控制台或者API建立,前提是您已經建立了一台執行個體。
使用Packer構建自訂鏡像 支援識別Packer請求,通過AccessKey驗證使用者資訊。
  • 無需提前建立執行個體或快照。
  • 可多次利用和修改JSON檔案。
  • 具有動作記錄,步驟清晰可見易於回溯。
  • 自動釋放臨時資源。
  • 支援自動轉換ISO檔案並匯入阿里雲ECS。
  • 可基於阿里雲公用鏡像和本地ISO檔案構建,靈活方便。
具有少量學習成本。

操作條件

本文通過比較“使用執行個體建立自訂鏡像”和“使用Packer構建自訂鏡像”的操作流程,突出Packer在DevOps情境中的優勢。以下為本次操作的假設情境和一致性條件:

  • 目標地區:阿里雲華北2(北京)地區,更多詳情,請參見地區和可用性區域
  • 作業系統:CentOS 7.3 64位。本文兩種方式均採用公用鏡像centos_7_03_64_20G_alibase_20170818.vhd,您可以在ECS管理主控台或調用DescribeImages查詢其他動作系統的鏡像ID列表。
  • 自訂服務:redis。
  • 是否保留臨時資源:否。
说明 本文操作會建立計費資源,請注意釋放和清理。如執行個體、公網IP、快照等。

使用執行個體建立自訂鏡像

本樣本介紹如何通過ECS管理主控台建立一份自訂鏡像。以下為樣本操作的流程示意圖:

  1. 登入Elastic Compute Service管理主控台
  2. 在左側導覽列,單擊執行個體
  3. 選擇地區。
  4. 參見使用嚮導建立執行個體完成執行個體購買。為較少費用消耗和簡化操作流程,您可以選擇以下配置:
    • 計費方式:隨用隨付,更多詳情,請參見隨用隨付
    • 執行個體規格:ecs.t5-lc1m1.small,更多詳情,請參見執行個體規格類型系列匯總
    • 公用鏡像:CentOS 7.3 64位。
    • 專用網路:預設VPC。
    • 安全性群組:預設安全性群組。
    • 公網頻寬:如果不需要公網訪問,可以選擇不開通公網頻寬,並通過管理終端遠端連線執行個體。
  5. 遠端連線已建立的ECS執行個體。串連方式可參見串連方式導航
  6. 運行yum install redis.x86_64 -y安裝redis服務。
  7. 返回ECS控制台,選擇華北2(北京)地區。
  8. 參見使用執行個體建立自訂鏡像建立一份鏡像。
  9. 快照和鏡像 > 鏡像頁面查看鏡像完成狀態。
  10. (可選)鏡像製作成功後,釋放臨時資源,包括執行個體等。若您使用的是Elastic IP Address,也可以選擇釋放。

使用Packer構建自訂鏡像

本樣本介紹如何通過Packer構建一份自訂鏡像。以下為樣本操作的流程示意圖:



前提條件

您已經安裝了Packer。關於如何安裝Packer,請參見Packer官方文檔或者阿里雲文檔使用Packer構建自訂鏡像

操作步驟

  1. 本地建立一份alicloud.json檔案,檔案內容如下:
    {
      "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_basic",
        "source_image":"centos_7_03_64_20G_alibase_20170818.vhd",
        "ssh_username":"root",
        "instance_type":"ecs.t5-lc1m1.small",
        "internet_charge_type":"PayByTraffic",
        "io_optimized":"true"
      }],
      "provisioners": [{
        "type": "shell",
        "inline": [
          "sleep 30",
          "yum install redis.x86_64 -y"
        ]
      }]
    }
    表 2. Packer參數解釋
    參數 樣本值 參數解釋
    variables{"varible1":"value"} variables{"access_key":"{{env `ALICLOUD_ACCESS_KEY`}}"} 定義了builders中會用到的變數(variables)。將AccessKey(access_key和secret_key)資訊寫入設定檔有資訊泄露的風險,設定成變數後可防止意外,變數的值取自運行時的輸入值。
    builders{"type":"value"} builders{"type":"alicloud-ecs"} Packer定義的鏡像產生器(builders)。阿里雲支援alicloud-ecs,又稱Alicloud Image Builder,用於在阿里雲ECS建立自訂鏡像。
    provisioners{"type":"value"} provisioners{"type":"shell"} Packer定義的鏡像配置器(provisioners),用以定義需要在臨時執行個體內執行的操作。本文使用的是Shell Provisioner,表示在串連Linux執行個體後自動執行一段shell命令(如yum install redis.x86_64 -y)安裝redis服務。
    表 3. 阿里雲參數解釋
    參數 資料類型 樣本值 參數解釋 重要度
    access_key String LTAInPyXXXXQXXXX 您的AccessKeyID。更多詳情,請參見建立AccessKey
    说明 由於AccessKey許可權過大,為防止錯誤操作,建議您建立RAM使用者,並使用RAM子帳號建立AccessKey。
    secret_key String CM1ycKrrCekQ0dhXXXXXXXXXl7yavUT 您的AccessKeySecret。
    region String cn-beijing 目標自訂鏡像的所屬地區。更多詳情,請參見地區和可用性區域
    image_name String packer_basic 目標自訂鏡像的名稱。不允許與已有鏡像重名。
    source_image String centos_7_03_64_20G_alibase_20170818.vhd 具有相同作業系統的阿里雲公用鏡像ID。
    instance_type String ecs.t5-lc1m1.small 建立自訂鏡像時使用的臨時執行個體的執行個體規格。更多詳情,請參見執行個體規格類型系列匯總
    internet_charge_type String PaybyTraffic 臨時執行個體的公網頻寬付費類型。建議設定為按流量付費(PaybyTraffic)。
    io_optimized Boolean true 臨時執行個體的I/O最佳化屬性。建議設定為I/O最佳化(true)。
  2. 執行以下命令構建一份鏡像:
    packer build alicloud.json
    说明 構建鏡像是相對耗時的任務,請您耐心等待。鏡像構建成功後,會出現在相應阿里雲地區中,您可以通過ECS控制台或DescribeImages查看。

    構建鏡像時會產生的動作記錄。日誌給出了構建過程中執行的每一個步驟,包括校正參數、建立臨時資源、預先安裝軟體、建立目標資源和釋放臨時資源等。

    alicloud-ecs output will be in this color.
    
    ==> alicloud-ecs: Prevalidating image name...
        alicloud-ecs: Found image ID: centos_7_03_64_20G_alibase_20170818.vhd
    ==> alicloud-ecs: Creating temporary keypair: packer_xxx
    ==> alicloud-ecs: Creating vpc
    ==> alicloud-ecs: Creating vswitch...
    ==> alicloud-ecs: Creating security groups...
    ==> alicloud-ecs: Creating instance.
    ==> alicloud-ecs: Allocating eip
    ==> alicloud-ecs: Allocated eip xxx
        alicloud-ecs: Attach keypair packer_xxx to instance: i-xxx
    ==> alicloud-ecs: Starting instance: i-xxx
    ==> alicloud-ecs: Using ssh communicator to connect: ***
    ==> alicloud-ecs: Waiting for SSH to become available...
    ==> alicloud-ecs: Connected to SSH!
    ==> alicloud-ecs: Provisioning with shell script: /var/folders/k_/nv2r4drx3bs08l6tcx06ndb40000gn/T/packer-shell260049331
        alicloud-ecs: Loaded plugins: fastestmirror
        alicloud-ecs: Determining fastest mirrors
        alicloud-ecs: Resolving Dependencies
        alicloud-ecs: --> Running transaction check
        alicloud-ecs: ---> Package redis.x86_64 0:3.2.12-2.el7 will be installed
        alicloud-ecs: --> Processing Dependency: libjemalloc.so.1()(64bit) for package: redis-3.2.12-2.el7.x86_64
        alicloud-ecs: --> Running transaction check
        alicloud-ecs: ---> Package jemalloc.x86_64 0:3.6.0-1.el7 will be installed
        alicloud-ecs: --> Finished Dependency Resolution
        alicloud-ecs:
        alicloud-ecs: Dependencies Resolved
        alicloud-ecs:
        alicloud-ecs: ================================================================================
        alicloud-ecs:  Package           Arch            Version                  Repository     Size
        alicloud-ecs: ================================================================================
        alicloud-ecs: Installing:
        alicloud-ecs:  redis             x86_64          3.2.12-2.el7             epel          544 k
        alicloud-ecs: Installing for dependencies:
        alicloud-ecs:  jemalloc          x86_64          3.6.0-1.el7              epel          105 k
        alicloud-ecs:
        alicloud-ecs: Transaction Summary
        alicloud-ecs: ================================================================================
        alicloud-ecs: Install  1 Package (+1 Dependent package)
        alicloud-ecs:
        alicloud-ecs: Total download size: 648 k
        alicloud-ecs: Installed size: 1.7 M
        alicloud-ecs: Downloading packages:
        alicloud-ecs: --------------------------------------------------------------------------------
        alicloud-ecs: Total                                              2.2 MB/s | 648 kB  00:00
        alicloud-ecs: Running transaction check
        alicloud-ecs: Running transaction test
        alicloud-ecs: Transaction test succeeded
        alicloud-ecs: Running transaction
        alicloud-ecs:   Installing : jemalloc-3.6.0-1.el7.x86_64                                  1/2
        alicloud-ecs:   Installing : redis-3.2.12-2.el7.x86_64                                    2/2
        alicloud-ecs:   Verifying  : redis-3.2.12-2.el7.x86_64                                    1/2
        alicloud-ecs:   Verifying  : jemalloc-3.6.0-1.el7.x86_64                                  2/2
        alicloud-ecs:
        alicloud-ecs: Installed:
        alicloud-ecs:   redis.x86_64 0:3.2.12-2.el7
        alicloud-ecs:
        alicloud-ecs: Dependency Installed:
        alicloud-ecs:   jemalloc.x86_64 0:3.6.0-1.el7
        alicloud-ecs:
        alicloud-ecs: Complete!
    ==> alicloud-ecs: Stopping instance: i-xxx
    ==> alicloud-ecs: Waiting instance stopped: i-xxx
    ==> alicloud-ecs: Creating image: packer_basic
        alicloud-ecs: Detach keypair packer_xxx from instance: i-xxx
    ==> alicloud-ecs: Cleaning up 'EIP'
    ==> alicloud-ecs: Cleaning up 'instance'
    ==> alicloud-ecs: Cleaning up 'security group'
    ==> alicloud-ecs: Cleaning up 'vSwitch'
    ==> alicloud-ecs: Cleaning up 'VPC'
    ==> alicloud-ecs: Deleting temporary keypair...
    Build 'alicloud-ecs' finished.
    
    ==> Builds finished. The artifacts of successful builds are:
    --> alicloud-ecs: Alicloud images were created:
    
    cn-beijing: m-xxx

相關連結

更多參數和範例,請參見: