什么是Packer

Packer是HashiCorp推出的一款工具,旨在提供简易的方式自动化构建镜像。通过Packer,你只需要在配置文件中指明镜像构建所需的基本信息及期望安装到镜像中的软件及配置,即可通过自动化脚本构建所需的镜像。由于构建镜像的过程被固化成了配置文件,每一个步骤都清晰可见易于回溯,无需担心多次构建得到的镜像存在不一致。且镜像构建配置化后,将为测试和更新镜像带来极大的便利,大大降低运维和管理镜像的成本。

在具体介绍Packer的使用方法之前,我们先来看下以前在阿里云ECS上如何手动创建一个自定义镜像。如果对这个流程已非常熟悉,可以直接跳到通过Packer构建镜像一节。

注意:后续操作会创建一些收费资源,请注意释放和清理,如实例、公网IP、快照等。

实例规格和镜像会随着时间的推移不断更新,本文后续提到的一些规格和镜像可能会在未来下线,所以具体操作流程可以根据实际情况选择不同的规格、镜像或者其他实例相关的资源。

手动创建自定义镜像

简单起见,假设我们需要在阿里云北京地域构建一个CentOS 7.3的镜像,其中需要安装redis,其他方面无特定需求,则整个创建步骤如下所示:

  1. 打开ECS售卖页,从上到下依次选择按量付费 => 华北2(北京) => ecs.t5-lc1m1.small => 公共镜像CentOS 7.3 64位,点击页面右下方下一步:网络和安全组
  2. 继续选择专有网络 => 公网带宽 => 安全组,点击页面右下方下一步:系统配置
  3. 继续选择秘钥对,如不存在需要新建秘钥对,便于后续通过秘钥连接实例。其余配置保持默认,点击页面右下方确认订单创建实例
  4. 购买流程完成后,可在ECS控制台华北2(北京)地域看到新建的实例,稍等片刻待实例状态变成运行中。
  5. 连接并登陆新创建的实例,通过命令行安装redis。连接方式可参照使用SSH密钥对连接Linux实例一文。
  6. 安装完成后回到控制台实例列表,点击对应实例右侧更多 => 磁盘和镜像 => 创建自定义镜像,等待自定义镜像创建完成。
  7. 最后清理不需要的资源,释放实例、公网IP(如果是弹性公网IP)。如果需要,可以进一步删除VPC、安全组等仅用于测试的资源。

上述过程实际上简化了镜像内最为关键的软件及其配置部分,实际上该过程会随着镜像内需预装的软件及其配置不断扩充变得愈发复杂。通过人肉保证每一次操作都准确无误,和之前毫无偏差,会是一件非常困难的事情,更别提之后的维护和更新了。接下来我们将看到如何通过Packer自动化地完成上述镜像构建构成。

通过Packer构建镜像

如上所述,Packer通过配置文件记录镜像构建过程中所需的所有细节。如下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"]}]
}

其中:

  1. variables中定义了builders中会用到的两个变量access_keysecret_key。 这两个变量的值取自运行时的环境变量,这是为了防止意外将AK写到配置文件中造成遗漏。
  2. builders中表明使用的是Alicloud Image Builder。该Builder用于在阿里云上创建自定义镜像。其他则为创建镜像所需要的一些信息,包括AK、地域、镜像名称、源镜像、登陆名、实例规格、公网计费方式和IO优化。
  3. provisioners定义了需要在实例内执行的操作。这里用到Shell Provisioner,表示在连接实例后执行一段shell脚本安装redis。

安装Packer的过程详见官网Getting Started,此处不再赘述。假设Packer已经安装成功,执行packer build alicloud.json完成镜像构建,整个构建过程需要耗费一些时间,构建过程中产生的日志如下所示:

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 xxxalicloud-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-shell260049331alicloud-ecs: Loaded plugins: fastestmirroralicloud-ecs: Determining fastest mirrorsalicloud-ecs: Resolving Dependenciesalicloud-ecs: --> Running transaction checkalicloud-ecs: ---> Package redis.x86_64 0:3.2.12-2.el7 will be installedalicloud-ecs: --> Processing Dependency: libjemalloc.so.1()(64bit) for package: redis-3.2.12-2.el7.x86_64alicloud-ecs: --> Running transaction checkalicloud-ecs: ---> Package jemalloc.x86_64 0:3.6.0-1.el7 will be installedalicloud-ecs: --> Finished Dependency Resolutionalicloud-ecs:alicloud-ecs: Dependencies Resolvedalicloud-ecs:alicloud-ecs: ================================================================================alicloud-ecs:  Package           Arch            Version                  Repository     Sizealicloud-ecs: ================================================================================alicloud-ecs: Installing:alicloud-ecs:  redis             x86_64          3.2.12-2.el7             epel          544 kalicloud-ecs: Installing for dependencies:alicloud-ecs:  jemalloc          x86_64          3.6.0-1.el7              epel          105 kalicloud-ecs:alicloud-ecs: Transaction Summaryalicloud-ecs: ================================================================================alicloud-ecs: Install  1 Package (+1 Dependent package)alicloud-ecs:alicloud-ecs: Total download size: 648 kalicloud-ecs: Installed size: 1.7 Malicloud-ecs: Downloading packages:alicloud-ecs: --------------------------------------------------------------------------------alicloud-ecs: Total                                              2.2 MB/s | 648 kB  00:00alicloud-ecs: Running transaction checkalicloud-ecs: Running transaction testalicloud-ecs: Transaction test succeededalicloud-ecs: Running transactionalicloud-ecs:   Installing : jemalloc-3.6.0-1.el7.x86_64                                  1/2alicloud-ecs:   Installing : redis-3.2.12-2.el7.x86_64                                    2/2alicloud-ecs:   Verifying  : redis-3.2.12-2.el7.x86_64                                    1/2alicloud-ecs:   Verifying  : jemalloc-3.6.0-1.el7.x86_64                                  2/2alicloud-ecs:alicloud-ecs: Installed:alicloud-ecs:   redis.x86_64 0:3.2.12-2.el7alicloud-ecs:alicloud-ecs: Dependency Installed:alicloud-ecs:   jemalloc.x86_64 0:3.6.0-1.el7alicloud-ecs:alicloud-ecs: Complete!
==> alicloud-ecs: Stopping instance: i-xxx
==> alicloud-ecs: Waiting instance stopped: i-xxx
==> alicloud-ecs: Creating image: packer_basicalicloud-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

上述日志较为完整得给出了Packer构建过程中执行的每一个步骤:从校验参数、创建临时资源、预安装软件、创建目标资源到最后的释放临时资源,所有的过程一气呵成,而这仅仅只需预装好Packer以及定义好相应的配置文件。接下来将针对一些实际DevOps场景会用到的一些配置进行必要的说明以供参考,更多参数和样例详见Alicloud Image Builder和Examples。

DevOps常用配置

镜像标签(tags)

当所要管理的镜像达到一定的数量时,对镜像进行适当的标记就变得很有必要,比如记录镜像版本号、镜像包含的应用类型等。通过为镜像打上标签是达到上述目的绝佳手段,阿里云Builder提供了tags参数以支持此类需求。如下配置文件将为最终生成的镜像和对应的快照打上version=v1.0.0app=web两个标签。

{"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","tags": {"version": "v1.0.0","app": "web"}}]
}

控制台镜像列表页面和API DescribeImages均支持查询镜像时返回标签以及根据标签过滤镜像。但为镜像打上标签真正强大的地方在于能够和Terraform一起为标准化的DevOps流程提供支持。Terraform的内容超出了本文讨论的范畴,在此不再展开。这里推荐Alibaba Cloud DevOps tutorials系列教程,其中讲解了一些企业DevOps过程中的最佳实践,其中涉及Terraform和Packer的内容参见Continuous Delivery一节。

让镜像只包含系统盘(image_ignore_data_disks)

默认情况下Packer直接从实例创建镜像,而从实例创建镜像时如果包含数据盘,则镜像会同时包含数据盘快照。在构建过程中创建包含数据盘的实例通常有两种方式:一是通过image_disk_mappings设置数据盘相关参数,二是选择默认带有数据盘的实例规格。其中后者涉及的规格包含的数据盘大多为本地盘,如ecs.d1ne.2xlarge,而本地盘当前并不支持创建快照,进而也无法直接通过此类实例创建镜像。即便如此,很多场景下为了满足某些方面的性能需求,用户依然会选择这类实例规格,但实际上数据盘部分并不是必须的。此时就可以在配置文件中加上"image_ignore_data_disks": "true"实现只基于系统盘来创建镜像。

设置快照超时时间(wait_snapshot_ready_timeout)

镜像依赖于快照,而快照的创建时间依赖于磁盘大小。当磁盘较大时,创建快照所需要的时间也会相应的增加。默认情况下,轮询快照的超时时间为3600s。如果由于磁盘太大导致超时,则可以通过wait_snapshot_ready_timeout调大超时时间。

通过私网IP连接实例(ssh_private_ip)

默认情况下,Packer创建EIP并绑定到实例上,然后通过EIP对应的公网IP连接实例安装软件或执行命令。但在一些场景下,用户可以直接通过私网IP连接实例,此时公网IP就会显得多余。此时可以通过设置"ssh_private_ip": "true",该设置下Packer将不会分配EIP或者公网IP,而是直接尝试通过私网IP连接实例。

停止实例选项(disable_stop_instance)

默认情况下,Packer在执行完provisioners后,会先停止实例然后创建镜像。但如果设置了"disable_stop_instance": "true",Packer将不会主动去停止实例,而是假设配置中提供的指令会自行停止实例,以满足一些特殊场景,如Sysprep一个Windows实例。Sysprep的一个使用场景可参照修改Windows实例SID以搭建域环境。

通过UserData启用WinRM

出于安全考虑,Windows镜像默认关闭了WinRM。但连接Windows实例及之后在实例内部执行命令都依赖于WinRM,所以需要在实例创建时启用WinRM,而这可以通过UserData来完成。启用WinRM的Userdata文件内容详见winrm_enable_userdata.ps1,Packer则通过配置user_data_file指定UserData文件路径。跟WinRM相关的参数还包括"communicator": "winrm""winrm_port": 5985"winrm_username": "Administrator""winrm_password": "Test1234",分别表示通过WinRM连接实例、连接端口为5985、连接时使用Administrator账户,密码采用Test1234。以下配置文件提供了基于Windows的一个简单示例:

{"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_test","source_image":"win2008r2_64_ent_sp1_zh-cn_40G_alibase_20181220.vhd","instance_type":"ecs.n1.tiny","io_optimized":"true","internet_charge_type":"PayByTraffic","image_force_delete":"true","communicator": "winrm","winrm_port": 5985,"winrm_username": "Administrator","winrm_password": "Test1234","user_data_file": "examples/alicloud/basic/winrm_enable_userdata.ps1"}],"provisioners": [{"type": "powershell","inline": ["dir c:\\"]}]
}

其中image_force_delete表示如果已存在同名镜像则先删除,并假定UserData文件在给定的相对路径下。provisioners内的指令只用做在实例内调用命令的示例,可根据实际情况填写。

从ISO到阿里云镜像

ISO文件需要在线下虚拟化环境安装完成后,生成对应格式的镜像文件再导入到阿里云(当前支持QCOW2、VHD和RAW三种格式的文件导入阿里云)。如果线下环境为qemu,可参照使用Packer创建并导入本地镜像一文。其中包含两个重要的部分,首先需要使用对应虚拟化环境或软件对应的Builder,如上文中使用的是Qemu Builder。其次,通过定义Alicloud Import Post-Processor将前面生成的镜像文件导入到阿里云。

镜像即代码:基于Packer构建阿里云镜像相关推荐

  1. 基于 RocketMQ 构建阿里云事件驱动引擎EventBridge

    简介:阿里云事件总线 EventBridge 作为云上的事件枢纽,最核心的能力是连接.无论是在线业务场景.IoT 场景.还是大数据场景,无论是阿里云.其他云厂商,还是私有 IDC 机房,我们都将提供安 ...

  2. 三步搭建免费无限空间无限速网盘——基于docker与阿里云镜像(B站学习)

    # 前提说明:本博客是参考了B站UP主xausky的视频,包括他的github里的软件,只用于自用后的推广 ## 参考视频:[B站](https://www.bilibili.com/video/BV ...

  3. docker-for-windows配置了阿里云镜像,仍然无法获得链接:(Client.Timeout exceeded while awaiting headers)

    Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while w ...

  4. linux配置docker源,国内加速镜像(注册阿里云镜像)

    docker源配置,国内加速地址 由于公司进行网络管控,唯一能连上的就是清华镜像 更改配置文件 vi /etc/docker/daemon.json //配置docker国内源 {"regi ...

  5. Packer创建阿里云本地镜像

    Packer创建阿里云本地镜像 通过手工创建在本地镜像,并且上传到云环境是一个复杂而易错的过程,而packer的出现极大的降低了这种复杂度,本文详细了讲解了如何在ubuntu(16.04或者更高版本) ...

  6. 基于树莓派+传感器+阿里云IoT的智能家居管理(代码实现)

    视频教程已经放在B站 请大家狠狠地三连我 虽然我没有稚晖君那么强 教程!基于树莓派+传感器+阿里云IoT的智能家居管理(2) 主文件 #!/usr/bin/python3import aliLink, ...

  7. 基于Javaweb和阿里云服务器的用户管理平台

    基于Javaweb和阿里云服务器的用户管理平台 技术支持: 视图层:js+html+css 业务层:servlet 持久层:mysql5.6 项目介绍:myEclipse负责开发javaweb项目,t ...

  8. 最干净利索且下载快速的maven3.6.3安装方式和阿里云镜像

    先说效果,构建Spring Cloud初始项目只用了35s,之前我没用这个镜像半个小时没出来 直接官网下载 http://maven.apache.org/docs/3.5.2/release-not ...

  9. 基于MFC与阿里云制作简易发送短信

    ***~~ 做到最后可能会只是不能识别汉字,但是能识别英文和数字,有待改进的地方` ` ~~ *** # 详细步骤见如下 一. 新建一个MFC项目:打开VS2013,文件->新建->项目 ...

最新文章

  1. BrupSuite渗透测试笔记(十一)
  2. 在centos上安装最新的glibc
  3. lucene倒排索引瘦身的一些实验——merge的本质是减少cfx文件 变为pos和doc;存储term vector多了tvx和tvd文件有337M...
  4. 5分钟上手写ECharts的第一个图表
  5. MaxScript Slider/Timer
  6. WSL端口映射到win
  7. 吃货莫跑小小程序冲刺07
  8. WCF自定义地址路由映射(不用svc文件)
  9. 2014年4月5日 java集合框架总结2--List接口及其子类
  10. 《MySQL——索引笔记》
  11. ubuntu1804系统设置在哪里_电销呼叫系统CRM功能设计
  12. centos php 开启mysql扩展_CentOS 7下部署php7.1和开启MySQL扩展的方法教程
  13. 【MATLAB】基于支持向量机的简单图像识别实现
  14. isee看图精灵下载
  15. 基因重组-冲刺日志(第一天)
  16. 弹性盒子flex布局实现骰子六个面并让骰子3D空间旋转
  17. github问题之Unable to retrieve your user info from the server
  18. (二)UPF之电压域、低功耗模式编码(Primary Supply Set、Power State)
  19. 接口中的变量为什么不能是普通变量,只能是static final
  20. .bat文件实现一个简单的http请求工具(支持get和post请求)

热门文章

  1. 解决“The name ‘x:0‘ refers to a Tensor which does not exist. The operation, ‘x‘, does not exist in the
  2. 惊!马云爸爸要演电影了!居然还是男一号!
  3. DVWA 之 CSRF
  4. 苹果电脑自动更新怎么关闭 苹果系统关闭自动更新
  5. 学习笔记(04):Python 面试100讲(基于Python3.x)-请详细描述print函数的用法
  6. 属于mysql安装目录中_下面选项中,属于 MySQL 安装目录中包含的文件是()_Flash 二维动画设计与制作答案_学小易找答案...
  7. BACnet/IP之BACnet4j学习VTS创建虚拟设备及点位测试03
  8. springboot整合springsecurity时出现了localhost将您重定向次数过多 循环地址错误解决
  9. 宝塔安装sqlserver_宝塔面板安装SQLServer图文教程
  10. 基于SqlServer实现微信推送消息