
# 使用Packer创建私有镜像
Packer是一款可以创建自定义镜像的开源工具。Packer包含构建器（Builder）、配置器（Provisioner）、后处理器（Post-Processor）三个组件，通过HCL2（HashiCorp Configuration Language）或者JSON格式的模板文件，可以灵活组合这三种组件并行地、自动化地创建镜像文件。使用Packer通过配置代码的形式，降低了创建私有镜像复杂度，并且将创建镜像的过程变成可以配置管理代码的形式，在支持用户灵活定制个性化镜像的同时，也为镜像在不同云平台间的切换提供了一种新的途径。
本节以在CentOS 8.2 64bit云服务器中创建Ubuntu 22.04 Server 64bit私有镜像并上传到公有云平台为例，介绍使用Packer创建镜像的操作步骤。
#### 约束与限制
不支持Packer使用整机镜像作为源镜像来创建私有镜像。
#### 操作流程
![](https://support.huaweicloud.com/bestpractice-ims/zh-cn_image_0140629595.png "点击放大")
#### 安装Packer
1. 登录[ECS控制台](https://console.huaweicloud.com/ecm/?#/ecs/manager/vmList)，创建一台弹性云服务器（以CentOS 8.2 64bit为例），并绑定弹性公网IP。
2. 在[Packer工具下载页面](https://developer.hashicorp.com/packer/install)选择与云服务器操作系统及架构类型相对应的Packer版本，版本号建议选择最新版本。
3. 执行以下命令，安装Packer（本节操作以packer_1.9.1_linux_amd64.zip为例）。 **wget --no-check-certificate https://releases.hashicorp.com/packer/1.9.1/packer_1.9.1_linux_amd64.zip**
   ![](https://support.huaweicloud.com/bestpractice-ims/public_sys-resources/note_3.0-zh-cn.png)
   - 需要提前给云服务器绑定弹性公网IP，以便能够访问外网。
   
   - 如果执行本步骤命令后报"command not found"的错误，说明没有预装wget工具，需要执行**yum install wget**进行安装。
     
4. 执行以下命令，解压Packer安装包。 **unzip packer_1.9.1_linux_amd64.zip**
   
5. 执行以下命令，将Packer安装包移动至"/usr/local/bin"目录下。
   **mv packer /usr/local/bin**
   ![](https://support.huaweicloud.com/bestpractice-ims/public_sys-resources/note_3.0-zh-cn.png)
   "/usr/local/bin"目录已被添加到环境变量，您也可以将Packer安装包移动至其它目录下，并确保该目录已被添加到环境变量中。
   
6. 执行以下命令，查询Packer版本号，检查Packer是否安装成功。 **packer -v**
   - 如果回显信息为Packer版本号，表示已完成Packer安装。
   
   - 如果回显信息为"command not found"，表示Packer安装失败，请检查Packer所在目录是否被添加到环境变量中。
     ![](https://support.huaweicloud.com/bestpractice-ims/public_sys-resources/note_3.0-zh-cn.png)
     使用命令**env \| grep PATH**打印环境变量，查看环境变量PATH是否包含Packer的安装目录。
     如果环境变量PATH中没有包含Packer安装目录，请依次使用以下命令，将Packer的安装路径添加到环境变量PATH中：
     1. 执行以下命令，打开profile文件。 **vim /etc/profile**
        
     
     2. 按"i"键进入编辑模式，在文件末尾添加"export PATH=$PATH:/usr/local/bin"。 请将/usr/local/bin换成您实际安装Packer的目录。
        
     
     3. 按"ESC"退出编辑模式，输入**:wq**，按回车键保存修改并退出。
     
     4. 执行以下命令，使修改生效。 **source /etc/profile**
        
       
    
 
#### 定义Packer模板
使用Packer创建镜像，需要一个后缀为.pkr.hcl格式模板文件。在模板文件中，您需要指定[构建器](https://developer.hashicorp.com/packer/tutorials/docker-get-started/docker-get-started-build-image)、[配置器](https://developer.hashicorp.com/packer/tutorials/docker-get-started/docker-get-started-provision)，还可以指定后处理器。在配置器中，您可以指定对源镜像的任何操作，可以指定安装软件也可以对相关配置做修改。本示例使用后处理器重定向manifest的输出路径，如果您的Packer模板文件中有多个builders（构建器），您可以通过manifest的输出内容，找到每个builder创建镜像的ID。关于构建器、配置器以及后处理器的详细介绍请参考[Packer官方文档](https://developer.hashicorp.com/packer/docs)。
本节操作以Shell配置器为例。
1. 执行以下命令，创建hwcloud.pkr.hcl文件。 **touch hwcloud.pkr.hcl**
   
2. 执行以下命令，打开hwcloud.**pkr.hcl** 文件。
   **vim hwcloud.pkr.hcl**
   
3. 按"i"进入编辑模式，根据实际需求编写模板，以下内容仅供参考，参数列表请查看[表1 Packer模板参数列表]。
   ```
   packer {
     required_plugins {
       huaweicloud = {
         version = ">= 1.0.0"
         source  = "github.com/huaweicloud/huaweicloud"
       }
     }
   }
    
   source "huaweicloud-ecs" "artifact" {
     region            = "xxx"
     availability_zone = "xxx"
     flavor            = "c6.large.2"
     source_image_name = "Ubuntu 22.04 server 64bit"
     image_name        = "Ubuntu-2204-image-powered-by-Packer"
     image_tags = {
       builder = "packer"
       os      = "Ubuntu-22.04-server"
     }
    
     ssh_username       = "root"
     eip_type           = "5_bgp"
     eip_bandwidth_size = 5
   }
    
   build {
     sources = ["source.huaweicloud-ecs.artifact"]
    
     provisioner "shell" {
       inline = ["apt-get update -y"]
     }
    
     post-processor "manifest" {
       strip_path = true
       output     = "packer-result.json"
     }
   }
   ```
   ![](https://support.huaweicloud.com/bestpractice-ims/public_sys-resources/note_3.0-zh-cn.png)
   [表1 Packer模板参数列表]中，region、availability_zone、flavor、source_image_name均为创建私有镜像时使用的云服务器的属性信息。
    表1Packer模板参数列表 
   | 参数                 | 描述                                                                                                                                                                                                                             | 是否为必选 |
   |:---|:---|:---|
   | region             | 区域名称。参考[地区和终端节点](https://console.huaweicloud.com/apiexplorer/#/endpoint/IMS)获取。                                                                                                                                                | 是     |
   | flavor             | 云服务器的规格。                                                                                                                                                                                                                       | 是     |
   | image_name         | 待创建私有镜像的名称。                                                                                                                                                                                                                    | 是     |
   | image_tags         | 待创建私有镜像的tags。                                                                                                                                                                                                                  | 否     |
   | availability_zone  | 可用区。参考[地区和终端节点](https://console.huaweicloud.com/apiexplorer/#/endpoint/IMS)获取。                                                                                                                                                 | 否     |
   | source_image_name  | 源镜像名称，可以从[IMS控制台](https://console.huaweicloud.com/ecm/?#/ims/manager/imageList/selfImage)公共镜像列表获取。 说明： 您也可以使用source_image参数指定源镜像的ID或者使用source_image_filter参数查询源镜像。 | 否     |
   | ssh_username       | 待创建私有镜像的ssh登录用户名。 使用SSH方式登录时，该配置项必选。                                                                                                                                                             | 否     |
   | eip_type           | 弹性公网IP的线路类型。                                                                                                                                                                                                                   | 否     |
   | eip_bandwidth_size | 弹性公网IP的带宽大小（Mbit/s）。如果在Packer创建的镜像实例中需要使用外网，那么该配置项必选。 说明： 您也可以使用floating_ip或者reuse_ips参数使用已有的EIP。                                                                   | 否     |
   | provisioner        | 创建私有镜像时使用的Packer配置器类型。详情请参见[Packer配置器](https://developer.hashicorp.com/packer/tutorials/docker-get-started/docker-get-started-provision)。                                                                                      | 是     |
   | post-processor     | 创建私有镜像时使用的Packer后处理器类型。                                                                                                                                                                                                        | 否     |
      
   ![](https://support.huaweicloud.com/bestpractice-ims/public_sys-resources/note_3.0-zh-cn.png)
   更多配置参数请参见<https://github.com/huaweicloud/packer-plugin-huaweicloud/wiki>。
   
#### 使用Packer创建镜像
1. Packer模板文件制作完成后，请执行以下命令，导入您的AK、SK。 **export HW_ACCESS_KEY=\<AccessKey ID\>**
   **export HW_SECRET_KEY=\<AccessKey Secret\>**
   
2. 请执行以下命令创建镜像。 **packer build hwcloud.pkr.hcl**
   ```
   huaweicloud-ecs.artifact: output will be in this color.
    
   ==> huaweicloud-ecs.artifact: Loading availability zones...
       huaweicloud-ecs.artifact: the specified availability_zone ap-southeast-1a is available
   ==> huaweicloud-ecs.artifact: Loading flavor: c6.large.2
   ==> huaweicloud-ecs.artifact: Creating temporary keypair: packer_64abc4fd-xxxx-xxxx-xxxx-2139eee76819...
   ==> huaweicloud-ecs.artifact: Created temporary keypair: packer_64abc4fd-xxxx-xxxx-xxxx-2139eee76819
       huaweicloud-ecs.artifact: Found Image ID: 19d9079e-xxxx-xxxx-xxxx-642116ad6557
   ==> huaweicloud-ecs.artifact: Creating temporary VPC...
       huaweicloud-ecs.artifact: temporary VPC ID: 6e309adc-xxxx-xxxx-xxxx-4c3356b972c7
   ==> huaweicloud-ecs.artifact: Creating temporary subnet...
       huaweicloud-ecs.artifact: temporary subnet ID: 66ab3bc3-xxxx-xxxx-xxxx-d8ca2d9378cc
       huaweicloud-ecs.artifact: the [default] security groups will be used ...
   ==> huaweicloud-ecs.artifact: Creating EIP ...
       huaweicloud-ecs.artifact: Created EIP: '0cd696e3-xxxx-xxxx-xxxx-220b8d277604' (159.xxx.xxx.180)
   ==> huaweicloud-ecs.artifact: Launching server in AZ ap-southeast-1a...
       huaweicloud-ecs.artifact: Waiting for server to become ready...
       huaweicloud-ecs.artifact: Server ID: 13f78f88-xxxx-xxxx-xxxx-7e8c27a9ad1f
   ==> huaweicloud-ecs.artifact: Using SSH communicator to connect: 159.138.141.180
   ==> huaweicloud-ecs.artifact: Waiting for SSH to become available...
   ==> huaweicloud-ecs.artifact: Connected to SSH!
   ==> huaweicloud-ecs.artifact: Provisioning with shell script: /tmp/packer-shell2456008753
   huaweicloud-ecs.artifact: Hit:1 http://repo.huaweicloud.com/ubuntu jammy InRelease
           ......
       huaweicloud-ecs.artifact: Fetched 5,536 kB in 3s (2,006 kB/s)
       huaweicloud-ecs.artifact: Reading package lists...
   ==> huaweicloud-ecs.artifact: Stopping server: 13f78f88-xxxx-xxxx-xxxx-7e8c27a9ad1f ...
       huaweicloud-ecs.artifact: Waiting for server to stop: 13f78f88-xxxx-xxxx-xxxx-7e8c27a9ad1f ...
   ==> huaweicloud-ecs.artifact: Creating the system image: Ubuntu-2204-image-powered-by-Packer ...
       huaweicloud-ecs.artifact: Image: 62dc6e37-xxxx-xxxx-xxxx-a2a00a677f5b
   ==> huaweicloud-ecs.artifact: Terminating the source server: 13f78f88-xxxx-xxxx-xxxx-7e8c27a9ad1f...
   ==> huaweicloud-ecs.artifact: Deleted temporary public IP '0cd696e3-xxx-xxxx-xxxx-220b8d277604' (159.xxx.xxx.180)
   ==> huaweicloud-ecs.artifact: Deleting temporary subnet: 66ab3bc3-xxxx-xxxx-xxxx-d8ca2d9378cc...
   ==> huaweicloud-ecs.artifact: Deleting temporary VPC: 6e309adc-xxxx-xxxx-xxxx-4c3356b972c7...
   ==> huaweicloud-ecs.artifact: Deleting temporary keypair: packer_64abc4fd-xxxx-xxxx-xxxx-2139eee76819 ...
   ==> huaweicloud-ecs.artifact: Running post-processor:  (type manifest)
   Build 'huaweicloud-ecs.artifact' finished after 5 minutes 48 seconds.
    
   ==> Wait completed after 5 minutes 48 seconds
    
   ==> Builds finished. The artifacts of successful builds are:
   --> huaweicloud-ecs.artifact: An image was created: 62dc6e37-xxxx-xxxx-xxxx-a2a00a677f5b
   ```
   
3. 命令执行成功后，登录[IMS控制台](https://console.huaweicloud.com/ecm/?#/ims/manager/imageList/selfImage)。
4. 在"私有镜像"列表页面，查看使用Packer创建的镜像，如[图1]所示。
   图1查看使用Packer创建的镜像   
   ![](https://support.huaweicloud.com/bestpractice-ims/zh-cn_image_0000001648507829.png "点击放大") 
 
#### 相关链接
Packer官方指导：<https://developer.hashicorp.com/packer/tutorials/docker-get-started/get-started-install-cli>
