Packer 镜像构建¶
一句话概述:Packer 是 HashiCorp 出品的自动化镜像构建工具,用代码定义镜像内容,一次构建可以输出多个平台的镜像(AWS AMI、Docker、VMware 等)。
核心知识点¶
| 概念 | 白话解释 |
|---|---|
| Template | 模板 = 描述镜像怎么构建的配置文件(HCL 或 JSON) |
| Builder | 构建器 = 负责创建特定平台镜像(如 amazon-ebs 创建 AWS AMI) |
| Provisioner | 供应器 = 镜像里安装软件的方式(Shell 脚本、Ansible 等) |
| Post-processor | 后处理器 = 镜像构建完后的处理(压缩、上传等) |
| Source | 来源 = HCL 格式中定义构建器的块 |
| Build | 构建 = HCL 格式中定义构建流程的块 |
| Artifact | 产物 = 构建出来的镜像文件/ID |
安装配置¶
# macOS
brew install packer # Homebrew 安装
# Ubuntu/Debian
wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg # 导入密钥
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list # 添加仓库
sudo apt update && sudo apt install packer # 安装
# 验证
packer version # 查看版本
基本使用¶
1. 构建 AWS AMI¶
# aws-ubuntu.pkr.hcl
packer {
required_plugins {
amazon = {
version = ">= 1.3.0" # Amazon 插件版本
source = "github.com/hashicorp/amazon" # 插件来源
}
}
}
# 变量定义
variable "aws_region" {
type = string
default = "us-east-1" # 默认区域
}
variable "instance_type" {
type = string
default = "t3.micro" # 构建用的实例类型
}
# 来源:基于 Amazon EBS 构建 AMI
source "amazon-ebs" "ubuntu" {
ami_name = "bioinfo-ubuntu-{{timestamp}}" # AMI 名称(加时间戳避免重名)
instance_type = var.instance_type # 构建用的临时实例类型
region = var.aws_region # 区域
source_ami_filter { # 自动查找最新的 Ubuntu AMI
filters = {
name = "ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*" # Ubuntu 22.04
root-device-type = "ebs"
virtualization-type = "hvm"
}
most_recent = true # 用最新的
owners = ["099720109477"] # Canonical 官方
}
ssh_username = "ubuntu" # SSH 用户名
}
# 构建流程
build {
sources = ["source.amazon-ebs.ubuntu"] # 使用上面定义的来源
# Shell 脚本安装软件
provisioner "shell" {
inline = [
"sudo apt-get update", # 更新包列表
"sudo apt-get install -y python3 python3-pip", # 安装 Python
"sudo pip3 install biopython pandas numpy", # 安装生信常用包
"sudo apt-get install -y samtools bwa fastqc", # 安装生信工具
]
}
# 执行外部脚本
provisioner "shell" {
script = "scripts/setup.sh" # 执行本地脚本
}
# 后处理:生成清单文件
post-processor "manifest" {
output = "manifest.json" # 输出构建清单
}
}
# 执行构建
packer init . # 初始化(下载插件)
packer validate . # 验证配置
packer build . # 开始构建(会启动 EC2 → 安装软件 → 创建 AMI → 销毁 EC2)
packer build -var "aws_region=ap-southeast-1" . # 指定变量构建
2. 构建 Docker 镜像¶
# docker-python.pkr.hcl
source "docker" "python" {
image = "python:3.12-slim" # 基础镜像
commit = true # 提交为新镜像
}
build {
sources = ["source.docker.python"]
provisioner "shell" {
inline = [
"pip install flask gunicorn", # 安装 Web 框架
"mkdir -p /app", # 创建应用目录
]
}
post-processor "docker-tag" {
repository = "myapp" # 镜像名
tags = ["latest", "1.0"] # 标签
}
}
高级用法¶
多平台同时构建¶
source "amazon-ebs" "aws" {
ami_name = "myapp-{{timestamp}}"
instance_type = "t3.micro"
region = "us-east-1"
source_ami = "ami-xxx"
ssh_username = "ubuntu"
}
source "docker" "local" {
image = "ubuntu:22.04"
commit = true
}
build {
sources = [
"source.amazon-ebs.aws", # 同时构建 AWS AMI
"source.docker.local", # 和 Docker 镜像
]
provisioner "shell" {
inline = ["apt-get update && apt-get install -y python3"] # 两个平台都执行
}
}
常见报错¶
| 报错信息 | 原因 | 解决方法 |
|---|---|---|
Error launching source instance | AWS 权限不足 | 检查 IAM 权限(需 EC2、AMI 相关) |
Timeout waiting for SSH | SSH 连接超时 | 检查安全组是否允许 SSH,加大超时 |
AMI name already in use | AMI 名重复 | 名称加 {{timestamp}} |
Plugin not found | 插件未安装 | packer init . 安装插件 |
速查表¶
# === 核心命令 ===
packer init . # 初始化插件
packer validate . # 验证配置
packer build . # 构建镜像
packer build -var "k=v" . # 带变量构建
packer fmt . # 格式化配置文件
packer inspect . # 查看配置详情
# === 常用供应器 ===
provisioner "shell" { inline = ["cmd"] } # Shell 命令
provisioner "shell" { script = "setup.sh" } # 执行脚本
provisioner "file" { source = "f"; destination = "/tmp/f" } # 上传文件
provisioner "ansible" { playbook_file = "playbook.yml" } # Ansible
# === 内置函数 ===
{{timestamp}} # 当前时间戳
{{uuid}} # 随机 UUID
{{env `VAR`}} # 读取环境变量
参考:Packer 文档 | 更新于 2026 年