前言:packer是根据HCL模板构建容器镜像的
注:HCL2 模板最初是作为 Packer 版本 1.5 的 beta 功能引入的。从 v1.7 开始,HCL2 支持不再处于测试阶段,并且是编写 Packer 配置的首选方式。对于老式的稳定配置语言,请参阅模板文档。从 v1.6.2 开始,您可以使用 hcl2_upgrade 命令将旧 JSON 模板转换为 HCL2 配置文件。
所以只有1.5版本以后的packer才支持HCL模板
一、 安装packer
官方文档:Packer官方网站
1.Packer 可以通过以下方式安装:
使用预编译的二进制文件
。Packer官方为所有受支持的平台和架构发布二进制文件。建议大多数用户使用此方法。- 从源安装。此方法仅推荐给高级用户。
- 使用系统的包管理器。
2.如何安装预编译的二进制文件
1.思路:
(1)要安装预编译的二进制文件
,请为您的系统下载适当的软件包。 Packer 当前打包为 zip 文件。
(2)下载 Packer 后,解压缩包。 Packer 作为一个名为 packer 的二进制文件运行。(解压后可直接运行
)
(3)最后,确保打包程序二进制文件在您的 PATH 中可用
。(即将packer移动到你的系统环境变量PATH的目录下)
tip:如何确保打包程序二进制文件在您的 PATH 中可用
分两步:
①首先打印系统环境目录(环境位置以冒号
隔开):
echo $PATH
#测试
[root@zsh bin]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
②将 Packer 二进制文件移动到列出的位置之一
。(此命令假定二进制文件当前位于您的下载文件夹中,并且您的 PATH 包含 /usr/local/bin,但如果您的位置不同,您可以自定义它)。
mv ~/Downloads/packer /usr/local/bin/
2.演示:这里在Linux系统中进行packer安装演示:
如何下载:不同平台的packer下载方法
①在centos7.9下安装packer,执行以下命令
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
sudo yum -y install packer
②在进行yum安装完packer后,会自动进行解压,解压后的二进制文件就是packer。
#下载完packer的默认存储路径为/usr/bin/目录下
#如何查看是否下载安装包成功呢,列出所有安装包,用grep筛选
[root@zsh~]# rpm -qa|grep packer
packer-1.8.0-1.x86_64
#查看安装包路径
[root@zsh ~]# rpm -ql packer-1.8.0-1.x86_64
/usr/bin/packer
#现在将packer移动到/usr/local/bin/目录下
mv usr/bin/packer /usr/local/bin/
③将packer移动到/usr/local/bin/后,验证packer。
#命令:packer -v
#测试
[root@zsh bin]# packer -v
1.8.0
#或者直接输入packer
[root@zsh bin]# packer
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
fmt Rewrites HCL2 config files to canonical format
hcl2_upgrade transform a JSON template into an HCL2 configuration
init Install missing plugins or upgrade plugins
inspect see components of a template
plugins Interact with Packer plugins and catalog
validate check that a template is valid
version Prints the Packer version
二、 构建docker镜像(Build Image)
安装 Packer 后,是时候构建您的第一个映像了,您将构建一个 Docker 容器。如果你没有安装 Docker,你可以在这里下载它Docker。
1.编写 Packer 模板
注意:编写Packer模板前要确认packer版本>=1.5,否则无法解析HCL语言
Packer 模板是一个配置文件,它定义了您要构建的映像以及如何构建它。 Packer 模板使用 Hashicorp 配置语言 (HCL)。
①创建一个名为 packer_tutorial 的新目录。该目录将包含本教程的 Packer 模板。
mkdir packer_tutorial
②导航到packer_tutorial目录。
cd packer_tutorial
③创建一个文件 docker-ubuntu.pkr.hcl。
touch docker-ubuntu.pkr.hcl
④将以下 HCL 块添加到其中并保存文件。
这是一个完整的 Packer 模板,您将使用它来构建 Ubuntu Docker 映像。在以下部分中,您将更详细地查看此模板的每个块。
packer {
required_plugins {
docker = {
version = ">= 0.0.7"
source = "github.com/hashicorp/docker"
}
}
}
source "docker" "ubuntu" {
image = "ubuntu:xenial"
commit = true
}
build {
name = "learn-packer"
sources = [
"source.docker.ubuntu"
]
}
2.初始化 Packer 配置
1.packer init .
packer init .
Packer 将下载您在上面定义的插件。在这种情况下,Packer 将下载大于 0.0.7 版本的 Packer Docker 插件
3.格式化并验证您的 Packer 模板
1.格式化模板
packer fmt .
2.验证模板
packer validate .
4.构建 Packer 映像
1.构建镜像
packer build docker-ubuntu.pkr.hcl
2.列出所有镜像
docker images
5.过程演示图
三、使用配置器将软件安装和配置到您的映像(镜像)中
在上一教程中,您使用 Packer 创建了第一个容器映像。但是,您构建的映像实质上是重新打包了现有的 Docker 映像。 Packer 的真正实用性是自动配置,以便在将软件转换为映像之前在机器中安装和配置软件。
在本教程中,您将使用配置器设置环境变量并在 Docker 映像中创建文件。虽然定义环境变量和在 Docker 映像中创建文件只是一个小示例,但它应该让您了解 Packer 配置程序可以做什么
1.Prerequisite(先决条件)
本教程基于前面的教程继续操作,如果没有进行前面操作,请先进行以下操作。
①安装packer
②编写HCL模板
创建一个名为 packer_tutorial 的目录并将以下配置粘贴到名为 docker-ubuntu.pkr.hcl 的文件中。
packer {
required_plugins {
docker = {
version = ">= 0.0.7"
source = "github.com/hashicorp/docker"
}
}
}
source "docker" "ubuntu" {
image = "ubuntu:xenial"
commit = true
}
build {
name = "learn-packer"
sources = [
"source.docker.ubuntu"
]
}
③初始化Packer模板配置(pcaker init .)
packer init .
2.Add provisioner to template(将配置器添加到模板)
使用配置器可以让您完全自动化对镜像的修改。您可以使用 shell 脚本、文件上传以及与现代配置管理工具(例如 Chef 或 Puppet)的集成。
要编写您的第一个配置程序,请将以下块添加到您的 Packer 模板中,在构建块内部和源分配下方(即build内,source下方)
provisioner "shell" {
environment_vars = [
"FOO=hello world",
]
inline = [
"echo Adding file to Docker Container",
"echo \"FOO is $FOO\" > example.txt",
]
}
#这个块定义了一个 shell 配置器,它在 shell 执行环境中设置一个名为 FOO 的环境变量,并运行 inline 属性中的命令。此配置程序将创建一个名为 example.txt 的文件,其中包含 FOO is hello world。
您的构建块应该为:
build {
name = "learn-packer"
sources = [
"source.docker.ubuntu"
]
provisioner "shell" {
environment_vars = [
"FOO=hello world",
]
inline = [
"echo Adding file to Docker Container",
"echo \"FOO is $FOO\" > example.txt",
]
}
}
添加后为:
packer {
required_plugins {
docker = {
version = ">= 0.0.7"
source = "github.com/hashicorp/docker"
}
}
}
source "docker" "ubuntu" {
image = "ubuntu:xenial"
commit = true
}
#构建器
build {
name = "learn-packer"
#源分配
sources = [
"source.docker.ubuntu"
]
provisioner "shell" {
environment_vars = [
"FOO=hello world",
]
inline = [
"echo Adding file to Docker Container",
"echo \"FOO is $FOO\" > example.txt",
]
}
}
3.Build image(构建修改后的镜像)
使用配置器构建镜像
packer build docker-ubuntu.pkr.hcl
从packer的输出中可以清晰地看到进行的改动信息。
在输出中,您将找到使用 shell 脚本进行配置,确认 Packer 运行了配置步骤。注意 Packer 如何输出第一个内联命令(将文件添加到 Docker 容器)。
4.Verify update image(验证更新后的镜像)
通过使用 Docker 运行镜像来验证镜像。
①首先查找Image ID
,并修改镜像标签(新建的镜像是没有REPOSITORY和TAG的,可以根据创建时间判断哪个是我们新建的镜像)
[root@zsh packer_tutorial]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 4637a109718e 13 minutes ago 135MB
<none> <none> f9d33370206f 11 hours ago 135MB
hello-world latest feb5d9fea6a5 6 months ago 13.3kB
ubuntu xenial b6f507652425 7 months ago 135MB
[root@zsh packer_tutorial]# docker tag 4637a109718e ubuntu_update:xenial_addfile
[root@zsh packer_tutorial]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu_update xenial_addfile 4637a109718e 14 minutes ago 135MB
<none> <none> f9d33370206f 11 hours ago 135MB
hello-world latest feb5d9fea6a5 6 months ago 13.3kB
ubuntu xenial b6f507652425 7 months ago 135MB
②要验证配置器在新镜像中创建了 example.txt 文件
,首先启动新创建的 Docker 镜像
。在终端中将 IMAGE_ID 替换为上面显示的值(如上面的输出所示,本地等效于 4637a109718e)。
docker run -it IMAGE_ID
//测试,启动镜像后就会进入ubuntu容器,此时容器就是一个ubuntu操作系统实例(启动ubuntu容器实例,进入shell终端)
[root@zsh packer_tutorial]# docker run -it 4637a109718e
#
③在 Docker 容器Shell中,打印 example.txt 文件的内容。这应该返回 FOO is hello world 正如预期的那样。
cat example.txt
//测试
#启动添加了example.txt文件的镜像,生成Ubuntu容器实例
[root@zsh packer_tutorial]# docker run -it 4637a109718e
# ls
bin dev example.txt lib media opt proc run srv tmp var
boot etc home lib64 mnt packer-files root sbin sys usr
# cat example.txt
FOO is hello world
#
过程截图如下:
启动ubuntu容器实例,进入shell终端
④退出容器
exit
5.总结
-
上面演示的 shell 配置器非常强大和灵活。对于复杂的配置,您可以传递
整个 shell 脚本
,而不是上面显示的内联声明。 -
您可以根据需要运行任意数量的配置器。配置器按照声明的顺序运行。
-
用以下内容替换现有的构建块。这会在构建块的末尾添加一个配置器,它将在 shell 执行环境中打印一条消息。
build {
name = "learn-packer"
sources = [
"source.docker.ubuntu"
]
provisioner "shell" {
environment_vars = [
"FOO=hello world",
]
inline = [
"echo Adding file to Docker Container",
"echo \"FOO is $FOO\" > example.txt",
]
}
provisioner "shell" {
inline = ["echo This provisioner runs last"]
}
}
-
Build and verify updated image(构建并验证更新的镜像)
再次构建镜像。
packer build docker-ubuntu.pkr.hcl
上面第二个配置器中仅显示预期的信息,没有执行其他操作,此时再查看又多了一个镜像
#查看镜像,最新的就是我们新构建的镜像。(最上面那个)
[root@zsh packer_tutorial]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> d1d39530765d 3 minutes ago 135MB
ubuntu_update xenial_addfile 4637a109718e 2 hours ago 135MB
<none> <none> f9d33370206f 13 hours ago 135MB
hello-world latest feb5d9fea6a5 6 months ago 13.3kB
ubuntu xenial b6f507652425 7 months ago 135MB
四、Variables变量
-
在上一个教程中,您实现了第一个配置器。但是,您的 Packer 模板是静态的。目前如果你想改变文件的内容,你需要手动更新你的模板。
-
您可以使用输入变量作为 Packer 构建的参数,允许在不更改 Packer 模板的情况下自定义构建的各个方面。此外,当您想要在整个模板中引用特定值时,Packer 变量很有用。
-
在本教程中,您将添加 Packer 变量来参数化您的 Packer 构建,使其更加健壮。
-
总结:就是将packer模板中的参数用变量替代,没有写死,在需要更改的时候直接改变量的值
-
此外,当您想要在整个模板中引用特定值时,Packer 变量很有用。
-
在本教程中,您将添加 Packer 变量来参数化您的 Packer 构建,使其更加健壮。
-
总结:就是将packer模板中的参数用变量替代,没有写死,在需要更改的时候直接改变量的值
1.Prerequisites(先决条件)
本教程假设您从前面的教程继续学习。如果没有执行,执行2.3的先决条件中的操作。
①安装packer
②编写HCL模板
创建一个名为 packer_tutorial 的目录并将以下配置粘贴到名为 docker-ubuntu.pkr.hcl 的文件中。
packer {
required_plugins {
docker = {
version = ">= 0.0.7"
source = "github.com/hashicorp/docker"
}
}
}
source "docker" "ubuntu" {
image = "ubuntu:xenial"
commit = true
}
build {
name = "learn-packer"
sources = [
"source.docker.ubuntu"
]
provisioner "shell" {
environment_vars = [
"FOO=hello world",
]
inline = [
"echo Adding file to Docker Container",
"echo \"FOO is $FOO\" > example.txt",
]
}
provisioner "shell" {
inline = ["echo This provisioner runs last"]
}
}
③初始化Packer模板配置(pcaker init .)
packer init .
2.Add variable to template(将变量添加到模板)
将以下变量块添加到您的 docker-ubuntu.pkr.hcl 文件中。
variable "docker_image" {
type = string
default = "ubuntu:xenial"
}
变量块声明变量名称(docker_image)、数据类型(字符串)和默认值(ubuntu:xenial)。虽然变量类型和默认值是可选的,但我们建议您在创建新变量时定义这些属性。
将 Packer 变量视为常量——您不能在运行时更新它们。
在您的 Packer 模板中,更新您的源代码块以引用 docker_image 变量。请注意模板如何将变量引用为
var.docker_image(通过var.变量名
来引用变量)
更新第二个配置器以打印 docker_image 变量。请注意,即使在上面的源代码块中直接使用了 docker_image 变量,要将变量嵌入到另一个字符串中,您需要使用语法 ${} 对其进行模板化,如在配置程序块中回显 docker_image 时所示。
添加后模板如下:
packer {
required_plugins {
docker = {
version = ">= 0.0.7"
source = "github.com/hashicorp/docker"
}
}
}
#定义变量块
variable "docker_image" {
type = string
default = "ubuntu:xenial"
}
source "docker" "ubuntu" {
image