基础设施即代码的意思是把基础设施的实现方式写成代码。告别手工配置各类资源而采用基础设施即代码的方式,可以获得多种好处:
- 可重复-可以随时重新创建基础架构,例如在灾备环境重新创建生产环境。
- 可一致性-在各个不同的环境之间实现最大程度的一致性,减少环境差异导致的生产、测试效率下降。
- 可追溯回滚-环境的所有变化都通过代码实现,而代码的变化是可以追溯回滚的。
- 快速-由于基础架构是通过代码实现的,那么改变或者重建系统时就会非常快,是敏捷开发和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文件,内容如下:
代码语言:txt复制{
"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是从腾讯云控制台查到的,如下图:
builder后边是一个provisioner的定义,指定了几个命令行及参数。
随后可以执行:
代码语言:txt复制packer build tencent-nginx.json
我们可以看到:
代码语言:txt复制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的脚本:
代码语言:txt复制{
"type": "shell",
"script": "script.sh"
}
用户还可以通过在builder中加入下边一行代码告诉packer,镜像创建成功后拷贝到其它大区:
代码语言:txt复制"image_copy_regions": ["ap-beijing"]
也可以通过修改大区名的方式,在中国和海外的不同大区创建同样的镜像。
还可以同时在腾讯云和aws上创建同一功能的镜像:
代码语言:txt复制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两者上都运行成功:
代码语言:txt复制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应用指南。
本文中涉及到的例子都可以在这里找到,读者也可以通过扫描并关注腾讯云 社区社区领取试用金,在腾讯云上进行实验。