介绍
帕克 ,由Hashicorp,是用于快速创建多平台和环境相同的机器映像的命令行工具。 随着封隔器,您可以使用一个配置文件,称为模板 ,创建一个包含预配置的操作系统和软件的计算机图像。 然后,您可以使用此映像创建新计算机。 您甚至可以使用单个模板来编排您的生产,暂存和开发环境的同时创建。
在本教程中,您将使用Packer在CentOS 7上配置Nginx Web服务器。然后,您将使用Packer创建此Droplet的快照,并使其立即在您的DigitalOcean仪表板中可用,以便您可以使用它来创建新的Droplet 。
先决条件
在你可以开始使用Packer之前,你需要一些东西。
- 一个CentOS 7服务器,用sudo的特权的非root用户配置的,您可以通过跟踪设置此如何一个CentOS 7服务器上添加和删除用户 。
- 一个DigitalOcean API令牌读取和写入权限。 回顾如何使用API DigitalOcean V2获得令牌。
第1步 - 下载并安装Packer
登录到服务器后,您将下载Packer二进制包,为当前用户安装Packer,并检查安装是否成功。
得到帕克系统上运行的最简单的方法是从官方Hashicorp释放下载最新的二进制包的网站 。 在撰写本文时,最新版本为0.12.2。
使用curl
实用程序从Hashicorp网站下载二进制包。
curl -O https://releases.hashicorp.com/packer/0.12.2/packer_0.12.2_linux_amd64.zip
一旦下载,安装unzip
实用程序,并用它来解压缩包的内容到/usr/local
目录,推荐的位置,使封隔器提供给所有用户。
sudo yum install -y unzip
sudo unzip -d /usr/local packer_0.12.2_linux_amd64.zip
CentOS的已经包括了一项名为packer
,虽然你可以在每次运行一个命令时只需键入了完整的路径,更有效的方法来解决这个问题是创建一个映射一个符号链接packer.io
来/usr/local/packer
。 使在符号链接/usr/local/bin
使用下列命令文件夹:
sudo ln -s /usr/local/packer /usr/local/bin/packer.io
验证安装成功通过检查packer.io
可在命令行:
packer.io
成功安装将输出以下内容:
Outputusage: packer [--version] [--help] <command> [<args>]
Available commands are:
build build image(s) from template
fix fixes templates from old versions of packer
inspect see components of a template
push push a template and supporting files to a Packer build service
validate check that a template is valid
version Prints the Packer version
Packer现在安装并在您的机器上工作。 在下一步中,您将设置一个项目目录并配置模板以生成基本的CentOS快照。
第2步 - 配置DigitalOcean Builder
我们希望Packer创建一个Droplet,安装一些软件和配置文件,然后将Droplet转换成我们可以用来创建新机器的映像。 帕克使用名为包含所有告诉帕克如何构建一个图像的细节模板的配置文件。 我们编写使用此配置JSON ,对配置文件的通用格式。
在帕克发言, 建设者是一个包含你想封隔器来创建映像的蓝图JSON对象。 使用digitalocean
建设者,你要指导帕克创建一个512 MB的CentOS 7.3Droplet将在NYC1地区推出。
创建并更改为一个新目录,其中包含我们将在本教程中创建的模板和配置文件:
mkdir ~/packerProject
cd ~/packerProject
现在你有一个项目目录中,打开一个名为新文件template.json
,在文本编辑器:
vi ~/packerProject/template.json
每个制造商需要进入的builders
的部分template.json
。 现在加入这部分,包括digitalocean
通过将该代码到文件生成器:
{
"builders": [
{
"type": "digitalocean"
}]
}
该type
其构建器包装机键定义用来创建你的形象。 该digitalocean
生成器所创建从中派克创建快照DigitalOceanDroplet。
Packer现在知道你想为DigitalOcean创建一个图像,但它仍然需要几个键值对来完成构建。
通过添加这些键和值来完成配置您的Droplet,以从在NYC1区域启动的512 MB CentOS 7 Droplet生成快照。 修改您的文件,使其看起来像这样:
{
"builders": [
{
"type": "digitalocean",
"ssh_username": "root",
"api_token": "YOUR_DIGITALOCEAN_API_TOKEN",
"image": "centos-7-x64",
"region": "nyc1",
"size": "512mb"
}]
}
帕克连接使用,以Dropletssh_username
值。 此值需要设置为“root”才能使Packer正常工作。
保存template.json
并退出文本编辑器。
前面的代码块包含创建DigitalOcean Droplet所需的最少配置,但是还有其他可用的配置选项,如下表所示:
键 | 值 | 需要 | 描述 |
---|---|---|---|
api_token |
串 | 是 | 用于访问您的帐户的API令牌。 它也可以通过环境变量指定DIGITALOCEAN_API_TOKEN ,如果设置。 |
image |
串 | 是 | 要使用的基本映像的名称(或块)。 这是将用于启动新的Droplet并提供它的映像。 见https://developers.digitalocean.com/documentation/v2/#list-all-images关于如何得到公认的图像名称/蛞蝓的列表的详细信息。 |
region |
串 | 是 | 要启动Droplet的区域的名称(或段)。因此,这是快照将可用的区域。 见https://developers.digitalocean.com/documentation/v2/#list-all-regions为接受的地区名称/蛞蝓。 |
size |
串 | 是 | 要使用的Droplet大小的名称(或块)。 见https://developers.digitalocean.com/documentation/v2/#list-all-sizes为接受的尺寸名称/蛞蝓。 |
api_url |
串 | 没有 | 非标准API端点的URL。 如果您使用的是DigitalOcean API兼容服务,请设置此项。 |
droplet_name |
串 | 没有 | 分配给Droplet的名称。 DigitalOcean将机器的主机名设置为此值。 |
private_networking |
布尔值 | 没有 | 设置为true 要创建的Droplet的启用专用网络。 默认为false 或不启用。 |
snapshot_name |
串 | 没有 | 将在您的帐户中显示的结果快照的名称。 这必须是唯一的。 |
state_timeout |
串 | 没有 | 等待时间作为持续时间字符串,用于Droplet在超时之前进入所需状态(例如“活动”)。 默认状态超时为“6m”。 |
user_data |
串 | 没有 | 使用Droplet启动的用户数据。 见Droplet元数据的介绍了解更多信息。 |
您现在有一个有效的模板,但您的API令牌是硬编码在您的模板。 这是一个坏的做法和潜在的安全风险。 在下一步中,您将创建此令牌的变量并将其移出的template.json
。
第3步 - 创建和存储用户变量
Packer允许您在单独的文件中创建和存储变量的值。 当您准备好构建映像时,此文件可以通过命令行传递给Packer。
将变量存储在单独的文件中是将敏感信息或特定于环境的数据排除在模板外的理想方式。 如果您打算与团队成员共享或将其存储在面向公众的存储库(如GitHub)中,这是至关重要的。
即使你只保存一个本地副本,它是一个Packer最佳实践,存储模板外的变量。
创建并在打开一个新的JSON文件packerProject
目录来存储这些信息:
vi ~/packerProject/variables.json
现在,添加一个my_token
变量,并将其值设置为您DigitalOcean API令牌:
{
"my_token": "YOUR_DIGITALOCEAN_API_TOKEN"
}
保存variables.json
并退出编辑器。
现在让我们配置我们的模板使用变量。 在你使用my_token
变量,或任何其他变量,你首先需要告诉帕克通过在定义它存在的变量variables
在年初部分template.json
文件。
打开template.json
在编辑器:
vi template.json
添加一个新的variables
上面的部分builders
部分,您以前定义。 在这个新的部分,声明my_token
变量,它的默认值设置为空字符串:
{
"variables": {
"my_token":""
},
"builders": [
...
}
在定义的变量variables
部分是全局可用。
接下来,在更换您的API令牌builders
通过调用部分my_token
:
{
...
"builders": [
{
"type": "digitalocean",
"api_token": "{{ user `my_token` }}",
...
}]
}
正如你所看到的,调用用户变量必须使用特定的格式: "{{ user ` variable_name ` }}
引号和反引号是必需的,因为是双大括号。
保存文件并退出编辑器。
现在,您有一个工作模板,可生成基本快照和单独的变量文件,以存储API密钥。 在你验证,建立自己的形象,让我们添加一个provisioners
部分,我们的模板,将配置封隔器安装和设置在机器上的Nginx Web服务器创建映像之前。
第4步 - 配置Provisioner
该provisioners
部分中,帕克安装并把它变成一个机器映像之前配置上运行的软件的Droplet。 与构建器一样,您可以使用不同类型的配置来配置Droplet。
为了配置Nginx的,你要使用帕克的file
置备于配置文件上传到服务器,然后使用shell
置备执行使用这些文件的安装脚本。 该file
置备使您可以移动文件和目录,并从跑步机之前,它变成一个图像。 随着shell
置备,您可以远程的机器上执行shell脚本。
Provisioner按照在模板中显示的顺序执行。 这意味着把file
置备第一,因为你的shell脚本需要上传的文件。
添加provisioners
部分立即以下builders
在第template.json
并设置您将使用两个置备:
{
...
"builders": [
{
...
}],
"provisioners": [
{
"type": "file"
},
{
"type": "shell"
}]
}
该file
置备需要一个source
,它指向一个本地文件路径,和一个destination
,它指向跑步机上已经存在的文件的路径。 Packer只能将文件移动到已经存在的目标。 出于这个原因,我们一般文件上传到/tmp
目录。
配置file
通过添加高亮行至置备template.json
:
{
...
"provisioners": [
{
"type": "file",
"source": "configs/",
"destination": "/tmp"
},
...
}
我们将创建configs
下一步我们本地机器上的文件夹中。 我们这样做之前,让我们完成通过设置编辑配置文件shell
置备。
该shell
置备需要一个scripts
其中包含应传递给跑步机脚本数组的键。 每个脚本按照模板中指定的顺序上传和执行。
现在,配置shell
通过提供fulle路径脚本置备:
{
...
"provisioners": [
{
"type": "file",
"source": "configs/",
"destination": "/tmp"
{
"type": "shell",
"scripts": [
"scripts/configureNginx.sh"
]
}]
}
脚本必须单独列出,这允许您控制脚本的执行顺序。
该provisioners
模板的部分就完成了。 保存文件并退出Vim。
现在让我们创建一个shell脚本和配置文件,Packer将使用它来创建你的镜像。
第5步 - 添加配置文件和安装脚本
我们希望我们的映像具有完全配置的Nginx安装,具有正确的配置文件和默认网页。 在本节中,您将创建一些预定义配置这些文件的基础上,教程如何在Ubuntu 16.04设置的Nginx服务器块(虚拟主机) ,因为Nginx的配置已经超出了本文的范围。
我们将通过创建和上传由单个安装脚本处理的三个单独的配置文件来配置Nginx的服务器。
首先,在项目文件夹中创建一个新目录以存储配置文件。
mkdir ~/packerProject/configs
更改为/configs
创建Nginx的配置文件:
cd ~/packerProject/configs
首先,您需要从新网域投放默认网页。 创建文件index.html.new
:
vi index.html.new
在此新文件中,插入以下内容:
HELLO FROM YOUR TEST PAGE
接下来,您需要一个Nginx配置文件,该文件定义您的域的服务器块,定义监听端口和您的网页的位置。 创建一个名为newDomain.conf
:
vi newDomain.conf
将以下配置放在此文件中:
server {
listen 80;
listen [::]:80;
server_name example.com;
location / {
root /var/www/html/newDomain;
index index.html index.htm;
}
}
在这个例子中,我们使用example.com
作为占位符值。 从映像创建新计算机时,您必须登录到新计算机并更改此文件以反映指向计算机的实际域或IP地址。
最后,你要Nginx的,从一个新的目录加载您域的配置, /etc/nginx/vhost.d/
。 这意味着编辑主要的Nginx配置文件。
创建nginx.conf.new
:
vi nginx.conf.new
我们将使用默认的Nginx配置文件,但我们将修改它以包括我们的特定网站配置。 将以下内容放入此文件:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/vhost.d/*.conf;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
保存并退出文件。
配置文件就位,让我们定义Packer将用来安装我们需要的软件的脚本。 创建一个新文件夹以存储脚本:
mkdir ~/packerProject/scripts
现在切换到这个新的目录,并创建安装脚本, configureNginx.sh
,其安装,配置,启用和启动Nginx的网络服务器:
cd ~/packerProject/scripts
vi configureNginx.sh
将以下内容粘贴到文件中,使用刚创建的配置文件安装,配置和启动Nginx:
#!/bin/bash
# Script to install Nginx and enable on boot.
# Update your system:
yum update -y
# Install EPEL Repository, update EPEL, and install Nginx:
yum install -y epel-release
yum update -y
yum install -y nginx
#Start Nginx service and enable to start on boot:
systemctl enable nginx
systemctl start nginx
# Create new 'vhost' directory for domain configuration:
mkdir /etc/nginx/vhost.d
# Create a new directory to serve new content.
mkdir -p /var/www/html/newDomain
# Create a copy of original configuration files and import configuration:
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.original
cp /tmp/nginx.conf.new /etc/nginx/nginx.conf
# Copy over the server block configuration:
cp /tmp/newDomain.conf /etc/nginx/vhost.d/newDomain.conf
# Copy over the html test page:
cp /tmp/index.html.new /var/www/html/newDomain/index.html
# Restart Nginx:
systemctl restart nginx
您的模板已完成,您现在可以验证和构建快照。
第6步 - 验证和构建Droplet
这是一次使用帕克的测试模板validate
子命令。 一旦模板验证成功,您将构建您的Droplet并创建快照。
更改为项目的根目录:
cd ~/packerProject
该validate
命令会检查您的有效语法和配置选项模板:
packer.io validate -var-file=variables.json template.json
该-var-file
标志的读variables.json
并设置值my_token
内template.json
。
您将看到以下输出:
OutputTemplate validated successfully.
如果有什么问题template.json
,你会得到一个错误信息。 此消息将根据错误而有所不同,但大多数可以通过双重检查语法和更正任何拼写错误来解决。
在build
子命令运行您在定义的构建builders
模板的部分。 换句话说,它告诉Packer构建您的Droplet,然后在您的DigitalOcean仪表板中创建该Droplet的快照。
呼叫packer.io build
打造滴和创建快照:
packer.io build -var-file=variables.json template.json
需要注意的是-var-file
标志完全相同的方式为这两个工作build
和validate
子命令。
成功构建的输出将类似于以下内容:
Outputdigitalocean output will be in this color.
==> digitalocean: Creating temporary ssh key for Droplet...
==> digitalocean: Creating Droplet...
==> digitalocean: Waiting for Droplet to become active...
==> digitalocean: Waiting for SSH to become available...
==> digitalocean: Connected to SSH!
==> digitalocean: Gracefully shutting down Droplet...
==> digitalocean: Creating snapshot: packer-1467580504
==> digitalocean: Waiting for snapshot to complete...
==> digitalocean: Destroying Droplet...
==> digitalocean: Deleting temporary ssh key...
Build 'digitalocean' finished.
==> Builds finished. The artifacts of successful builds are:
--> digitalocean: A snapshot was created: 'packer-1487878703' (ID: 18252043) in region 'nyc1'
成功构建后,您将在您的DigitalOcean快照库中找到一个新快照。 您可以在输出中找到快照的名称。 在这个例子中,它的packer-1487878703
。
从这里,请访问DigitalOcean仪表盘,选择图像 ,然后新的快照将出现在您的列表:
您现在可以使用此新快照创建新的Droplet。 选择更多 ,然后选择创建快捷批处理 。 然后完成表单以创建新机器。
机器联机后,从仪表板确定其IP地址并登录到新机器:
ssh root@your_new_server_ip_address
然后编辑Nginx服务器配置文件:
vi /etc/nginx/vhost.d/newDomain.conf
和替换example.com
无论使用哪种机器或将使用该域名的IP地址:
server {
listen 80;
listen [::]:80;
server_name your_new_server_ip_address;
location / {
root /var/www/html/newDomain;
index index.html index.htm;
}
}
另外,您也可以使用sed
命令文件中,以取代的价值,就像这样:
sudo sed -i 's/^.*server_name example.com/server_name your_new_server_ip_address/' /etc/nginx/vhost.d/newDomain.conf
您可以了解更多有关sed
在本教程中 。
故障排除
有时,您可能遇到错误消息未能充分解释的问题。 在这些情况下,您可以通过启用调试模式,检查Packer日志或两者来提取有关构建的更多详细信息。
调试模式为远程构建中的每个步骤提供特定于构建器的调试信息。 启用DigitalOcean构建的调试模式还会在项目文件夹中生成临时私钥,您可以在将其转换为快照之前连接到并检查正在运行的Droplet。
您可以通过将进入调试模式-debug
标志packer.io build
在命令行:
packer.io build -debug --var-file=variables.json template.json
如果您无法在调试模式下诊断问题,您可以尝试启用Packer日志。 这些日志主要用于调试本地构建器,但它们也可以提供有关远程构建的有用信息。
要启用日志封隔器,设定PACKER_LOG
环境变量,除了“0”的任何值或空字符串:
PACKER_LOG=1 packer build --var-file=variables.json template.json
日志将打印到控制台,除非您还设置PACKER_LOG_PATH
环境变量。
如果您仍然有问题,你可能想尝试接触到有人在帕克社区 。
结论
现在你对Packer的基础感到舒服,你可能有兴趣在这个基础上建立。
尝试向模板中添加第二个构建器,以在DigitalOcean快照旁创建本地测试环境。 在virtualbox-iso
建设者,例如,用于产生图像VirtualBox的 ,由企业和业余爱好者使用的免费,开源的虚拟化产品。 您可以定义一个post-processor
的VirtualBox的形象和创建反映您DigitalOcean快照放浪环境。 这将允许您在本地测试网站更改,然后将其推送到现场Droplet。 你可以学到更多的流浪后处理文件 。
或者您可能想要将Web服务器连接到数据库。 添加第二个digitalocean
建设者和使用only
在关键provisioners
部分以不同的配置适用于每个版本。
如果你更舒适的使用配置管理工具,帕克自带出箱支持Ansible , Puppet , Chef等。 尝试使用这些配置程序之一进一步配置您的Droplet以匹配您的用例。 如果你从来没有尝试过的配置管理,来看看如何创建Ansible Playbook在Ubuntu自动化系统配置 。