使用 Packer 打造云市场镜像

159 阅读5分钟

引言

在云计算的时代,快速部署和交付成为了每个企业都追求的目标。而针对跨平台部署需求,Packer 凭借其高效的自动化镜像创建能力成为众多技术团队的优选工具。在本文中,我们将深入探讨 Packer 的核心功能及其在构建云市场镜像中的实际应用,同时也会结合FinClip小程序系统的案例,展示如何通过 Packer 快速生成标准化的镜像以满足多个云平台的上架需求。

Packer 的核心特性

在进入细节之前,让我们先了解一下 Packer 的核心特性:

  1. 跨平台支持:支持主流云平台如 AWS、Azure、Alibaba Cloud、Google Cloud 等。
  2. 多镜像并行构建:通过一次性配置,可以生成多个不同平台的镜像。
  3. 基础设施即代码 (IaC) :使用 JSON 或 HCL 格式定义模板,易于版本控制和团队协作。

这些特点使 Packer 成为构建云市场镜像的理想工具。而对像 FinClip 这样的复杂系统来说,标准化的镜像构建流程尤为重要。

FinClip 小程序系统和 Packer

FinClip 小程序系统 是一个高性能的小程序容器解决方案,为企业提供灵活的开发和部署能力。随着业务拓展,我们需要将 FinClip 小程序系统 镜像发布到多个云平台的云市场,例如 AWS、阿里云、腾讯云和华为云。传统手动创建镜像的方式既耗时又易出错,而 Packer 恰好解决了这些问题。

通过 Packer,我们可以实现:

  • 统一的构建流程:一次编写模板文件,构建适配多个云平台的镜像。
  • 提前配置启动服务:利用 cloud-init 技术,在服务启动时完成 FinClip 的初始化配置,使镜像启动后即可访问服务。
  • 高质量标准化镜像:确保所有镜像内的软件版本、配置一致,从而降低运维复杂度。

下面将从整体架构到具体实现进行详细说明。

Packer 应用框架介绍

1. Packer 模板

下面的 Packer 模板文件是在 AWS 中通过 amazon-ebs 构建 Amazon EC2 实例的镜像。

packer {
  required_plugins {
    amazon = {
      version = ">= 1.2.8"
      source  = "github.com/hashicorp/amazon"
    }
  }
}
​
variable "aws_region" {
  type    = string
  default = "cn-northwest-1"
}
​
variable "instance_type" {
  type    = string
  default = "c5.xlarge"
}
​
source "amazon-ebs" "finclip" {
  ami_name    = "finclip-ami"
  region        = var.aws_region
  instance_type = var.instance_type
  source_ami_filter {
    filters = {
      name                = "ubuntu/images/*ubuntu-jammy-22.04-amd64-server-*"
      root-device-type    = "ebs"
      virtualization-type = "hvm"
    }
    most_recent = true
    owners      = ["888888888888"]
  }
  
  ssh_username = "ubuntu"
​
  # 硬盘
  launch_block_device_mappings {
    device_name = "/dev/sda1"
    volume_size = 40
    volume_type = "gp2"
    delete_on_termination = true
  }
​
}
​
build {
  sources = ["source.amazon-ebs.finclip"]
​
  provisioner "file" {
    source      = "setup.sh"
    destination = "/tmp/setup.sh"
  }
​
  provisioner "file" {
    source      = "init.sh"
    destination = "/tmp/init.sh"
  }
​
  provisioner "shell" {
    inline = [
      "sudo mv /tmp/init.sh /var/lib/cloud/scripts/per-instance/init.sh",
      "sudo chmod +x /var/lib/cloud/scripts/per-instance/init.sh",
      "ls -l /tmp/setup.sh",
      "sudo bash /tmp/setup.sh",
      "sudo rm -f /tmp/setup.sh"
    ]
  }
}

Packer 插件配置

在模板文件的开头,我们通过 packer { required_plugins } 配置了 Packer 使用的插件。此处配置了 amazon 插件,并指定了插件的版本要求。这表明我们将构建一个 Amazon EC2 实例的镜像,并使用该插件来处理与 AWS 相关的操作。

变量定义

接下来,我们定义了两个变量:

  • aws_region: 定义 AWS 区域的字符串变量,默认值为 cn-northwest-1
  • instance_type: 定义 EC2 实例类型的字符串变量,默认值为 c5.xlarge

这些变量的作用是使模板更加灵活,用户可以在运行 Packer 时通过命令行传入不同的参数来调整这些变量的值,从而适应不同的部署需求。

源定义(Source)

source 部分,我们配置了 amazon-ebs 来定义我们希望创建的 EC2 实例镜像(AMI)。该部分包含以下配置:

  • ami_name: 定义创建的 AMI 的名称。
  • region: 使用之前定义的 aws_region 变量来设置区域。
  • instance_type: 使用之前定义的 instance_type 变量来设置实例类型。
  • source_ami_filter: 通过过滤器指定了用于创建新镜像的源 AMI。我们指定了操作系统类型(Ubuntu 22.04)。
  • ssh_username: 指定 SSH 用户名为 ubuntu,因为我们使用的是 Ubuntu 系统。
  • launch_block_device_mappings : 用于配置实例的存储设备,这里指定了 40 GB 的 EBS 磁盘.

构建配置(Build)

build 部分,我们指定了如何构建镜像并配置相应的执行步骤:

  • sources: 指定使用 source.amazon-ebs.finclip 作为构建的源。
  • provisioner "file": 这两行配置上传了 setup.shinit.sh 脚本到实例的 /tmp 目录。
  • provisioner "shell": 该配置会在构建的虚拟机上执行一系列的 Shell 脚本。

2. Cloud-init 实现

为了实现服务的自动化初始化,我们在镜像中设计了两阶段的自动化脚本:

setup.sh :构建阶段准备环境

在镜像构建过程中,setup.sh 脚本被执行,主要职责是:

  • 下载所需的部署文件。
  • 配置必要的依赖项和目录结构,确保服务可以正常初始化。
  • 优化镜像体积,清理构建过程中多余的临时文件。

init.sh:由 Cloud-init 在服务器启动时执行,用于完成真正的自动化服务初始化和启动。

最终效果

通过上述两阶段脚本的配合,我们确保:

  1. 构建镜像时,部署环境已完全准备好(包括所有必要文件)。
  2. 镜像启动时,服务能够自动完成初始化,无需用户手动干预,实现 "开箱即用"。

这种实现方式不仅优化了镜像的构建和启动流程,还增强了系统部署的可维护性和可靠性。

镜像的高效上架

通过 Packer 和 Cloud-init 的结合,我们不仅能快速构建标准化镜像,还能提升部署效率,使服务开箱即用。以下是完整的工作流:

模板定义 -> Packer 构建镜像 -> 集成 Cloud-init -> 测试 -> 上传到云市场