基础架构即代码入门介绍-packer

基础设施即代码的意思是把基础设施的实现方式写成代码。告别手工配置各类资源而采用基础设施即代码的方式,可以获得多种好处:

  • 可重复-可以随时重新创建基础架构,例如在灾备环境重新创建生产环境。
  • 可一致性-在各个不同的环境之间实现最大程度的一致性,减少环境差异导致的生产、测试效率下降。
  • 可追溯回滚-环境的所有变化都通过代码实现,而代码的变化是可以追溯回滚的。
  • 快速-由于基础架构是通过代码实现的,那么改变或者重建系统时就会非常快,是敏捷开发和DevOps中必不可少的一步。

Packer可以说是基础设施即代码的第一步。本入门介绍会帮助您了解Packer是什么,解决什么问题,有什么好处,以及怎样开始使用Packer。如果您已经对Packer有了了解,那么这个链接可以提供Packer所有功能的详细参数。

Packer介绍

Packer是用一个配置文件,在多种云计算平台上创建完全一致镜像的开源工具。Packer是由HashiCorp在2013年左右推出的。Packer可以在各种主流操作系统上运行,可以高速、并行在多种云平台上创建镜像。Packer并不能取代puppet或者Chef之类的主机配置工具,而是互为补充-Packer在创建镜像时,可以调用这些工具在基础镜像上安装、配置软件。

镜像是指一个预先安装了软件、配置好了的操作系统,这个镜像可以被用开快速创建云主机。每个云平台通常有不同的镜像格式。关于腾讯云镜像的概述,可以参考腾讯云的文档

Packer解决什么问题

使用预先准备好的镜像有很多好处,但是很多人都不太愿意使用这种方式,原因是创建和管理镜像实在是太复杂了。所以在Packer出现之前,镜像都是人工在云平台上搭建一个操作系统,然后通过云平台的功能转换成镜像而创建的,这对运维团队的速度影响很大,因此大家都不怎么使用镜像。

Packer的出现解决了这些问题。Packer只是一个命令行工具,易于通过终端使用,也可以很简单的放到自动化工具里边,用来自动创建任何类型的主机镜像。

使用Packer的好处

快速的基础架构实施:Packer创建的镜像可以让运维人员几秒钟内创建一个预先配置好的云主机,而不是几分钟甚至几个小时。这一好处不但对生产环境,也对测试及开发环境有益。

多平台兼容:由于Packer可以为多个平台创建完全一致的镜像,你可以在腾讯云上运行生产环境,在自己的私有云里边运行测试环境,在自己的vmware虚拟机里运行开发环境。而每个环境都完全一致。

提高稳定性:Packer在创建镜像时安装并配置软件。安装或者配置步骤中的问题会在这时候发现,而不是在穿件云主机的时候。

提高可测试性:镜像创建完成后,可以很快的启动一个云主机并对其进行测试。如果测试通过,那就可以相信,通过这个镜像创建的云主机都会通过测试。

具体用例

现在您已经了解到了Packer是干什么的,有什么好处。下边是一些具体的实例。

在持续开发、持续交付Pipeline里使用Packer

Packer是用命令行驱动的,而且不需要很多资源。因此可以很容易把Packer放到持续交付的pipeline里,创建镜像。在持续交付随后的步骤中,可以对此镜像进行测试,看基础设施的变化是不是能够通过测试。如果测试通过,那就可以相信在这一镜像基础上搭建的云主机也会工作。这对基础设施变化的稳定性和可测试性提供了基础。

保证开发与生产环境的一致性

Packer可以让开发与生产环境尽量一致。由于Packer可以为多个平台创建完全一致的镜像,你可以在腾讯云上运行生产环境,在自己的私有云里边运行测试环境,在自己的vmware虚拟机里运行开发环境。而每个环境都完全一致。把这一用例与前边的持续交付结合在一起,用户可以保障开发环境与生产环境尽量一致,从而减少出问题的可能。

例子一在腾讯云生成一个自定义centOS 7.6镜像,安装nginx

首先创建一个tencent-nginx.json文件,内容如下:

{
  "variables": {
    "tc_secret_id": "{{env `TENCENTCLOUD_ACCESS_KEY`}}",
    "tc_secret_key": "{{env `TENCENTCLOUD_SECRET_KEY`}}"
  },
  "builders": [
    {
    "type": "tencentcloud-cvm",
    "secret_id": "{{user `tc_secret_id`}}",
    "secret_key": "{{user `tc_secret_key`}}",
    "region": "ap-guangzhou",
    "zone": "ap-guangzhou-3",
    "instance_type": "S2.SMALL1",
    "disk_type": "CLOUD_PREMIUM",
    "associate_public_ip_address": true,
    "source_image_id": "img-9qabwvbn",
    "ssh_username" : "root",
    "image_name": "nginx-service-v1"
  }
  ],
  "provisioners": [{
    "type": "shell",
    "inline": [
      "rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm",
      "yum install -y nginx",
      "systemctl enable nginx",
      "systemctl start nginx"
    ]
  }]
}

这段代码一开始,引入了两个变量,分别是tc_secret_id和tc_secret_key,它们的值分别取自环境变量TENCENTCLOUD_ACCESS_KEY和TENCENTCLOUD_SECRET_KEY,这与腾讯云Terraform应用指南中提到设置是一样的。

随后紧跟的是一个builder,这个例子中指定在腾讯云广州大区创建一个自定义镜像nginx-service-v1,该镜像的基础镜像是腾讯云的共有镜像img-9qabwvbn,这个镜像id是从腾讯云控制台查到的,如下图:

getting_image_id_from_tencentcloud_console.png

builder后边是一个provisioner的定义,指定了几个命令行及参数。

随后可以执行:

packer build tencent-nginx.json

我们可以看到:

tencent-cloud-test packer build tencent-nginx.json
tencentcloud-cvm output will be in this color.

    tencentcloud-cvm: Image found: img-9qabwvbn
==> tencentcloud-cvm: Creating temporary keypair: packer_5d3e96e5
==> tencentcloud-cvm: Trying to create a new vpc
==> tencentcloud-cvm: Trying to create a new subnet
==> tencentcloud-cvm: Creating Instance.
==> tencentcloud-cvm: Using ssh communicator to connect: 193.112.98.141
==> tencentcloud-cvm: Waiting for SSH to become available...
==> tencentcloud-cvm: Connected to SSH!
==> tencentcloud-cvm: Provisioning with shell script: /var/folders/zv/c_b0s5gn31bdggpz1r6w5pxr0000gp/T/packer-shell592674642
==> tencentcloud-cvm: warning: /var/tmp/rpm-tmp.TLSKKM: Header V4 RSA/SHA1 Signature, key ID 7bd9bf62: NOKEY
    tencentcloud-cvm: Retrieving http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
    tencentcloud-cvm: Preparing...                          ########################################
    tencentcloud-cvm: Updating / installing...
    tencentcloud-cvm: nginx-release-centos-7-0.el7.ngx      ########################################
==> tencentcloud-cvm: Existing lock /var/run/yum.pid: another copy is running as pid 3431.
    tencentcloud-cvm: Loaded plugins: fastestmirror, langpacks
==> tencentcloud-cvm: Another app is currently holding the yum lock; waiting for it to exit...
==> tencentcloud-cvm:   The other application is: yum
==> tencentcloud-cvm:     Memory :  83 M RSS (488 MB VSZ)
==> tencentcloud-cvm:     Started: Mon Jul 29 14:49:57 2019 - 00:14 ago
==> tencentcloud-cvm:     State  : Running, pid: 3431
    tencentcloud-cvm: Determining fastest mirrors
    tencentcloud-cvm: Resolving Dependencies
    tencentcloud-cvm: --> Running transaction check
    tencentcloud-cvm: ---> Package nginx.x86_64 1:1.16.0-1.el7.ngx will be installed
    tencentcloud-cvm: --> Finished Dependency Resolution
    tencentcloud-cvm:
    tencentcloud-cvm: Dependencies Resolved
    tencentcloud-cvm:
    tencentcloud-cvm: ================================================================================
    tencentcloud-cvm:  Package       Arch           Version                       Repository     Size
    tencentcloud-cvm: ================================================================================
    tencentcloud-cvm: Installing:
    tencentcloud-cvm:  nginx         x86_64         1:1.16.0-1.el7.ngx            nginx         766 k
    tencentcloud-cvm:
    tencentcloud-cvm: Transaction Summary
    tencentcloud-cvm: ================================================================================
    tencentcloud-cvm: Install  1 Package
    tencentcloud-cvm:
    tencentcloud-cvm: Total download size: 766 k
    tencentcloud-cvm: Installed size: 2.7 M
    tencentcloud-cvm: Downloading packages:
    tencentcloud-cvm: Running transaction check
    tencentcloud-cvm: Running transaction test
    tencentcloud-cvm: Transaction test succeeded
    tencentcloud-cvm: Running transaction
    tencentcloud-cvm:   Installing : 1:nginx-1.16.0-1.el7.ngx.x86_64                              1/1
    tencentcloud-cvm: ----------------------------------------------------------------------
    tencentcloud-cvm:
    tencentcloud-cvm: Thanks for using nginx!
    tencentcloud-cvm:
    tencentcloud-cvm: Please find the official documentation for nginx here:
    tencentcloud-cvm: * http://nginx.org/en/docs/
    tencentcloud-cvm:
    tencentcloud-cvm: Please subscribe to nginx-announce mailing list to get
    tencentcloud-cvm: the most important news about nginx:
    tencentcloud-cvm: * http://nginx.org/en/support.html
    tencentcloud-cvm:
    tencentcloud-cvm: Commercial subscriptions for nginx are available on:
    tencentcloud-cvm: * http://nginx.com/products/
    tencentcloud-cvm:
    tencentcloud-cvm: ----------------------------------------------------------------------
    tencentcloud-cvm:   Verifying  : 1:nginx-1.16.0-1.el7.ngx.x86_64                              1/1
    tencentcloud-cvm:
==> tencentcloud-cvm: Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.
    tencentcloud-cvm: Installed:
    tencentcloud-cvm:   nginx.x86_64 1:1.16.0-1.el7.ngx
    tencentcloud-cvm:
    tencentcloud-cvm: Complete!
==> tencentcloud-cvm: Detaching temporary key pair skey-0u57cefv...
==> tencentcloud-cvm: Creating image nginx-service-v1
==> tencentcloud-cvm: Cleaning up 'Instance'
==> tencentcloud-cvm: Cleaning up 'Security Group'
==> tencentcloud-cvm: Cleaning up 'SUBNET'
==> tencentcloud-cvm: Cleaning up 'VPC'
==> tencentcloud-cvm: Deleting temporary keypair...
Build 'tencentcloud-cvm' finished.

==> Builds finished. The artifacts of successful builds are:
--> tencentcloud-cvm: Tencentcloud images(ap-guangzhou: img-411k3pnt) were created:

具体解释:

packer在读取了nginx.json文件后,首先会发现,文件指定要在腾讯云创建一个镜像,因此它会首先在指定的大区上创建一个专门的vpc、子网和ssh密钥,并用配置文件中指定的image id创建一个cvm实例,然后会在实例创建成功后,用ssh密钥链接实例,并运行provisioner里边指定的命令行。命令行都运行成功以后,packer会自动删除该ssh密钥、子网、vpc,关机,并在此基础上生成一个新的自定义镜像。新镜像的id是img-411k3pnt。由于创建新镜像是完全自动的,时间很短,整个过程并不会有很多成本。

实际应用中,packer的provisioner还可以上传并调用脚本,比如下边这个例子可以上传并执行一个叫script.sh的脚本:

{
  "type": "shell",
  "script": "script.sh"
}

用户还可以通过在builder中加入下边一行代码告诉packer,镜像创建成功后拷贝到其它大区:

"image_copy_regions": ["ap-beijing"]

也可以通过修改大区名的方式,在中国和海外的不同大区创建同样的镜像。

还可以同时在腾讯云和aws上创建同一功能的镜像:

tencent-cloud-test cat tencent-aws-nginx.json
{
  "variables": {
    "tc_secret_id": "{{env `TENCENTCLOUD_ACCESS_KEY`}}",
    "tc_secret_key": "{{env `TENCENTCLOUD_SECRET_KEY`}}",
    "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}",
    "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}"
  },
  "builders": [
    {
    "type": "tencentcloud-cvm",
    "secret_id": "{{user `secret_id`}}",
    "secret_key": "{{user `secret_key`}}",
    "region": "ap-guangzhou",
    "zone": "ap-guangzhou-3",
    "instance_type": "S2.SMALL1",
    "disk_type": "CLOUD_PREMIUM",
    "associate_public_ip_address": true,
    "source_image_id": "img-9qabwvbn",
    "ssh_username" : "root",
    "image_name": "nginx-service-v2"
  },
  {
    "type": "amazon-ebs",
    "access_key": "{{user `aws_access_key`}}",
    "secret_key": "{{user `aws_secret_key`}}",
    "source_ami": "ami-033d9e49dbfa14af5",
    "region": "ap-southeast-2",
    "instance_type": "t2.micro",
    "ssh_username": "ec2-user",
    "ami_name": "nginx-service-{{isotime \"2006-01-02\"}}"
  }
  ],
  "provisioners": [{
    "type": "shell",
    "inline": [
      "sudo rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm",
      "sudo yum install -y nginx",
      "sudo systemctl enable nginx",
      "sudo systemctl start nginx"
    ]
  }]
}

注意这个例子中,我们把provisioner中每一个命令行前边都加了sudo,原因是aws上的centos的缺省用户是ec2-user,更改后的命令行可以在腾讯云和aws两者上都运行成功:

tencent-cloud-test packer build tencent-aws-nginx.json
amazon-ebs output will be in this color.
tencentcloud-cvm output will be in this color.

==> amazon-ebs: Prevalidating AMI Name: nginx-service-2019-07-29
    amazon-ebs: Found Image ID: ami-033d9e49dbfa14af5
==> amazon-ebs: Creating temporary keypair: packer_5d3ebd78-4ab8-61ba-5543-df661f8e0b2c
==> amazon-ebs: Creating temporary security group for this instance: packer_5d3ebd7a-f32c-7c33-d654-9b2566ad68bf
==> amazon-ebs: Authorizing access to port 22 from [0.0.0.0/0] in the temporary security groups...
    tencentcloud-cvm: Image found: img-9qabwvbn
==> tencentcloud-cvm: Creating temporary keypair: packer_5d3ebd78
==> amazon-ebs: Launching a source AWS instance...
==> amazon-ebs: Adding tags to source instance
    amazon-ebs: Adding tag: "Name": "Packer Builder"
==> tencentcloud-cvm: Trying to create a new vpc
    amazon-ebs: Instance ID: i-0b9fcf04c7bc20e18
==> amazon-ebs: Waiting for instance (i-0b9fcf04c7bc20e18) to become ready...
==> tencentcloud-cvm: Trying to create a new subnet
==> tencentcloud-cvm: Creating Instance.
==> amazon-ebs: Using ssh communicator to connect: 54.252.137.172
==> amazon-ebs: Waiting for SSH to become available...
==> tencentcloud-cvm: Using ssh communicator to connect: 129.204.76.72
==> tencentcloud-cvm: Waiting for SSH to become available...
==> amazon-ebs: Connected to SSH!
==> amazon-ebs: Provisioning with shell script: /var/folders/zv/c_b0s5gn31bdggpz1r6w5pxr0000gp/T/packer-shell877817097
==> amazon-ebs: warning: /var/tmp/rpm-tmp.AaWCob: Header V4 RSA/SHA1 Signature, key ID 7bd9bf62: NOKEY
==> amazon-ebs: warning: waiting for transaction lock on /var/lib/rpm/.rpm.lock
    amazon-ebs: Retrieving http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
    amazon-ebs: Preparing...                          ########################################
    amazon-ebs: Updating / installing...
    amazon-ebs: nginx-release-centos-7-0.el7.ngx      ########################################
    amazon-ebs: Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
    amazon-ebs: Resolving Dependencies
    amazon-ebs: --> Running transaction check
    amazon-ebs: ---> Package nginx.x86_64 1:1.16.0-1.el7.ngx will be installed
    amazon-ebs: --> Finished Dependency Resolution
    amazon-ebs:
    amazon-ebs: Dependencies Resolved
    amazon-ebs:
    amazon-ebs: ================================================================================
    amazon-ebs:  Package       Arch           Version                       Repository     Size
    amazon-ebs: ================================================================================
    amazon-ebs: Installing:
    amazon-ebs:  nginx         x86_64         1:1.16.0-1.el7.ngx            nginx         766 k
    amazon-ebs:
    amazon-ebs: Transaction Summary
    amazon-ebs: ================================================================================
    amazon-ebs: Install  1 Package
    amazon-ebs:
    amazon-ebs: Total download size: 766 k
    amazon-ebs: Installed size: 2.7 M
    amazon-ebs: Downloading packages:
    amazon-ebs: Running transaction check
    amazon-ebs: Running transaction test
    amazon-ebs: Transaction test succeeded
    amazon-ebs: Running transaction
    amazon-ebs:   Installing : 1:nginx-1.16.0-1.el7.ngx.x86_64                              1/1
    amazon-ebs: ----------------------------------------------------------------------
    amazon-ebs:
    amazon-ebs: Thanks for using nginx!
    amazon-ebs:
    amazon-ebs: Please find the official documentation for nginx here:
    amazon-ebs: * http://nginx.org/en/docs/
    amazon-ebs:
    amazon-ebs: Please subscribe to nginx-announce mailing list to get
    amazon-ebs: the most important news about nginx:
    amazon-ebs: * http://nginx.org/en/support.html
    amazon-ebs:
    amazon-ebs: Commercial subscriptions for nginx are available on:
    amazon-ebs: * http://nginx.com/products/
    amazon-ebs:
    amazon-ebs: ----------------------------------------------------------------------
    amazon-ebs:   Verifying  : 1:nginx-1.16.0-1.el7.ngx.x86_64                              1/1
    amazon-ebs:
    amazon-ebs: Installed:
    amazon-ebs:   nginx.x86_64 1:1.16.0-1.el7.ngx
    amazon-ebs:
    amazon-ebs: Complete!
==> amazon-ebs: Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.
==> amazon-ebs: Stopping the source instance...
    amazon-ebs: Stopping instance
==> amazon-ebs: Waiting for the instance to stop...
==> tencentcloud-cvm: Connected to SSH!
==> tencentcloud-cvm: Provisioning with shell script: /var/folders/zv/c_b0s5gn31bdggpz1r6w5pxr0000gp/T/packer-shell791398033
==> amazon-ebs: Creating AMI nginx-service-2019-07-29 from instance i-0b9fcf04c7bc20e18
    amazon-ebs: AMI: ami-05d743427e2152bb5
==> amazon-ebs: Waiting for AMI to become ready...
    tencentcloud-cvm: Retrieving http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
    tencentcloud-cvm: Preparing...                          ########################################
    tencentcloud-cvm: Updating / installing...
==> tencentcloud-cvm: warning: /var/tmp/rpm-tmp.C8nUSC: Header V4 RSA/SHA1 Signature, key ID 7bd9bf62: NOKEY
    tencentcloud-cvm: nginx-release-centos-7-0.el7.ngx      ########################################
    tencentcloud-cvm: Loaded plugins: fastestmirror, langpacks
    tencentcloud-cvm: Determining fastest mirrors
    tencentcloud-cvm: Resolving Dependencies
    tencentcloud-cvm: --> Running transaction check
    tencentcloud-cvm: ---> Package nginx.x86_64 1:1.16.0-1.el7.ngx will be installed
    tencentcloud-cvm: --> Finished Dependency Resolution
    tencentcloud-cvm:
    tencentcloud-cvm: Dependencies Resolved
    tencentcloud-cvm:
    tencentcloud-cvm: ================================================================================
    tencentcloud-cvm:  Package       Arch           Version                       Repository     Size
    tencentcloud-cvm: ================================================================================
    tencentcloud-cvm: Installing:
    tencentcloud-cvm:  nginx         x86_64         1:1.16.0-1.el7.ngx            nginx         766 k
    tencentcloud-cvm:
    tencentcloud-cvm: Transaction Summary
    tencentcloud-cvm: ================================================================================
    tencentcloud-cvm: Install  1 Package
    tencentcloud-cvm:
    tencentcloud-cvm: Total download size: 766 k
    tencentcloud-cvm: Installed size: 2.7 M
    tencentcloud-cvm: Downloading packages:
==> amazon-ebs: Terminating the source AWS instance...
==> amazon-ebs: Cleaning up any extra volumes...
==> amazon-ebs: No volumes to clean up, skipping
==> amazon-ebs: Deleting temporary security group...
==> amazon-ebs: Deleting temporary keypair...
Build 'amazon-ebs' finished.
    tencentcloud-cvm: Running transaction check
    tencentcloud-cvm: Running transaction test
==> tencentcloud-cvm: Warning: RPMDB altered outside of yum.
    tencentcloud-cvm: Transaction test succeeded
    tencentcloud-cvm: Running transaction
    tencentcloud-cvm:   Installing : 1:nginx-1.16.0-1.el7.ngx.x86_64                              1/1
    tencentcloud-cvm: ----------------------------------------------------------------------
    tencentcloud-cvm:
    tencentcloud-cvm: Thanks for using nginx!
    tencentcloud-cvm:
    tencentcloud-cvm: Please find the official documentation for nginx here:
    tencentcloud-cvm: * http://nginx.org/en/docs/
    tencentcloud-cvm:
    tencentcloud-cvm: Please subscribe to nginx-announce mailing list to get
    tencentcloud-cvm: the most important news about nginx:
    tencentcloud-cvm: * http://nginx.org/en/support.html
    tencentcloud-cvm:
    tencentcloud-cvm: Commercial subscriptions for nginx are available on:
    tencentcloud-cvm: * http://nginx.com/products/
    tencentcloud-cvm:
    tencentcloud-cvm: ----------------------------------------------------------------------
    tencentcloud-cvm:   Verifying  : 1:nginx-1.16.0-1.el7.ngx.x86_64                              1/1
    tencentcloud-cvm:
    tencentcloud-cvm: Installed:
    tencentcloud-cvm:   nginx.x86_64 1:1.16.0-1.el7.ngx
    tencentcloud-cvm:
    tencentcloud-cvm: Complete!
==> tencentcloud-cvm: Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/  1 rename
nginx.service.
==> tencentcloud-cvm: Detaching temporary key pair skey-dskwqs6v...
==> tencentcloud-cvm: Creating image nginx-service-v2
==> tencentcloud-cvm: Cleaning up 'Instance'
==> tencentcloud-cvm: Cleaning up 'Security Group'
==> tencentcloud-cvm: Cleaning up 'SUBNET'
==> tencentcloud-cvm: Cleaning up 'VPC'
==> tencentcloud-cvm: Deleting temporary keypair...
Build 'tencentcloud-cvm' finished.

==> Builds finished. The artifacts of successful builds are:
--> amazon-ebs: AMIs were created:
ap-southeast-2: ami-05d743427e2152bb5

--> tencentcloud-cvm: Tencentcloud images(ap-guangzhou: img-enu0br7p) were created:

新镜像创建完成以后,用户可以人工用它来创建新云主机,也可以通过terraform自动创建云主机,具体可以参考腾讯云Terraform应用指南。

本文中涉及到的例子都可以在这里找到,读者也可以通过扫描并关注腾讯云+社区社区领取试用金,在腾讯云上进行实验。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券