
# 制作CCE节点自定义镜像
CCE自定义镜像制作基于开源工具[HashiCorp Packer](https://developer.hashicorp.com/packer)以及[开源插件](https://github.com/huaweicloud/packer-plugin-huaweicloud)实现，并提供了cce-image-builder配置模板帮助您快速制作符合要求的自定义镜像。
Packer是一款可以创建自定义镜像的开源工具。Packer包含构建器（Builder）、配置器（Provisioner）、后处理器（Post-Processor）三个组件，支持通过json或者hcl格式的模板文件，可以灵活组合这三种组件并行地、自动化地创建镜像文件。
Packer作为镜像制作的工具有如下优势：
1. 构建过程自动化：创建镜像的过程变成可以通过Packer配置文件的形式固化，支持自动化构建。
2. 云平台兼容性强：原生支持对接绝大多数的云平台，也包括各类第三方插件。
3. 配置文件易用性高：Packer配置文件中模块职责清晰，参数定义简单直观，学习成本低。
4. 镜像构建功能全面：原生支持较多常用功能模块，例如Provisioner中支持使用远程执行脚本的shell模块、支持远程传输文件的file模块、支持暂停流程的breakpoint模块。
#### 约束与限制
- 创建自定义镜像仅支持以下操作系统及内核版本：
  
  | 操作系统                          | 内核版本                                                |
  |:---|:---|
  | CentOS 7.6                    | \>= 3.10.0-1160.15.2.el7.x86_64                     |
  | Ubuntu 18.04                  | \>= 4.15.0-136-generic                              |
  | Ubuntu 22.04                  | \>= 5.15.0-86-generic                               |
  | EulerOS 2.9（x86）              | \>= 4.18.0-147.5.1.6.h1071.eulerosv2r9.x86_64       |
  | EulerOS 2.9（ARM）              | \>= 4.19.90-vhulk2103.1.0.h1060.eulerosv2r9.aarch64 |
  | Huawei Cloud EulerOS 2.0（x86） | \>= 5.10.0-60.18.0.50.r1002_48.hce2.x86_64          |
  | Huawei Cloud EulerOS 2.0（ARM） | \>= 5.10.0-60.18.0.50.r1002_48.hce2.aarch64         |
     
  
- CCE节点镜像使用建议：
  - 节点镜像推荐优先使用CCE服务维护的默认节点镜像。相关镜像经过严格的测试，且能获得最新的更新推送，具有更好的兼容性、稳定性和安全性。
  
  - 如果您有特殊场景需要使用自定义镜像功能，请使用CCE提供的节点镜像ID来制作自定义镜像，不支持直接将ECS公共镜像或正在运行的节点镜像导出作为自定义镜像。
   
- 自定义镜像时，请**谨慎修改内核参数** ，部分内核参数过大或者过小时都会影响系统运行效率，参考值请参见[修改节点内核参数](https://support.huaweicloud.com/usermanual-cce/cce_10_0412.html)。
  已知存在影响的内核参数有：tcp_keepalive_time、tcp_max_tw_buckets、somaxconn、max_user_instances、max_user_watches、netdev_max_backlog、net.core.wmem_max、net.core.rmem_max。
  如修改节点内核参数，请您在测试环境中自行完成充分的测试验证，再应用于生产环境。
  
 
#### 使用须知
- 制作镜像前需要准备：
  - ECS执行机：一台ECS x86服务器作为Linux执行机，建议选择Huawei Cloud EulerOS 2.0操作系统并绑定EIP支持访问公网，便于后续安装Packer工具。
  
  - 认证凭据：制作镜像需要获取具有相关权限用户或者租户的AK/SK认证凭据，请提前获取，详情请参考[IAM 如何获取访问密钥AK/SK](https://support.huaweicloud.com/iam_faq/iam_01_0618.html)。
  
  - 安全组：由于Packer通过创建临时ECS服务器并使用密钥对SSH登录，需要提前确保临时ECS服务器指定的安全组放开**TCP:22** 端口通道，允许执行机SSH登录。详情请参考[安全组配置示例](https://support.huaweicloud.com/usermanual-ecs/zh-cn_topic_0140323152.html)。
   
- 制作过程中：
  - 制作镜像的过程中必须按照操作指南进行制作，防止一些不可预期问题出现。
  
  - 根据基础镜像创建出来的虚机，默认SSH登录用户需要支持sudo root权限，或者拥有root权限。
   
- 制作结束时：
  - 制作过程会消耗一定计费资源，主要涉及ECS服务器、EVS云硬盘、弹性IP及带宽和IMS镜像。正常场景制作成功或者失败后会自动释放。但制作完成后，建议再次确认资源已彻底释放，以避免非预期的消耗。
   
 
 #### 获取镜像ID
1. 登录[CCE控制台](https://console.huaweicloud.com/cce2.0/?#/cce/cluster/list)，单击集群名称进入集群，在左侧导航栏中选择"节点管理"。
2. 单击右上角"创建节点"，在"操作系统"选项中选择"私有镜像"。
3. 单击"查看CCE基础镜像信息"，即可复制操作系统的镜像ID。 
   ![](https://support.huaweicloud.com/bestpractice-cce/public_sys-resources/notice_3.0-zh-cn.png)
   不同区域的镜像ID存在区别，切换区域后请重新获取。
   图1获取镜像ID   
   ![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000002531147741.png "点击放大")
   
   
   
 
#### 制作镜像
1. **下载cce-image-builder**
   
   登录ECS执行机，下载cce-image-builder并解压。
   ```
   wget https://cce-north-4.obs.cn-north-4.myhuaweicloud.com/cce-image-builder/cce-image-builder.tgz
   tar zvxf cce-image-builder.tgz
   cd cce-image-builder/
   ```
   ![](https://support.huaweicloud.com/bestpractice-cce/public_sys-resources/note_3.0-zh-cn.png)
   cce-image-builder主要包含：
   - turbo-node.pkr.hcl 镜像制作使用的Packer配置模板，修改请参见[3]。
   
   - scripts/\* 模板预置的CCE镜像制作。建议不要修改，避免影响最终镜像可用性。
   
   - user-scripts/\* **模板预置的自定义包脚本目录**。以example.sh为例，制作自定义镜像时将自动上传至临时服务器并执行。
   
   - user-packages/\* **模板预置的自定义包目录**。制作自定义镜像时，以example.package为例，制作自定义镜像时将自动上传至临时服务器的/tmp/example.package路径。
    
   
   
2. **安装Packer**
   
   手动下载并安装[HashiCorp Packer](https://developer.hashicorp.com/packer)，更多操作详情请参考[官方指导](https://learn.hashicorp.com/tutorials/packer/get-started-install-cli)。
   ![](https://support.huaweicloud.com/bestpractice-cce/public_sys-resources/note_3.0-zh-cn.png)
   Packer版本要求：packer = 1.10.0
   以Huawei Cloud EulerOS 2.0执行机为例，执行如下命令安装packer：
   ```
   wget https://releases.hashicorp.com/packer/1.10.0/packer_1.10.0_linux_amd64.zip
   unzip packer_1.10.0_linux_amd64.zip
   cp -f packer /usr/bin/packer
   ```
   
   
3. **定义Packer模板参数**
   
   cce-image-builder/turbo-node.pkr.hcl文件中定义了packer构建镜像的过程，涉及的参数字段如下。关于pkr.hcl文件更详细的说明请参考[Packer官网文档](https://developer.hashicorp.com/packer/docs)。
   ![](https://support.huaweicloud.com/bestpractice-cce/public_sys-resources/note_3.0-zh-cn.png)
   - ***variables/variable***
     *变量定义。turbo-node.pkr.hcl中主要定义了构建所需填写的参数，支持用户按需修改或填写，参数定义请参见 [表1]。*
     
   
   - ***packer***
     *packer模块定义。其中required_plugins定义了Packer的插件依赖，包括插件来源与插件版本范围，packer init时会自动下载插件并初始化。修改如下：*
     ```
     packer {
       required_plugins {
         huaweicloud = {
           version = ">= 1.0.4"
           source  = "github.com/huaweicloud/huaweicloud"
         }
       }
     }
     ```
     
   
   - ***source***
     *source定义。通过引用上述定义的变量，自动配置插件创建ECS所需的参数，无需用户手动填写。*
     
   
   - ***build***
     *build定义* *。按顺序从上到下依* *次执行，支持文件上传file模块、脚本执行shell模块等常用模块，对应的脚本及文件分别存放在cce-image-builder下user-scripts和user-packages目录。*
     *样例参考：*
     ```
     build {
       sources = ["source.huaweicloud-ecs.builder"]
     # Example：
       provisioner "file" {
         source      = "<source file path>"
         destination = "<destination file path>"
       }
       provisioner "shell" {
         scripts = [
           "<source script file: step1.sh>",
           "<source script file: step2.sh>"
         ]
       }
       provisioner "shell" {
         inline = ["echo foo"]
       }
     }
     ```
     
    
   
   
4. **设置环境变量**
   
   在执行机上设置以下环境变量：
   ```
   export REGION_NAME=xxx
   export IAM_ACCESS_KEY=xxx
   export IAM_SECRET_KEY=xxx
   export ECS_VPC_ID=xxx
   export ECS_NETWORK_ID=xxx
   export ECS_SECGRP_ID=xxx
   export CCE_SOURCE_IMAGE_ID=xxx
   export PKR_VAR_ecs_flavor=xxx
   ```
    表1variables配置参数说明 
   | 参数                  | 参数说明              | 备注                                                                                                                                                                                                           |
   |:---|:---|:---|
   | REGION_NAME         | 所属项目区域。           | 请在[我的凭证](https://console.huaweicloud.com/iam/?locale=zh-cn#/mine/apiCredential)下查看所属区域。                                                                                                                      |
   | IAM_ACCESS_KEY      | 用户认证凭据Access Key。 | 建议临时申请，制作完成后删除。                                                                                                                                                                                              |
   | IAM_SECRET_KEY      | 用户认证凭据Secret Key。 | 建议临时申请，制作完成后删除。                                                                                                                                                                                              |
   | ECS_VPC_ID          | 虚拟私有云ID。          | 临时ECS服务器使用，需要与执行机一致。                                                                                                                                                                                         |
   | ECS_NETWORK_ID      | 子网的网络ID。          | 临时ECS服务器使用，建议与执行机一致，非子网的子网ID。                                                                                                                                                                                |
   | ECS_SECGRP_ID       | 安全组ID。            | 临时ECS服务器使用，该安全组入方向的22端口需要放通执行机的公网IP，保证执行机可通过SSH登录临时服务器。                                                                                                                                                      |
   | CCE_SOURCE_IMAGE_ID | CCE服务的最新节点镜像ID。   | 请参考[获取镜像ID]。                                                                                                                                                  |
   | PKR_VAR_ecs_flavor  | 临时ECS服务器的规格。      | 请填写CCE支持的节点规格，建议规格为2U4G及以上。关于规格名称详情请参见[规格清单（X86）](https://support.huaweicloud.com/productdesc-ecs/zh-cn_topic_0159822360.html)及[规格清单（鲲鹏）](https://support.huaweicloud.com/productdesc-ecs/ecs_01_0066.html)。 |
      
   备注：其他参数通常无需配置，默认即可。如需修改，可以参考*turbo-node.pkr.hcl*中variable定义中的description描述通过环境变量配置。
   以ECS规格变量ecs_az为例，未指定时选择随机可用区，如需指定可以按照如下格式通过环境变量配置。其他参数类似。
   ```
   # export PKR_VAR_<variable name>=<variable value>
   export PKR_VAR_ecs_az=xxx
   ```
   
   
5. **设置自定义脚本及文件**
   
   参考pkr.hcl文件中[build]字段定义的file和shell模块，编写对应的脚本及文件，并分别存放在cce-image-builder下的user-scripts和user-packages目录。
   ![](https://support.huaweicloud.com/bestpractice-cce/public_sys-resources/notice_3.0-zh-cn.png)
   自定义镜像时，请**谨慎修改内核参数** ，部分内核参数过大或者过小时都会影响系统运行效率，参考值请参见[修改节点内核参数](https://support.huaweicloud.com/usermanual-cce/cce_10_0412.html)。
   已知存在影响的内核参数有：tcp_keepalive_time、tcp_max_tw_buckets、somaxconn、max_user_instances、max_user_watches、netdev_max_backlog、net.core.wmem_max、net.core.rmem_max。
   如修改节点内核参数，请您在测试环境中自行完成充分的测试验证，再应用于生产环境。
   
   
6. **制作自定义镜像**
   
   定制修改结束后，执行以下命令制作镜像并等待镜像制作完成，通常需要耗时3\~5min。
   ```
   make image
   ```
   ![](https://support.huaweicloud.com/bestpractice-cce/public_sys-resources/note_3.0-zh-cn.png)
   构建封装脚本packer.sh中，
   - 隐私和安全考虑，默认关闭了packer自动访问hashicorp.com检查版本的功能。
     ```
     export CHECKPOINT_DISABLE=false
     ```
     
   
   - 构建过程可见性与可追溯考虑，默认开启了debugging详细日志，并指定了本地packer构建日志packer_{timestamp}.log以在构建时打包至镜像/var/log/目录。如涉及敏感信息，移除相关逻辑即可。
     ```
     export PACKER_LOG=1
     export PACKER_BUILD_TIMESTAMP=$(date +%Y%m%d%H%M%S)
     export PACKER_LOG_PATH="packer_$PACKER_BUILD_TIMESTAMP.log"
     ```
     
   
   
   更多packer配置详细参见[官网说明](https://developer.hashicorp.com/packer/docs/configure)。
   执行结束日志：
   ![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000001162973231.png "点击放大")
   如果出现packer插件报错的情况，请参见[常见问题]处理。
   
   
7. **构建文件清理**
   
   清理执行机上构建文件，主要涉及turbo-node.pkr.hcl中认证凭据清理。
   - 建议直接释放执行机，如认证凭据为临时申请建议直接删除；
   
   - 如需自动构建，建议自行在配置文件中添加post-processor实现相关功能。
    
   
   
 
 #### 常见问题
- 执行packer制作镜像过程，会自动从github获取最新Huawei Cloud ECS开源插件。此过程会由于网络环境原因导致获取失败，如下所示。 ![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000001240446507.png "点击放大")
  该问题可以通过如下两种方案解决：
  - 在网络环境相对较优的香港等区域创建执行机，对接到原区域创建自定义镜像，例如北京4： export REGION_NAME=cn-north-4
    
  
  - 手动下载对应插件并初始化至对应本地插件路径。 插件对应github发布地址为：<https://github.com/huaweicloud/packer-plugin-huaweicloud/releases>
    以x86执行机为例，下载的插件为packer-plugin-huaweicloud_v1.0.4_x5.0_linux_amd64.zip，参考如下命令进行初始化：
    ```
    PLUGIN_PATH="$HOME/.packer.d/plugins/github.com/huaweicloud/huaweicloud"
    mkdir -p $PLUGIN_PATH
    unzip packer-plugin-huaweicloud_v1.0.4_x5.0_linux_amd64.zip -d /tmp/
    cp /tmp/packer-plugin-huaweicloud_v1.0.4_x5.0_linux_amd64 $PLUGIN_PATH/
    sha256sum /tmp/packer-plugin-huaweicloud_v1.0.4_x5.0_linux_amd64 | awk '{print $1}' > $PLUGIN_PATH/packer-plugin-huaweicloud_v1.0.4_x5.0_linux_amd64_SHA256SUM
    ll $PLUGIN_PATH/*
    ```
    再执行make image命令制作镜像。
    
   
- 如果出现报错PublicIp type is invalid，请查看不同环境EIP的type类型（参见[申请EIP](https://support.huaweicloud.com/api-eip/eip_api_0001.html#eip_api_0001__request_CreatePublicipOption)），然后执行**export PKR_VAR_eip_type='xxx'** 后再进行镜像制作。
  例如：
  ```
  export PKR_VAR_eip_type='5_bgp'
  ```
  
- 如果出现错误码Ecs.0019，错误信息为Flavor xxxx is abandoned，可能是该规格在对应可用区不可用，请重试或者在turbo-node.pkr.hcl文件中更换规格即可。 ![](https://support.huaweicloud.com/bestpractice-cce/zh-cn_image_0000001833425641.png "点击放大")
  
- 如果出现错误信息为no such host，可能是由于当前IAM域名无法解析。
  请在执行机上设置以下环境变量，其中*{IAM endpoint}* 为当前区域的IAM域名。
  ```
  export PKR_VAR_auth_url='{IAM endpoint}'
  ```
  
 
