Most Powerful Open Source ERP

如何使用Packer构建自定义映像

如何构建可以在多台计算机中重复使用的自定义映像。
  • Last Update:2020-06-02
  • Version:001
  • Language:zh

使用PackerAnsible生成自定义的虚拟机(VM)映像

 

Packer是一款轻量级的镜像定义工具,能够运行在常用的主流操作系统(如Windows、Linux和macOS)上。参见本文使用Packer,轻松生成多个虚拟机映像,以简化多个虚拟机的安装流程。

Packer

当您要部署多个虚拟机且不想浪费时间用ISO安装映像手动逐个安装每个虚拟机时,可以使用Packer通过单一源配置为多个平台创建相同的虚拟机映像,而不是常规的ISO安装映像。这样可以为您节省很多时间。

Packer需要一个模板来构建映像。该模板以JSON格式呈现,包含了您要在虚拟机映像中构建的所有内容。此模板的核心是要构建ISO安装映像,然后您可以使用自定义的参数自动执行参数对应的指定内容要求的安装。 Packer 模板的文档可在以下位置找到: https://www.packer.io/docs/templates/.

让我们看一下模板文件的示例(此文件是我们的debian10.json模板):

{
  "variables": {
    "user": "slapos",
    "password": "slapos",
    "domain": "",
    "disk_size": "100",
    "name": "image",
    "custom_script": "scripts/empty.sh"
  },

  "builders":
  [
    {
      "name": "debian10-{{ user `disk_size`}}G-{{ user `name`}}",

      "type": "qemu",
      "format": "qcow2",
      "accelerator": "kvm",
      "disk_size": "{{ user `disk_size`}}000",

      "iso_url": "https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-10.2.0-amd64-netinst.iso",
      "iso_checksum": "36de671429939e90f2a31ce3fbed0aaf",
      "iso_checksum_type": "md5",

      "http_directory": "http",

      "ssh_username": "{{user `user`}}",
      "ssh_password": "{{user `password`}}",
      "ssh_wait_timeout": "1800s",
      "shutdown_command": "echo '{{user `password`}}'|sudo -S shutdown -h now",

      "headless": true,
      "boot_wait": "2s",
      "boot_command": [
        "",
        "auto preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed-debian10.cfg ",
        "debian-installer=en_US.UTF-8 locale=en_US keymap=fr ",
        "netcfg/get_hostname={{ .Name }} ",
        "netcfg/get_domain={{ user `domain`}} ",

        "fb=false debconf/frontend=noninteractive ",

        "passwd/user-fullname={{user `user`}} ",
        "passwd/user-password={{user `password`}} ",
        "passwd/user-password-again={{user `password`}} ",
        "passwd/username={{user `user`}} ",

        ""
      ]
    }
  ],

  "provisioners": [
    {
      "type": "shell",
      "execute_command": "echo '{{user `password`}}' | {{.Vars}} sudo -E -S bash '{{.Path}}'",
      "scripts": [
        "scripts/update.sh",
        "scripts/packages.sh",
        "scripts/network-debian.sh",
        "scripts/cleanup.sh",
        "{{ user `custom_script` }}"
      ]
    }
  ]
}

 

"builder"(构建器)部分是最重要也是唯一的必需部分。 另外还有两个部分:

  • "variables" (变量)定义了我们在其他部分中使用的变量。对映像进行一些详细的设置可能会很有用
  • "provisioners" (派生器)这是安装之后执行的步骤。它允许您通过ssh在新安装的系统内执行命令。此步骤将使我们可以自定义配置映像中所需的所有内容(用户,软件包等)。

请注意,文件preseed.cfg必须位于名为http的文件夹内。此http文件夹必须与模板(.json)在同级目录下,可以查看我们的http目录以确认: https://lab.nexedi.com/nexedi/slapos.package/tree/master/packer/http. 有关预置文件的更多信息,请参见:https://wiki.debian.org/fr/DebianInstaller/Preseed

在编写模板(如上面的模板)时,可以使用以下命令确保其语法正确无误 

packer validate debian10.json

验证模板文件没有语法错误后,您可以使用以下命令构建映像:

packer build debian10.json 

 

请注意,Packer支持任何操作系统。 您只需要查看如何自动安装所选操作系统,然后为其配置模板即可。 当然,有很多可用的模板示例(请参阅https://www.packer.io/community-tools.html中的“模板(Templates)”一章)。

 

使用Ansible自动构建映像

如果您需要构建许多不同的图像,例如,您可能要为多个发行版(Ubuntu,CentOS,Debian)或具有多个磁盘大小(50G,100G,200G等)构建映像,则可以使用Ansible生成所有图像,而不是一一生成。

使用命令packer build手动构建每个映像可能很繁琐。您可以通过创建Ansible剧本(playbooks)轻松生成所有的映像。

 

下面是一个Ansible任务(Task)的示例,该任务使用packer创建映像:

- shell: PATH=$PATH:/opt/packer/ packer build debian10.json >> log/debian10.log
args:
creates: output-debian10
ignore_errors: True

 

如您所见,此任务将仅调用packer并将输出映像保存在output-debian10目录中。

如果要压缩映像(Rapid.Space虚拟机服务可以从压缩映像启动)以节省磁盘空间:

- shell: gzip output-debian10/packer-debian10
args:
creates: output-debian10/packer-debian10.gz
ignore_errors: True

您还可以创建一个任务,将该映像上传到Web服务器,供Rapid.Space虚拟机使用。

如果您想了解我们在Nexedi用来生成的剧本的示例,请查看

 https://lab.nexedi.com/nexedi/slapos.package/blob/master/packer/build-vm-bootstrap.yml

 

如果您的剧本名为 build.yml,则可以使用以下简单命令运行它:

ansible-playbook build.yml -i localhost