Packer是一款輕量級的鏡像定義工具,能夠運行在常用的主流作業系統(例如Windows、Linux和macOS)上,並行高效地建立多平台的虛擬機器鏡像。本文為您介紹如何在ECS執行個體中安裝Packer、定義Packer模板並使用Packer建立自訂鏡像。
前提條件
已建立AccessKey,並擷取AccessKey ID和AccessKey Secret。具體操作,請參見建立AccessKey。
由於AccessKey許可權過大,為防止資料泄露,建議您先建立RAM使用者,再使用RAM使用者建立AccessKey。建立RAM使用者的具體操作,請參見建立RAM使用者。
RAM使用者的AccessKey Secret只在建立時顯示,不支援查看,請妥善保管。
背景資訊
Packer工具包含Builders(產生器)、Provisioners(配置器)、Post-Processors(後處理器)等組件,通過HCL(HashiCorp Configuration Language)或者JSON格式的模板檔案較大地降低了建立自訂鏡像的難度,並且將建立鏡像的過程從人工的隨機過程變成可以組態管理代碼,從而減少了使用者應用上雲的障礙。關於Packer的更多資訊,請參見Packer官方文檔。
操作步驟
步驟一:安裝Packer
遠端連線ECS執行個體。
具體操作,請參見通過密碼認證登入Linux執行個體。
運行以下命令,進入
/usr/local/bin
目錄。cd /usr/local/bin
說明/usr/local/bin目錄為環境變數目錄,您可以將Packer安裝到該目錄下或其他已添加到環境變數的目錄下。
運行以下命令,擷取Packer安裝包。
您也可以訪問Packer下載頁面擷取與Elastic Compute Service作業系統及架構類型相對應的Packer安裝包,本操作以packer_1.8.5_linux_amd64.zip為例。
wget https://releases.hashicorp.com/packer/1.8.5/packer_1.8.5_linux_amd64.zip
運行以下命令,解壓Packer安裝包。
unzip packer_1.8.5_linux_amd64.zip
運行以下命令查詢Packer版本號碼,驗證Packer的安裝狀態。
packer -v
如果返回Packer版本號碼,表示您已正確安裝Packer。
如果返回資訊提示
command not found
,表示Packer未正確安裝,請檢查Packer所在目錄是否被添加到環境變數中。
步驟二:定義Packer模板
使用Packer建立自訂鏡像時,需要建立一個HCL格式或者JSON格式的模板檔案。在該模板檔案中,您需要指定建立自訂鏡像的產生器和配置器。更多資訊,請參見Builders(產生器)和Provisioners(配置器)。Packer具有多種配置器類型可用於配置自訂鏡像的內容產生方式,以下操作以常用的Shell配置器為例,定義Packer模板。
運行以下命令,匯入您的AccessKey ID。
export ALICLOUD_ACCESS_KEY=<AccessKey ID>
請將
<AccessKey ID>
替換為您實際的AccessKey ID。查詢RAM使用者AccessKey ID的具體操作,請參見查看RAM使用者的AccessKey資訊。運行以下命令,匯入您的AccessKey Secret。
export ALICLOUD_SECRET_KEY=<AccessKey Secret>
請將
<AccessKey Secret>
替換為您實際的AccessKey Secret。RAM使用者的AccessKey Secret只在建立時顯示,不支援查詢。更多資訊,請參見建立AccessKey。運行以下命令,建立名為
alicloud
的檔案。說明您可以選擇以下任意一種檔案格式來建立
alicloud
檔案,如果建立HCL格式的檔案,後續就需要按照HCL模板來執行。HCL檔案
vi alicloud.pkr.hcl
JSON檔案
vi alicloud.json
按
i
鍵進入編輯模式,將以下樣本Packer模板內容複寫到alicloud
檔案並根據實際情況修改參數。HCL檔案
variable "access_key" { type = string default = "${env("ALICLOUD_ACCESS_KEY")}" } variable "secret_key" { type = string default = "${env("ALICLOUD_SECRET_KEY")}" } source "alicloud-ecs" "autogenerated_1" { associate_public_ip_address = true image_name = "packer_basic" instance_type = "ecs.g6.large" internet_charge_type = "PayByTraffic" io_optimized = true region = "cn-qingdao" skip_image_validation = true source_image = "aliyun_3_x64_20G_alibase_20220907.vhd" ssh_username = "root" } build { sources = ["source.alicloud-ecs.autogenerated_1"] provisioner "shell" { inline = ["sleep 30", "yum install redis.x86_64 -y"] } }
JSON檔案
{ "variables": { "access_key": "{{env `ALICLOUD_ACCESS_KEY`}}", "secret_key": "{{env `ALICLOUD_SECRET_KEY`}}" }, "builders": [{ "type":"alicloud-ecs", "region":"cn-qingdao", "image_name":"packer_basic", "source_image":"aliyun_3_x64_20G_alibase_20220907.vhd", "associate_public_ip_address":true, "ssh_username":"root", "instance_type":"ecs.g6.large", "internet_charge_type":"PayByTraffic", "io_optimized":true, "skip_image_validation":true }], "provisioners": [{ "type": "shell", "inline": [ "sleep 30", "yum install redis.x86_64 -y" ] }] }
Packer模板支援自訂的參數說明如下。 更多參數說明,請參見Packer官網。
參數
類型
是否必填
描述
region
string
是
指定建立自訂鏡像時使用臨時資源的地區,例如
cn-qingdao
。image_name
string
是
指定建立的自訂鏡像名稱,例如
packer_basic
。instance_type
string
是
建立自訂鏡像時產生的臨時ECS執行個體的類型,例如
ecs.g6.large
規格。鏡像建立完成後,該執行個體會被自動釋放。說明使用Packer建立自訂鏡像過程中,會調用CreateInstance介面建立ECS執行個體,該執行個體包含了用於建立自訂鏡像的作業系統和預裝軟體等。該執行個體類型為隨用隨付,因此會產生部分費用。
ssh_username
string
是
SSH串連執行個體的使用者名稱。
internet_charge_type
string
否
建立自訂鏡像時臨時執行個體的公網頻寬付費類型。
PayByBandwidth:按固定頻寬計費。
PayByTraffic:按使用流量計費。
source_image
string
二選一必填
基礎鏡像的ID,該鏡像用於建立臨時ECS執行個體。可以從ECS控制台公用鏡像列表獲得,也可以通過DescribeImages介面查詢獲得。
重要配置時需注意所選鏡像類型需支援ECS執行個體的類型,例如ARM鏡像(鏡像ID攜帶_arm64_)需選用ARM類型的執行個體,否則無法成功建立自訂鏡像。
image_family
string
鏡像族系名稱,通過設定該參數來擷取當前鏡像族系內最新可用鏡像來建立執行個體。
說明鏡像族系的名稱長度為2~128 個字元。鏡像族系名稱不能以特殊字元、數字、http://、https://開頭,只可包含特殊字元中的"."、"_"、"-"和":"。
target_image_family
string
否
指定建立的自訂鏡像的鏡像族系。
說明鏡像族系的名稱長度為2~128 個字元。鏡像族系名稱不能以特殊字元、數字、http://、https://開頭,只可包含特殊字元中的"."、"_"、"-"和":"。
ssh_private_ip
boolean
三選一必填
是否通過私網SSH串連執行個體。預設值:false。
false:分配公網IP,通過公網串連執行個體。
true:不會分配EIP或公網IP,而是通過私網IP串連執行個體。
說明運行Packer的機器需要和Packer建立的機器在同一個網路環境,即同一個交換器下,才能使用私網串連。
associate_public_ip_address
boolean
是否綁定公網IP。
eip_id
string
彈性公網ID。
skip_image_validation
boolean
否
是否跳過鏡像檢查。預設值:false。
system_disk_mapping
object
否
系統硬碟配置。例如:
"system_disk_mapping": { "disk_name": "sysdisk", "disk_category": "cloud_essd", "disk_size": 40 }
詳細配置資訊,請參見雲端硬碟配置。
image_disk_mappings
list
否
鏡像資料盤配置。例如:
"image_disk_mappings": { "disk_name": "datadisk", "disk_snapshot_id": "s-bp1xxxxxx", "disk_device": "dev/xvdb" }
詳細配置資訊,請參見雲端硬碟配置。
image_ignore_data_disks
boolean
否
建立的鏡像是否包含資料盤快照。預設值:false。
false:建立的鏡像會同時包含資料盤快照。
true:建立鏡像不需要包含資料盤,只基於系統硬碟建立鏡像。
profile
string
否
執行Packer的設定檔,如果配置了該參數,會優先從該配置中擷取配置。
ram_role_name
string
否
RAM角色名稱。擷取本機RAM角色的臨時AK,執行Packer模板。
說明僅適用於綁定了RAM角色的ECS執行個體執行Packer的情境。
ram_role_arn
string
否
RAM角色ARN。與ram_session_name組合使用,A帳號扮演B帳號建立鏡像。
ram_session_name
string
否
RAM角色名稱。與ram_role_arn組合使用,A帳號扮演B帳號建立鏡像。
ecs_ram_role_name
string
否
執行個體RAM角色名稱。您可以使用RAM的API介面ListRoles查詢您已建立的執行個體RAM角色。
ssh_keypair_name
string
否
SSH串連的金鑰組名稱。
ssh_private_key_file
string
否
SSH串連的金鑰組的私密金鑰檔案路徑。
custom_endpoint_ecs
string
否
用自訂建立ECS的Endpoint。
security_group_id
string
否
建立臨時ECS執行個體所屬於的安全性群組ID。
security_group_name
string
否
安全性群組名稱。若不指定安全性群組ID,則會按這個名稱建立一個安全性群組。
vpc_id
string
否
VPC的ID。
vpc_name
string
否
VPC名稱。若不指定
vpc_id
,則會按這個名稱建立一個VPC。vswitch_id
string
否
虛擬交換器ID。
vswitch_name
string
否
交換器名稱。若不指定
vswitch_id
,則會按這個名稱建立一個交換器。user_data
string
否
執行個體自訂資料。必須填寫已採用Base64編碼後的資料,且在進行Base64編碼前自訂資料內容的大小不能超過32 KB。有關執行個體自訂資料的使用限制、格式以及運行頻率的詳細資料,請參見自訂執行個體初始化配置。
說明為保證傳輸過程中UserData的安全性,請避免直接以明文形式傳送敏感性資料,如密碼和私密金鑰。若需傳送此類資訊,建議先行加密處理,並採用Base64編碼方式,隨後在執行個體內部進行解密以確保資訊安全。
user_data_file
string
否
執行個體自訂資料檔案,UserData檔案形式。
boot_mode
string
否
指定鏡像的啟動模式。取值範圍:BIOS,UEFI,UEFI-Preferred。
wait_snapshot_ready_timeout
Integer
否
設定快照逾時時間。預設值為3600(秒)。
instance_name
string
否
建立臨時ECS執行個體的名稱,預設值為執行個體的
InstanceId
。說明名稱長度為 2~128 個字元,支援Unicode中letter分類下的字元(其中包括英文、中文和數字等)。可以包含半形冒號(:)、底線(_)、半形句號(.)或者短劃線(-)。
image_force_delete
boolean
否
是否刪除同名鏡像。預設值:false。
true:如果存在同名鏡像,則先刪除已有鏡像,然後建立目標鏡像。
false:如果存在同名鏡像,建立目標鏡像失敗。
image_force_delete_snapshots
boolean
否
是否刪除同名鏡像關聯的快照。預設值:false。
true:如果存在同名鏡像,則先刪除已有鏡像和已有鏡像關聯的快照,然後建立目標鏡像。
false:如果存在同名鏡像,建立目標鏡像失敗。
image_version
string
否
建立的自訂鏡像的版本。
resource_group_id
string
否
資源群組ID。
force_stop_instance
boolean
否
強制停機。預設值:false。
disable_stop_instance
boolean
否
預設情況下,Packer執行完provisioners後,會先停止執行個體再建立鏡像。某些特殊情境,如在Windows執行個體中運行Sysprep,需要執行個體處於運行狀態。預設值:false。
run_tags
object
否
鏡像標籤。例如
{"key":"value"}
。image_description
string
否
鏡像描述。
image_share_account
[]string
否
建立的自訂鏡像需要共用的使用者列表。例如
["123456"]
。image_copy_regions
[]string
否
建立的自訂鏡像需要複製的目標地區。例如
["cn-beijing"]
。provisioners
string
否
建立自訂鏡像時使用的Packer配置器類型。主要包括:
File
PowerShell
Shell
Local Shell
Windows Shell
更多資訊,請參見Provisioners(配置器)。
雲端硬碟配置
參數
類型
是否必填
描述
disk_name
string
否
雲端硬碟名稱。
說明名稱長度為 2~128 個字元,支援Unicode中letter分類下的字元(其中包括英文、中文和數字等)。可以包含半形冒號(:)、底線(_)、半形句號(.)或者短劃線(-)。
disk_category
string
否
雲端硬碟類型。取值範圍:
cloud_efficiency:高效雲端硬碟。
cloud_ssd:SSD 雲端硬碟。
cloud_essd:ESSD 雲端硬碟。
cloud:普通雲端硬碟。
disk_size
int
否
雲端硬碟大小,單位為 GiB。該參數的取值必須大於或者等於 max{20, ImageSize}。預設值:max{40, ImageSize}。
disk_description
string
否
雲端硬碟的描述,預設為空白。
說明長度為 2~256 個英文或中文字元,不能以
http://
和https://
開頭。disk_snapshot_id
string
否
建立資料盤使用的快照。
disk_delete_with_instance
boolean
否
表示資料盤是否隨執行個體釋放。取值範圍:
true:資料盤隨執行個體釋放。
false:資料盤不隨執行個體釋放。
預設值為 true。
disk_device
string
否
資料盤的掛載點。
disk_encrypted
boolean
否
資料盤是否加密。取值範圍:
true:加密。
false:不加密。
預設值:false。
按
Esc
鍵,並輸入:wq
後按下斷行符號鍵,儲存並退出。
步驟三:使用Packer建立自訂鏡像
使用Packer模板檔案產生自訂鏡像的操作步驟如下:
運行以下命令,建立自訂鏡像。
HCL檔案
packer build alicloud.pkr.hcl
樣本運行結果如下,以下樣本表示將在華北1(青島)地區建立鏡像ID為
m-m5e3f0gu2dxs4z0s****
的自訂鏡像。alicloud-ecs.autogenerated_1: output will be in this color. ==> alicloud-ecs.autogenerated_1: Prevalidating source region and copied regions... ==> alicloud-ecs.autogenerated_1: Prevalidating image name... alicloud-ecs.autogenerated_1: Found image ID: aliyun_3_x64_20G_alibase_20220907.vhd ==> alicloud-ecs.autogenerated_1: Creating temporary keypair: packer_64bf3d40-2fe7-8251-276d-df59a0bb**** --------------------------- ==> alicloud-ecs.autogenerated_1: Provisioning with shell script: /tmp/packer-shell3356722207 alicloud-ecs.autogenerated_1: Last metadata expiration check: 0:00:11 ago on Tue 25 Jul 2023 11:12:18 AM CST. --------------------------- alicloud-ecs.autogenerated_1: Complete! ==> alicloud-ecs.autogenerated_1: Stopping instance: i-m5e87pt498pr8zv0**** ==> alicloud-ecs.autogenerated_1: Waiting instance stopped: i-m5e87pt498pr8zv0**** ==> alicloud-ecs.autogenerated_1: Creating image: packer_basic alicloud-ecs.autogenerated_1: Detach keypair packer_64bf3d40-2fe7-8251-276d-df59a0bb**** from instance: i-m5e87pt498pr8zv0**** ==> alicloud-ecs.autogenerated_1: Cleaning up 'EIP' ==> alicloud-ecs.autogenerated_1: Cleaning up 'instance' ==> alicloud-ecs.autogenerated_1: Cleaning up 'security group' ==> alicloud-ecs.autogenerated_1: Cleaning up 'vSwitch' ==> alicloud-ecs.autogenerated_1: Cleaning up 'VPC' ==> alicloud-ecs.autogenerated_1: Deleting temporary keypair... Build 'alicloud-ecs.autogenerated_1' finished after 4 minutes 32 seconds. ==> Wait completed after 4 minutes 32 seconds ==> Builds finished. The artifacts of successful builds are: --> alicloud-ecs.autogenerated_1: Alicloud images were created: cn-qingdao: m-m5e3f0gu2dxs4z0s****
JSON檔案
packer build alicloud.json
樣本運行結果如下,以下樣本表示將在華北1(青島)地區建立鏡像ID為
m-m5e3f0gu2dxs4z0s****
的自訂鏡像。alicloud-ecs output will be in this color. ==> alicloud-ecs: Prevalidating image name... alicloud-ecs: Found image ID: aliyun_3_x64_20G_alibase_20220907.vhd ==> alicloud-ecs: Creating temporary keypair: packer_6345090e-ec1f-8ea0-348c-f85ba047**** ==> alicloud-ecs: Creating vpc --------------------------- ==> alicloud-ecs: Provisioning with shell script: /tmp/packer-shell090019677 alicloud-ecs: Last metadata expiration check: 0:00:15 ago on Tue 11 Oct 2022 02:12:51 PM CST. --------------------------- alicloud-ecs: Complete! ==> alicloud-ecs: Deleting image snapshots. ==> alicloud-ecs: Creating image: packer_basic alicloud-ecs: Detach keypair packer_6345090e-ec1f-8ea0-348c-f85ba047**** from instance: i-m5e7it5p4dpwetfr**** ==> 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-qingdao: m-m5e3f0gu2dxs4z0s****
查看已建立的自訂鏡像。
登入ECS管理主控台。
在左側導覽列,選擇 。
在頂部功能表列左上方處,選擇
alicloud
檔案中指定的地區,例如華北1(青島)。在自訂鏡像頁簽下,鏡像列表中查看產生的名稱為packer_basic的自訂鏡像。