首先是安裝packer
在隨便一個64位的機器上
$ curl -sLO https://releases.hashicorp.com/packer/1.4.3/packer_1.4.3_linux_amd64.zip
$ unzip packer_1.4.3_linux_amd64.zip
$ chmod +x packer
$ sudo mv packer /usr/local/bin/packer
注意:
因為有一個linux 包也叫packer ,所以安裝前要確認一下
確認一下版本。以下多個命令都可以
$ packer -v
1.4.3
$ packer --version
1.4.3
$ packer -machine-readable version
1569220583,,version,1.4.3
1569220583,,version-prelease,
1569220583,,version-commit,613d8ef+CHANGES
1569220583,,ui,say,Packer v1.4.3
幫助的選項看以下
$ packer --help
Usage: packer [--version] [--help] <command> [<args>]
Available commands are:
build build image(s) from template
console creates a console for testing variable interpolation
fix fixes templates from old versions of packer
inspect see components of a template
validate check that a template is valid
version Prints the Packer version
幾個細項的幫助
分別是 validate 驗證模版
$ packer --help validate
Usage: packer validate [options] TEMPLATE
Checks the template is valid by parsing the template and also
checking the configuration with the various builders, provisioners, etc.
If it is not valid, the errors will be shown and the command will exit
with a non-zero exit status. If it is valid, it will exit with a zero
exit status.
Options:
-syntax-only Only check syntax. Do not verify config of the template.
-except=foo,bar,baz Validate all builds other than these.
-only=foo,bar,baz Validate only these builds.
-var 'key=value' Variable for templates, can be used multiple times.
-var-file=path JSON file containing user variables.
驗證模版創建的是否和預期一致
用法:
Usage: packer inspect TEMPLATE
Inspects a template, parsing and outputting the components a template
defines. This does not validate the contents of a template (other than
basic syntax by necessity).
Options:
-machine-readable Machine-readable output
build的幫助
$ packer --help build
Usage: packer build [options] TEMPLATE
Will execute multiple builds in parallel as defined in the template.
The various artifacts created by the template will be outputted.
Options:
-color=false Disable color output. (Default: color)
-debug Debug mode enabled for builds.
-except=foo,bar,baz Run all builds and post-procesors other than these.
-only=foo,bar,baz Build only the specified builds.
-force Force a build to continue if artifacts exist, deletes existing artifacts.
-machine-readable Produce machine-readable output.
-on-error=[cleanup|abort|ask] If the build fails do: clean up (default), abort, or ask.
-parallel=false Disable parallelization. (Default: true)
-parallel-builds=1 Number of builds to run in parallel. 0 means no limit (Default: 0)
-timestamp-ui Enable prefixing of each ui output with an RFC3339 timestamp.
-var 'key=value' Variable for templates, can be used multiple times.
-var-file=path JSON file containing user variables.
開啟自動完成的功能
packer -autocomplete-install
packer的工作流程
Packer使用作為json文件的模板將配置攜帶到各種任務中。 核心任務是Build 。 在此階段,Packer正在使用Builders為單個平臺創建機器映像。 例如。 Qemu Builder創建一個kvm / xen虛擬機映像。 下一階段是配置。 在此任務中, 預配器 (如ansible或shell腳本)在計算機映像內執行任務。 完成后, 后處理器將處理最終任務。 例如壓縮虛擬映像或將其導入特定的應用程序。
模版
一個 json template file 包含:
builders (必需)
description (可選)
variables (可選)
min_packer_version (可選)
provisioners (可選)
post-processors (可選)
也可以把注釋當做一個根鍵
{
"_comment": "This is a comment",
"builders": [
{}
]
}
然后,我們需要配置一個跑qemu環境的機器
首先要安裝qemu,因為centos自帶的qemu太老,目前是1.5版本的,很多bug
所以我們要安裝centos-release-qemu-ev 這個倉庫
yum install -y centos-release-qemu-ev
yum install -y qemu-kvm-ev
/usr/libexec/qemu-kvm -version
模版
模版的例子
我們已qemu 為例,做一個簡單的模版
以qemu_example.json為文件名,填充內容如下:
{
"_comment": "This is a qemu builder example",
"builders": [
{
"type": "qemu"
}
]
}
然后我們從語法驗證以下
[root@localhost ~]# packer validate -syntax-only qemu.json
Syntax-only check passed. Everything looks okay.
然后我們用packer validate驗證一下:
[root@localhost ~]# packer validate qemu_example.json
Template validation failed. Errors are shown below.
Errors validating build 'qemu'. 2 error(s) occurred:
* One of iso_url or iso_urls must be specified
* An ssh_username must be specified
Note: some builders used to default ssh_username to "root".
語法是沒有問題,但還是錯誤,通過packer validate這個命令的輸出,可以看到有幾個必須的值沒有定義,
如果需要debug
可以將PACKER_LOG=1 注入到系統變量里:
export PACKER_LOG=1
然后我們可以再次驗證一下
[root@localhost ~]# packer validate qemu_example.json
2019/09/23 04:19:18 [INFO] Packer version: 1.4.3
2019/09/23 04:19:18 Packer Target OS/Arch: linux amd64
2019/09/23 04:19:18 Built with Go Version: go1.12.8
2019/09/23 04:19:18 Detected home directory from env var: /root
2019/09/23 04:19:18 Using internal plugin for hyperv-vmcx
2019/09/23 04:19:18 Using internal plugin for lxc
2019/09/23 04:19:18 Using internal plugin for osc-chroot
2019/09/23 04:19:18 Using internal plugin for triton
2019/09/23 04:19:18 Using internal plugin for alicloud-ecs
2019/09/23 04:19:18 Using internal plugin for amazon-chroot
2019/09/23 04:19:18 Using internal plugin for amazon-instance
2019/09/23 04:19:18 Using internal plugin for hcloud
2019/09/23 04:19:18 Using internal plugin for parallels-pvm
2019/09/23 04:19:18 Using internal plugin for scaleway
2019/09/23 04:19:18 Using internal plugin for virtualbox-iso
2019/09/23 04:19:18 Using internal plugin for docker
2019/09/23 04:19:18 Using internal plugin for googlecompute
2019/09/23 04:19:18 Using internal plugin for oracle-classic
2019/09/23 04:19:18 Using internal plugin for osc-bsuvolume
2019/09/23 04:19:18 Using internal plugin for ncloud
2019/09/23 04:19:18 Using internal plugin for oneandone
2019/09/23 04:19:18 Using internal plugin for vmware-iso
2019/09/23 04:19:18 Using internal plugin for vmware-vmx
2019/09/23 04:19:18 Using internal plugin for hyperv-iso
2019/09/23 04:19:18 Using internal plugin for jdcloud
2019/09/23 04:19:18 Using internal plugin for oracle-oci
2019/09/23 04:19:18 Using internal plugin for ucloud-uhost
2019/09/23 04:19:18 Using internal plugin for amazon-ebsvolume
2019/09/23 04:19:18 Using internal plugin for azure-arm
2019/09/23 04:19:18 Using internal plugin for digitalocean
2019/09/23 04:19:18 Using internal plugin for file
2019/09/23 04:19:18 Using internal plugin for vagrant
2019/09/23 04:19:18 Using internal plugin for openstack
2019/09/23 04:19:18 Using internal plugin for osc-bsu
2019/09/23 04:19:18 Using internal plugin for profitbricks
2019/09/23 04:19:18 Using internal plugin for virtualbox-ovf
2019/09/23 04:19:18 Using internal plugin for hyperone
2019/09/23 04:19:18 Using internal plugin for proxmox
2019/09/23 04:19:18 Using internal plugin for null
2019/09/23 04:19:18 Using internal plugin for osc-bsusurrogate
2019/09/23 04:19:18 Using internal plugin for tencentcloud-cvm
2019/09/23 04:19:18 Using internal plugin for yandex
2019/09/23 04:19:18 Using internal plugin for amazon-ebs
2019/09/23 04:19:18 Using internal plugin for cloudstack
2019/09/23 04:19:18 Using internal plugin for linode
2019/09/23 04:19:18 Using internal plugin for lxd
2019/09/23 04:19:18 Using internal plugin for amazon-ebssurrogate
2019/09/23 04:19:18 Using internal plugin for parallels-iso
2019/09/23 04:19:18 Using internal plugin for qemu
2019/09/23 04:19:18 Using internal plugin for virtualbox-vm
2019/09/23 04:19:18 Using internal plugin for puppet-server
2019/09/23 04:19:18 Using internal plugin for shell-local
2019/09/23 04:19:18 Using internal plugin for windows-shell
2019/09/23 04:19:18 Using internal plugin for ansible-local
2019/09/23 04:19:18 Using internal plugin for inspec
2019/09/23 04:19:18 Using internal plugin for chef-client
2019/09/23 04:19:18 Using internal plugin for chef-solo
2019/09/23 04:19:18 Using internal plugin for puppet-masterless
2019/09/23 04:19:18 Using internal plugin for salt-masterless
2019/09/23 04:19:18 Using internal plugin for windows-restart
2019/09/23 04:19:18 Using internal plugin for ansible
2019/09/23 04:19:18 Using internal plugin for breakpoint
2019/09/23 04:19:18 Using internal plugin for powershell
2019/09/23 04:19:18 Using internal plugin for shell
2019/09/23 04:19:18 Using internal plugin for sleep
2019/09/23 04:19:18 Using internal plugin for converge
2019/09/23 04:19:18 Using internal plugin for file
2019/09/23 04:19:18 Using internal plugin for vagrant
2019/09/23 04:19:18 Using internal plugin for vsphere-template
2019/09/23 04:19:18 Using internal plugin for alicloud-import
2019/09/23 04:19:18 Using internal plugin for checksum
2019/09/23 04:19:18 Using internal plugin for digitalocean-import
2019/09/23 04:19:18 Using internal plugin for docker-import
2019/09/23 04:19:18 Using internal plugin for artifice
2019/09/23 04:19:18 Using internal plugin for compress
2019/09/23 04:19:18 Using internal plugin for docker-tag
2019/09/23 04:19:18 Using internal plugin for vsphere
2019/09/23 04:19:18 Using internal plugin for amazon-import
2019/09/23 04:19:18 Using internal plugin for googlecompute-export
2019/09/23 04:19:18 Using internal plugin for googlecompute-import
2019/09/23 04:19:18 Using internal plugin for vagrant-cloud
2019/09/23 04:19:18 Using internal plugin for shell-local
2019/09/23 04:19:18 Using internal plugin for docker-push
2019/09/23 04:19:18 Using internal plugin for docker-save
2019/09/23 04:19:18 Using internal plugin for exoscale-import
2019/09/23 04:19:18 Using internal plugin for manifest
2019/09/23 04:19:18 Detected home directory from env var: /root
2019/09/23 04:19:18 Attempting to open config file: /root/.packerconfig
2019/09/23 04:19:18 [WARN] Config file doesn't exist: /root/.packerconfig
2019/09/23 04:19:18 Packer config: &{DisableCheckpoint:false DisableCheckpointSignature:false PluginMinPort:10000 PluginMaxPort:25000 Builders:map[alicloud-ecs:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-alicloud-ecs amazon-chroot:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-amazon-chroot amazon-ebs:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-amazon-ebs amazon-ebssurrogate:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-amazon-ebssurrogate amazon-ebsvolume:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-amazon-ebsvolume amazon-instance:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-amazon-instance azure-arm:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-azure-arm cloudstack:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-cloudstack digitalocean:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-digitalocean docker:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-docker file:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-file googlecompute:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-googlecompute hcloud:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-hcloud hyperone:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-hyperone hyperv-iso:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-hyperv-iso hyperv-vmcx:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-hyperv-vmcx jdcloud:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-jdcloud linode:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-linode lxc:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-lxc lxd:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-lxd ncloud:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-ncloud null:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-null oneandone:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-oneandone openstack:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-openstack oracle-classic:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-oracle-classic oracle-oci:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-oracle-oci osc-bsu:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-osc-bsu osc-bsusurrogate:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-osc-bsusurrogate osc-bsuvolume:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-osc-bsuvolume osc-chroot:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-osc-chroot parallels-iso:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-parallels-iso parallels-pvm:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-parallels-pvm profitbricks:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-profitbricks proxmox:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-proxmox qemu:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-qemu scaleway:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-scaleway tencentcloud-cvm:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-tencentcloud-cvm triton:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-triton ucloud-uhost:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-ucloud-uhost vagrant:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-vagrant virtualbox-iso:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-virtualbox-iso virtualbox-ovf:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-virtualbox-ovf virtualbox-vm:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-virtualbox-vm vmware-iso:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-vmware-iso vmware-vmx:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-vmware-vmx yandex:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-builder-yandex] PostProcessors:map[alicloud-import:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-post-processor-alicloud-import amazon-import:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-post-processor-amazon-import artifice:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-post-processor-artifice checksum:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-post-processor-checksum compress:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-post-processor-compress digitalocean-import:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-post-processor-digitalocean-import docker-import:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-post-processor-docker-import docker-push:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-post-processor-docker-push docker-save:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-post-processor-docker-save docker-tag:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-post-processor-docker-tag exoscale-import:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-post-processor-exoscale-import googlecompute-export:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-post-processor-googlecompute-export googlecompute-import:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-post-processor-googlecompute-import manifest:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-post-processor-manifest shell-local:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-post-processor-shell-local vagrant:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-post-processor-vagrant vagrant-cloud:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-post-processor-vagrant-cloud vsphere:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-post-processor-vsphere vsphere-template:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-post-processor-vsphere-template] Provisioners:map[ansible:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-provisioner-ansible ansible-local:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-provisioner-ansible-local breakpoint:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-provisioner-breakpoint chef-client:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-provisioner-chef-client chef-solo:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-provisioner-chef-solo converge:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-provisioner-converge file:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-provisioner-file inspec:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-provisioner-inspec powershell:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-provisioner-powershell puppet-masterless:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-provisioner-puppet-masterless puppet-server:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-provisioner-puppet-server salt-masterless:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-provisioner-salt-masterless shell:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-provisioner-shell shell-local:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-provisioner-shell-local sleep:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-provisioner-sleep windows-restart:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-provisioner-windows-restart windows-shell:/usr/local/bin/packer-PACKERSPACE-plugin-PACKERSPACE-packer-provisioner-windows-shell]}
2019/09/23 04:19:18 Detected home directory from env var: /root
2019/09/23 04:19:18 Setting cache directory: /root/packer_cache
2019/09/23 04:19:18 Detected home directory from env var: /root
2019/09/23 04:19:18 Loading builder: qemu
2019/09/23 04:19:18 Plugin could not be found. Checking same directory as executable.
2019/09/23 04:19:18 Current exe path: /usr/local/bin/packer
2019/09/23 04:19:18 Creating plugin client for path: /usr/local/bin/packer
2019/09/23 04:19:18 Starting plugin: /usr/local/bin/packer []string{"/usr/local/bin/packer", "plugin", "packer-builder-qemu"}
2019/09/23 04:19:18 Waiting for RPC address for: /usr/local/bin/packer
2019/09/23 04:19:18 packer: 2019/09/23 04:19:18 [INFO] Packer version: 1.4.3
2019/09/23 04:19:18 packer: 2019/09/23 04:19:18 Packer Target OS/Arch: linux amd64
2019/09/23 04:19:18 packer: 2019/09/23 04:19:18 Built with Go Version: go1.12.8
2019/09/23 04:19:18 packer: 2019/09/23 04:19:18 Detected home directory from env var: /root
2019/09/23 04:19:18 packer: 2019/09/23 04:19:18 Attempting to open config file: /root/.packerconfig
2019/09/23 04:19:18 packer: 2019/09/23 04:19:18 [WARN] Config file doesn't exist: /root/.packerconfig
2019/09/23 04:19:18 packer: 2019/09/23 04:19:18 Packer config: &{DisableCheckpoint:false DisableCheckpointSignature:false PluginMinPort:10000 PluginMaxPort:25000 Builders:map[] PostProcessors:map[] Provisioners:map[]}
2019/09/23 04:19:18 packer: 2019/09/23 04:19:18 Detected home directory from env var: /root
2019/09/23 04:19:18 packer: 2019/09/23 04:19:18 Setting cache directory: /root/packer_cache
2019/09/23 04:19:18 packer: 2019/09/23 04:19:18 args: []string{"packer-builder-qemu"}
2019/09/23 04:19:18 packer: 2019/09/23 04:19:18 Detected home directory from env var: /root
2019/09/23 04:19:18 packer: 2019/09/23 04:19:18 Plugin minimum port: 10000
2019/09/23 04:19:18 packer: 2019/09/23 04:19:18 Plugin maximum port: 25000
2019/09/23 04:19:18 packer: 2019/09/23 04:19:18 Plugin address: unix /tmp/packer-plugin131147162
2019/09/23 04:19:18 packer: 2019/09/23 04:19:18 Waiting for connection...
2019/09/23 04:19:18 packer: 2019/09/23 04:19:18 Serving a plugin connection...
2019/09/23 04:19:18 Preparing build: qemu
2019/09/23 04:19:18 packer: 2019/09/23 04:19:18 use detected accelerator: tcg
2019/09/23 04:19:18 packer: 2019/09/23 04:19:18 MemorySize 0 is too small, using default: 512
2019/09/23 04:19:18 packer: 2019/09/23 04:19:18 CpuCount 0 too small, using default: 1
2019/09/23 04:19:18 Build 'qemu' prepare failure: 2 error(s) occurred:
* One of iso_url or iso_urls must be specified
* An ssh_username must be specified
Note: some builders used to default ssh_username to "root".
* One of iso_url or iso_urls must be specified
* An ssh_username must be specified
Note: some builders used to default ssh_username to "root".
2019/09/23 04:19:18 [INFO] (telemetry) Finalizing.
Template validation failed. Errors are shown below.
Errors validating build 'qemu'. 2 error(s) occurred:
* One of iso_url or iso_urls must be specified
* An ssh_username must be specified
Note: some builders used to default ssh_username to "root".
2019/09/23 04:19:20 [WARN] (telemetry) Error finalizing report. This is safe to ignore. Post https://checkpoint-api.hashicorp.com/v1/telemetry/packer: context deadline exceeded
2019/09/23 04:19:20 waiting for all plugin processes to complete...
2019/09/23 04:19:20 /usr/local/bin/packer: plugin process exited
我們可以看到好多內置的插件,這里先略過。。
變量
在 packer template 定義變量非常簡單
"variables": {
"centos_version": "7.5",
}
然后用下面的方式使用剛剛定義的變量:
"{{user `centos_version`}}",
注釋
我們可以在模板頂部添加描述聲明:
"description": "Minimal CentOS 7 Qemu Imagen_____
然后可以用
packer inspect 來驗證
QEMU BUILDER
然后我們用一段完整簡單的packer 的json代碼來做build的例子
$ cat qemu_example.json
{
"_comment": "This is a CentOS 7.5 Qemu Builder example",
"description": "Minimal CentOS 7 Qemu Imagen__________________________________________",
"variables": {
"7.5": "1908",
"checksum": "9a2c47d97b9975452f7d582264e9fc16d108ed8252ac6816239a3b58cef5c53d"
},
"builders": [
{
"type": "qemu",
"iso_url": "https://mirrors.163.com/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-{{user `7.5`}}.iso",
"iso_checksum": "{{user `checksum`}}",
"iso_checksum_type": "sha256",
"communicator": "none"
}
]
}
然后驗證一下
[root@localhost ~]# packer validate -syntax-only qemu_example.json
Syntax-only check passed. Everything looks okay.
[root@localhost ~]# packer validate qemu_example.json
Template validated successfully.
Communicator
有三個基本的選項:
none
Secure Shell (SSH)
WinRM
這個是在構建部分( provisioning ) 配置的需要配置的
通訊在構建部分上傳文件或者執行腳本,如果不需要特別構建鏡像時,可以使用none,而不是默認的ssh
來禁用這個選項
"communicator": "none"
iso_url
可以使用本地或者intelnet的地址,這個才調試的時候非常有用,可以避免經常從網上下載文件提高修復。
"iso_url": "/home/ebal/Downloads/CentOS-7-x86_64-Minimal-{{user `7.5`}}.iso"
如果在centos下面,使用packer 對qemu 進行打包時候,需要裝qemu-system-x86這個包,否則會報錯
[root@localhost ~]# packer build qemu_example.json
qemu output will be in this color.
Build 'qemu' errored: Failed creating Qemu driver: exec: "qemu-system-x86_64": executable file not found in $PATH
==> Some builds didn't complete successfully and had errors:
--> qemu: Failed creating Qemu driver: exec: "qemu-system-x86_64": executable file not found in $PATH
==> Builds finished but no artifacts were created.
然而這個包在epel庫里,因此還需要安裝epel的倉庫。
繼續,不出意外,應該還會出現另外一個錯誤
2019/09/24 00:40:45 packer: 2019/09/24 00:40:45 Qemu stderr:
2019/09/24 00:40:45 packer: 2019/09/24 00:40:45 Qemu stderr: (process:20773): GLib-WARNING **: 00:40:45.452: gmem.c:489: custom memory allocation vtable not supported
2019/09/24 00:40:45 packer: 2019/09/24 00:40:45 Qemu stderr: Could not initialize SDL(No available video device) - exiting
==> qemu: Error launching VM: Qemu failed to start. Please run with PACKER_LOG=1 to get more info.
2019/09/24 00:40:45 packer: 2019/09/24 00:40:45 failed to unlock port lockfile: close tcp 127.0.0.1:5957: use of closed network connection
==> qemu: Deleting output directory...
2019/09/24 00:40:45 [INFO] (telemetry) ending qemu
2019/09/24 00:40:45 machine readable: error-count []string{"1"}
==> Some builds didn't complete successfully and had errors:
Build 'qemu' errored: Build was halted.
這個手冊里有寫
請注意,如果要在沒有X11的Linux服務器上運行Packer,則需要設置"headless": true ; 或者,如果您通過ssh連接到遠程Linux服務器并且尚未啟用X11轉發( ssh -X )。
我們可以修改我們的配置文件來解決問題,但是實際上,我們需要打開一個虛擬機窗口,看看究竟發生了什么,因此我們選擇安裝一個圖形環境
然后我們安裝一個圖形環境
yum -y groupinstall "Server with GUI
然后繼續就可以了
我們當然想剩下的部分可以自動完成,
因此在linux部分,我們要引入linux的Kickstart來完成剩下的工作。
#version=CentOS-7
# Install OS instead of upgrade
install
# Text or Graphical mode ?
text
# Packages are on:
cdrom
# System keyboard
keyboard us
# System language
lang en_US.UTF-8
# TimeZone with NTP
timezone Asia/Shanghai --ntpservers=gr.pool.ntp.org
# SELinux - By default, selinux is enforcing
selinux --permissive
# Sets the system's root password to the password argument.
rootpw --plaintext password
# accept the End User License Agreement - rhel 7
## eula--agreed
# Do not Run the Setup Agent on first boot
firstboot --disabled
# Power Off the system when the install is complete
poweroff
# Partition Table
autopart --nohome --type=plain --fstype=ext4
bootloader --location=mbr
# Partition clearing information
clearpart --all --initlabel
zerombr
%packages --excludedocs
@core
# Remove
-aic94xx-firmware
-alsa-*
-iwl*-firmware
-ivtv-firmware
-libertas-*-firmware
-btrfs-progs
-ModemManager-glib
-NetworkManager*
-wpa_supplicant
# Install
openssh-clients
%end
# Disable Kdump
%addon com_redhat_kdump --disable
%end
這是非常簡單的一個kickstart文件,讓我們把他保存為centos7.ks
然后我們修改我們的qemu_example.json文件
加入kickstart文件
添加字段
"boot_command":[
"<tab> text ",
"ks=https://raw.githubusercontent.com/ebal/confs/master/Kickstart/CentOS7-ks.cfg ",
"nameserver=9.9.9.9 ",
"<enter><wait> "
],
"boot_wait": "0s"
記得要在前面的選項結尾后加逗號 ,
修改后變成這樣:
{
"_comment": "This is a CentOS 7.5 Qemu Builder example",
"description": "\tMinimal CentOS 7 Qemu Imagen\n__________________________________________",
"variables": {
"7.5": "1908",
"checksum": "9a2c47d97b9975452f7d582264e9fc16d108ed8252ac6816239a3b58cef5c53d"
},
"builders": [
{
"type": "qemu",
"iso_url": "/root/CentOS-7-x86_64-Minimal-{{user `7.5`}}.iso",
"iso_checksum": "{{user `checksum`}}",
"iso_checksum_type": "sha256",
"communicator": "none",
"boot_command" : [
"<tab> text ",
"console=ttyS0,115200n8 ",
"ks=https://192.168.4.190/CentOS7-ks.cfg ",
"nameserver=8.8.8.8",
"<enter><wait> "
],
"boot_wait": "0s",
"shutdown_timeout": "30m"
}
]
}
看到多了一行 "shutdown_timeout": "30m" 這個是解決安裝過程中,如果超過5分鐘,packer會報
Build 'qemu' errored: Failed to shutdown
原因是默認等待時間只有5分鐘,所以我們要加長一點
http_directory
在沒有Internet訪問的環境中構建映像時,可以從Packer可以創建的內部HTTP服務器檢索kickstast文件。 通過聲明目錄路徑來啟用此功能: http_directory
使用HTTP服務器提供服務的目錄的路徑。 該目錄中的文件將通過HTTP可用,可從虛擬機請求該文件
上面的代碼就要修改成這樣
"http_directory": "/root/Downloads/",
"http_port_min": "8090",
"http_port_max": "8100",
"boot_command":[
"<tab> text ",
"ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/CentOS7.ks",
"<enter><wait>"
],
"boot_wait": "0s"
事先要把centos7.ks 放到/root/Downloads/
最后,我們得到了如下的json文件
{
"_comment": "This is a CentOS 7.5 Qemu Builder example",
"description": "tMinimal CentOS 7 Qemu Imagen__________________________________________",
"variables": {
"7.7": "1908",
"checksum": "9a2c47d97b9975452f7d582264e9fc16d108ed8252ac6816239a3b58cef5c53d"
},
"builders": [
{
"type": "qemu",
"iso_url": "/root/CentOS-7-x86_64-Minimal-{{user `7.7`}}.iso",
"iso_checksum": "{{user `checksum`}}",
"iso_checksum_type": "sha256",
"communicator": "none",
"boot_command":[
"<tab> text ",
"ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/centos7.ks ",
"nameserver=8.8.8.8 ",
"<enter><wait> "
],
"boot_wait": "0s",
"http_directory": "/root/",
"http_port_min": "8090",
"http_port_max": "8100",
"shutdown_timeout": "40m"
}
]
}
然后我們重新build 一次鏡像
packer build qemu_example.json
然后我們驗證一下鏡像
[root@localhost ~]# ls output-qemu/
packer-qemu
[root@localhost ~]# file output-qemu/packer-qemu
output-qemu/packer-qemu: QEMU QCOW Image (v3), 42949672960 bytes
因為默認的qemu-img 起的虛擬機,內存只給512m,cpu只給一個內核,跑起來非常慢,另外在純qemu環境下,打包也是跑的非常慢,還有就是我們一般只有debug的時候需要起桌面,看看虛擬機到底跑的怎么樣,其他的時候,我們不需要起桌面,這些都需要對配置進行一些優化。
然后就是下面的這樣了
{
"_comment": "This is a CentOS 7.5 Qemu Builder example",
"description": "\tMinimal CentOS 7 Qemu Imageni\n__________________________________________",
"variables": {
"7.7": "1908",
"checksum": "9a2c47d97b9975452f7d582264e9fc16d108ed8252ac6816239a3b58cef5c53d",
"virtual_name": "centos7min.qcow2",
"virtual_dir": "centos7",
"virtual_size": "20480",
"virtual_mem": "4096",
"Password": "password"
},
"builders": [
{
"type": "qemu",
"headless": true,
"iso_url": "/root/CentOS-7-x86_64-Minimal-{{user `7.7`}}.iso",
"iso_checksum": "{{user `checksum`}}",
"iso_checksum_type": "sha256",
"communicator": "none",
"ssh_username": "root",
"ssh_password": "{{user `Password`}}",
"ssh_timeout": "3600s",
"boot_command":[
"<tab> text ",
"console=ttyS0,115200n8 ",
"ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/centos7.ks ",
"nameserver=8.8.8.8 ",
"<enter><wait> "
],
"boot_wait": "0s",
"http_directory": "/root/",
"http_port_min": "8090",
"http_port_max": "8100",
"shutdown_timeout": "120m",
"accelerator": "kvm",
"format": "qcow2",
"qemuargs":[
[ "-m", "2048" ],
["-smp", "2,sockets=2,cores=1,threads=1" ],
[ "-serial", "file:serial.out" ]
]
}
]
}
#Headless
打包程序無需使用顯示器。 在遠程計算機上運行打包程序時,這真的很有用。 盡管可以通過vnc連接并監視過程,但無需任何交互即可自動執行自動安裝。
禁用x終端鏈接
"headless": true
另外如果要監看packer打包過程的話,需要下面的步驟
在boot_command 的選項里添加了
"console=ttyS0,115200n8 ",
然后在
"qemuargs":[
[ "-serial", "file:serial.out" ]
這樣我們等于在內核啟動參數里,添加了通過serial口顯示屏幕的一個后門,然后又被packer 重定向到當前目錄下的serial.out 文件里,于是我們可以通過下面的命令來查看打包過程
tail -f serial.out
然后添加qmeu 優化的選項
首先添加變量
"virtual_name": "centos7min.qcow2",
"virtual_dir": "centos7",
"virtual_size": "20480",
"virtual_mem": "4096"
然后在下面的build 里面調用
"accelerator": "kvm",
"disk_size": "{{ user `virtual_size` }}",
"format": "qcow2",
"qemuargs":[
[ "-m", "{{ user `virtual_mem` }}" ]
],
"vm_name": "{{ user `virtual_name` }}",
"output_directory": "{{ user `virtual_dir` }}"
也可以按
["-smp", "2,sockets=2,cores=1,threads=1" ],
[ "-serial", "file:serial.out" ]
這樣寫。
特別說明"accelerator": "kvm",的 選項,如果是在kvm的主機里,并且沒有開啟嵌套虛擬化,加這個選項是會報錯的,如果不加的話,就是純qemu軟件虛擬機,我打包一個簡單的centos7的鏡像花了將近1個小時,而我在真實物理機打包的時候只有5分鐘左右,因此強烈不推薦在虛擬機上跑packer的打包程序。
最后的提示是這樣的
time packer build qemu_example.json
qemu output will be in this color.
==> qemu: Retrieving ISO
==> qemu: Trying /root/CentOS-7-x86_64-Minimal-1908.iso
==> qemu: Trying /root/CentOS-7-x86_64-Minimal-1908.iso?checksum=sha256%3A9a2c47d97b9975452f7d582264e9fc16d108ed8252ac6816239a3b58cef5c53d
==> qemu: /root/CentOS-7-x86_64-Minimal-1908.iso?checksum=sha256%3A9a2c47d97b9975452f7d582264e9fc16d108ed8252ac6816239a3b58cef5c53d => /root/packer_cache/4643e65b1345d2b22536e5d371596b98120f4251.iso
==> qemu: Creating required virtual machine disks
==> qemu: Starting HTTP server on port 8092
==> qemu: Looking for available port between 5900 and 6000 on 127.0.0.1
==> qemu: Starting VM, booting from CD-ROM
qemu: The VM will be run headless, without a GUI. If you want to
qemu: view the screen of the VM, connect via VNC without a password to
qemu: vnc://127.0.0.1:5961
==> qemu: Overriding defaults Qemu arguments with QemuArgs...
==> qemu: Connecting to VM via VNC (127.0.0.1:5961)
==> qemu: Typing the boot command over VNC...
==> qemu: Waiting for shutdown...
==> qemu: Converting hard drive...
Build 'qemu' finished.
==> Builds finished. The artifacts of successful builds are:
--> qemu: VM files in directory: centos7
real 5m4.663s
user 5m36.605s
sys 0m36.641s
后置處理
打包好的鏡像就可以推送到云或者是壓縮
我們這里簡單寫一個壓縮的處理程序
"post-processors":[
{
"type": "compress",
"format": "lz4",
"output": "{{.BuildName}}.lz4"
}
]
PROVISIONERS
packer的文檔是這樣描述的
Provisioners use builtin and third-party software to install and configure the machine image after booting. Provisioners prepare the system for use, so common use cases for provisioners include:
installing packages
patching the kernel
creating users
downloading application code
These are just a few examples, and the possibilities for provisioners are endless.
打開文檔,我們可以看到基本常見的iac工具都有了
ansible chef puppet inspec 等,,涵蓋了從部署到測試驗證的所有環節,
這里我們簡單使用 PROVISIONERS 的ansible 插件
我們首先創建一個ansible role,名字叫test
ansible-galaxy init test
- test was created successfully
然后在tasks/main.yml 里面加入如下內容
---
- name: Debug that our ansible role is working
debug:
msg: "It Works !"
- name: Install the Extra Packages for Enterprise Linux repository
yum:
name: epel-release
state: present
- name: upgrade all packages
yum:
name: *
state: latest
然后在packer的模版里面添加
變量部分修改
"variables":{
"playbook_name": "test.yml"
},
下面是新添加的一個新角色
"provisioners":[
{
"type": "ansible",
"playbook_file": "{{ user `playbook_name` }}"
}
],
因為ansible 其實是本地ansible連接我們打包過程中起的虛擬機,我們還需要在打包過程中打開ssh端口,讓ansible和打包過程中的虛擬機通訊
"communicator": "ssh",
同時要添加用戶和密碼到模版里去
"ssh_username": "root",
"ssh_password": "password",
"ssh_timeout": "3600s",
后來我發現我這個如果用"communicator": "none", 可以跑,
不過ansible 是跑在packer這個打包機上的,
ssh一直連不上
如果用ansible_local,結果packer 直接報錯退出了
然后看了一下文檔,在packer的模塊中,ansible 和 ansible_local 是兩個完全不同的實現方式
ansible 模塊是 由打包機的上執行ansible通過ssh連接到虛擬機上,執行playbook文件
ansible_local 模塊是將打包機上的ansible 文件,同步到虛擬機上,然后在虛擬機上執行ansible文件
因此需要事先在虛擬機上安裝ansible,才可以使用ansible_local的模塊,或者在使用這個模塊前,通過shell模塊安裝ansible ,就可以了