如何在 Ubuntu 16.04 上使用 Packer 创建 DigitalOcean 快照

介绍

Packer,由Hashicorp,是一个命令行工具,用于快速为多个平台和环境创建相同的机器图像. 使用Packer,您可以使用一个配置文件,称为 template,创建一个包含预配置的操作系统和软件的机器图像。

在本教程中,您将使用 Packer 在 Ubuntu 16.04 上配置 Nginx Web 服务器,然后使用 Packer 创建此 Droplet 的截图,并在您的 DigitalOcean 仪表板中立即可用,以便您可以使用它来创建新的 Droplets。

前提条件

在你可以起床和运行与Packer之前,你需要一些东西。

第1步:下载和安装包装器

登录到您的服务器后,您将下载 Packer 二进制包,为当前用户安装 Packer,并检查您的安装是否成功。

让 Packer 在您的系统上运行的最简单的方法是从官方 Hashicorp 网站(https://releases.hashicorp.com/packer/)下载最新的二进制包。

使用弯曲实用程序从Hashicorp网站下载二进制包。

1curl -O https://releases.hashicorp.com/packer/0.12.2/packer_0.12.2_linux_amd64.zip

一旦下载,安装unzip实用程序,并使用它将包内容解密到/usr/local/bin目录中,使Packer可供所有用户使用:

1sudo apt install -y unzip
2sudo unzip -d /usr/local/bin packer_0.12.2_linux_amd64.zip

通过检查packer在命令行上可用来验证安装是否成功:

1packer

成功的安装将产生如下:

 1[secondary_label Output]
 2usage: packer [--version] [--help] <command> [<args>]
 3
 4Available commands are:
 5    build build image(s) from template
 6    fix fixes templates from old versions of packer
 7    inspect see components of a template
 8    push push a template and supporting files to a Packer build service
 9    validate check that a template is valid
10    version Prints the Packer version

Packer 现在已安装并在您的机器上工作. 在下一步,您将设置一个项目目录并配置模板以生成一个基本的 Ubuntu 快照。

步骤 2 — 配置数字海洋构建器

我们希望Packer创建一个Droplet,安装一些软件和配置文件,然后将Droplet变成一个图像,我们可以使用它来创建新的机器。

在 Packer-speak 中,一个 builder 是一个 JSON 对象,它包含您希望 Packer 创建的图像的蓝图。 使用digitalocean 构建程序,您将指示 Packer 创建一个 512 MB Ubuntu 16.04 Droplet 将于 NYC1 地区推出。

创建并更改到一个新的目录,其中将包含我们将在本教程中创建的模板和配置文件:

1mkdir ~/packerProject
2cd ~/packerProject

现在你有一个项目目录,打开一个名为template.json的新文件,在你的文本编辑器:

1nano ~/packerProject/template.json

每个构建者都需要进入template.json构建者部分. 现在添加此部分并将digitalocean构建者添加到文件中,将此代码放入文件中:

1[label ~/packerProject/template.json]
2{
3  "builders": [
4    {
5      "type": "digitalocean"
6    }]
7}

类型键定义了构建者Packer用什么来创建您的图像,而构建者digitalocean创建了DigitalOceanDropplets,由此 Packer创建了快照。

Packer 现在知道你想为 DigitalOcean 创建一个图像,但它仍然需要一些额外的关键值对才能完成构建。

通过添加这些键和值来完成配置您的Droplet,以生成在NYC1地区发布的512 MB Ubuntu 16.04 Droplet的快照。

 1[label ~/packerProject/template.json]
 2{
 3  "builders": [
 4    {
 5      "type": "digitalocean",
 6      "ssh_username": "root",
 7      "api_token": "YOUR_DIGITALOCEAN_API_TOKEN",
 8      "image": "ubuntu-16-04-x64",
 9      "region": "nyc1",
10      "size": "512mb"
11    }]
12}

Packer 使用 ssh_username 值连接到 Droplets. 此值需要设置为 "root" 以便 Packer 正常工作。

保存template.json并退出文本编辑器。

上一个代码组包含创建 DigitalOcean Droplet 所需的最低配置量,但如下表所示,还有其他配置选项可用:

| 键 数值 ====== | --—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— | 用于访问您的账户的 API 符号 。 也可以通过环境变量`DIGITALOCEAN_API_TOKEN'(如果设置的话)来指定。 |

  • 图像 ' * 弦 * 是 * * 要使用的基础图像的名称( 或 slock) 。 此图像将用来启动一个新的 Droplet 并提供它 。 见[https://developers.digitalocean.com/documentation/v2/# list-all-images](https://developers.digitalocean.com/documentation/v2/#list-all-images),关于如何获得被接受的图像名称/slugs列表的细节. | 区域 ' ==== 发射"滴"号的区域名称(或"涕"). 因此,该地区将可提供简介。 见[https://developers.digitalocean.com/documentation/v2/# list-all-regies] (https://developers.digitalocean.com/documentation/v2/# list-all-regions) 被接受的区域名称/slugs. |
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 要使用的 Droplet 大小的名称( 或 sullet) 。 见[https://developers.digitalocean.com/documentation/v2/# list-all-sizes] (https://developers.digitalocean.com/documentation/v2/# list-all-sizes) 所接受的大小名称/slugs. | api_url 字符串 ===================================================================================================================================================================================================================================================== 如果您使用数字海洋API兼容服务, 请设置此功能 。 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ DigitalOcean将机器的主机名设置为这个值. | 私人_网络' 布尔' 没有' ' 设置 ' 以真'使正在创建的Droplet的私人网络成为可能。 此默认为 或未启用 。 | snapshot_name 字符串 =================================================================================================================================================================================================================================================== 这一定是独一无二的。 | 状态-超时 QQ String QQ No XQ 作为持续字符串等待 Dropplet 进入理想状态(如 活性 )的时间, 然后再计时出局 。 默认状态超时为"6m". | QQ 用户数据 QQ 字符串 QQ 用户数据与 Droplet 一同启动. 更多信息见Droplet元数据介绍。 |

你现在有一个有效的模板,但你的 API 代码在你的模板中被硬编码。这是一个不好的做法和潜在的安全风险。在下一步中,你将为这个代码创建一个变量,并将其从 template.json 中移除。

第3步:创建和存储用户变量

Packer 允许您在单独的文件中创建和存储变量值. 此文件可以在您准备构建图像时通过命令行传递给 Packer。

将变量存储在一个单独的文件中是将敏感信息或环境特定的数据保留在模板之外的理想方式,如果您打算与团队成员共享或存储在GitHub等公开面向的存储库中,这是至关重要的。

即使您只会存储本地副本,存储变量在模板外部是最好的做法。

packerProject目录中创建并打开新的 JSON 文件以存储此信息:

1nano ~/packerProject/variables.json

现在,添加一个my_token变量,并将其值设置为您的DigitalOcean API代币:

1[label ~/packerProject/variables.json]
2{
3  "my_token": "YOUR_DIGITALOCEAN_API_TOKEN"
4}

保存variables.json并退出编辑器。

现在让我们配置我们的模板以使用变量. 在您使用my_token变量或任何其他变量之前,您首先需要通过在template.json文件的开头的变量部分中定义该变量来告诉 Packer。

在您的编辑器中打开‘template.json’:

1nano template.json

在此新部分中,声明my_token变量并将其默认值设置为空字符串:

1[label ~/packerProject/template.json]
2{
3  "variables": {
4    "my_token":""
5  },
6  "builders": [
7  ...
8
9}

变量部分中定义的变量在全球范围内可用。

接下来,在构建者部分用my_token的呼叫代替您的 API 代码:

 1[label ~/packerProject/template.json]
 2{
 3  ...
 4  "builders": [
 5    {
 6      "type": "digitalocean",
 7      "api_token": "{{ user `my_token` }}",
 8      ...
 9    }]
10}

正如您所看到的,呼叫用户变量必须使用特定的格式: ``"{用户 变量_名称 }}。

保存文件并离开编辑器。

你现在有一个工作模板,生成一个基本的快照和一个单独的变量文件来存储你的API密钥. 在你验证和构建你的图像之前,让我们在创建图像之前添加一个供应商部分到我们的模板中,这将配置Packer在机器上安装和设置 Nginx Web 服务器。

步骤4:配置供应商

供应商部分是Packer在运行 Droplet 上安装和配置软件,然后将其转化为机器图像。

为了配置 Nginx,您将使用Packer的文件提供器将配置文件上传到服务器,然后使用提供器执行使用这些文件的安装脚本。

提供者以它们在模板中出现的顺序执行,这意味着将文件提供器放在首位,因为您的壳脚本需要上传的文件。

template.json中的构建者部分后立即添加一个供应商部分,并设置您将使用的两个供应商:

 1[label ~/packerProject/template.json]
 2{
 3  ...
 4  "builders": [
 5    {
 6      ...
 7  }],
 8  "provisioners": [
 9    {
10      "type": "file"
11    },
12    {
13      "type": "shell"
14    }]
15}

文件提供器需要一个,指向本地文件路径,以及一个目的地,指向运行机器上的现有文件路径。

通过将突出的行添加到template.json来配置文件提供器:

 1[label ~/packerProject/template.json]
 2{
 3  ...
 4  "provisioners": [
 5    {
 6      "type": "file",
 7      "source": "configs/",
 8      "destination": "/tmp"
 9    },
10    ...
11}

在下一步中,我们将在本地机器上创建configs文件夹,然后通过设置shell提供器来完成配置文件的编辑。

提供器采用一个脚本密钥,其中包含一系列应该传递到运行机器的脚本,每个脚本都被上传并执行在您的模板中指定的顺序。

现在,通过提供完整的脚本路径来配置提供器:

 1[label ~/packerProject/template.json]
 2{
 3  ...
 4  "provisioners": [
 5    {
 6      "type": "file",
 7      "source": "configs/",
 8      "destination": "/tmp"
 9    },
10    {
11      "type": "shell",
12      "scripts": [
13        "scripts/configureNginx.sh"
14      ]
15    }]
16}

脚本必须单独列出,这允许您控制脚本的执行顺序。

您的模板的供应商部分已完成. 如果您正在使用nano,请按住ctrl键并按x来退出文件,并在提示时按y来保存更改。

现在,让我们创建Shell脚本和配置文件,Packer将用来创建您的图像。

步骤5 — 添加配置文件和安装脚本

在本节中,您将根据教程 如何在Ubuntu 16.04上设置 Nginx服务器块(虚拟主机)创建这些文件,因为 Nginx配置超出了本教程的范围。

我们将通过创建和上传三个单独的配置文件来为服务器提供 Nginx,这些文件由一个单一的安装脚本处理。

首先,在项目文件夹中创建一个新目录,以存储配置文件。

1mkdir ~/packerProject/configs

更改到 /configs 以创建您的 Nginx 配置文件:

1cd ~/packerProject/configs

首先,你需要一个默认的网页来从你的新域名服务. 创建文件 index.html.new:

1nano index.html.new

在这个新文件中,插入以下内容:

1[label ~/packerProject/configs/index.html.new]
2HELLO FROM YOUR TEST PAGE

接下来,您需要一个 Nginx 配置文件,该文件定义了您的域的服务器块,从而定义了听取端口和域的网页的位置。

1nano newDomain.conf

在此文件中放置下列配置:

 1[label ~/packerProject/configs/newDomain.conf]
 2server {
 3        listen 80;
 4        listen [::]:80;
 5
 6        server_name example.com;
 7
 8        location / {
 9                root /var/www/html/newDomain;
10                index index.html index.htm;
11        }
12}

<$>[注] 在本示例中,我们将example.com作为位数值。当您从图像中创建新机器时,您需要登录到新机器并更改该文件以反映指向机器的实际域名或 IP 地址。

最后,您希望 Nginx 从一个新的目录中加载您的域的配置, /etc/nginx/vhost.d/. 这意味着编辑主要的 Nginx 配置文件。

创建nginx.conf.new:

1nano nginx.conf.new

我们将使用默认的 Nginx config 文件,但我们将修改它以包括我们特定的网站配置,并确保 Nginx 作为www-data用户运行。

 1[label ~/packerProject/configs/nginx.conf.new]
 2user www-data;
 3worker_processes auto;
 4error_log /var/log/nginx/error.log;
 5pid /run/nginx.pid;
 6
 7include /usr/share/nginx/modules/*.conf;
 8
 9events {
10    worker_connections 1024;
11}
12
13http {
14    log_format main  '$remote_addr - $remote_user [$time_local] "$request" '
15                      '$status $body_bytes_sent "$http_referer" '
16                      '"$http_user_agent" "$http_x_forwarded_for"';
17
18    access_log  /var/log/nginx/access.log main;
19
20    sendfile on;
21    tcp_nopush on;
22    tcp_nodelay on;
23    keepalive_timeout 65;
24    types_hash_max_size 2048;
25
26    include             /etc/nginx/mime.types;
27    default_type application/octet-stream;
28
29    include /etc/nginx/conf.d/*.conf;
30    include /etc/nginx/vhost.d/*.conf;
31
32    server {
33        listen 80 default_server;
34        listen       [::]:80 default_server;
35        server_name _;
36        root         /usr/share/nginx/html;
37
38        include /etc/nginx/default.d/*.conf;
39
40        location / {
41        }
42
43        error_page 404 /404.html;
44            location = /40x.html {
45        }
46
47        error_page 500 502 503 504 /50x.html;
48            location = /50x.html {
49        }
50    }
51
52}

保存和退出文件。

有了配置文件,让我们定义Packer将使用的脚本来安装我们需要的软件。

1mkdir ~/packerProject/scripts

现在切换到这个新目录并创建安装脚本,‘configureNginx.sh’,该脚本会安装、配置、启用和启动 Nginx Web 服务器:

1cd ~/packerProject/scripts
2nano configureNginx.sh

将以下内容粘贴到安装、配置和启动 Nginx 的文件中,使用您刚刚创建的配置文件:

 1[label ~/packerProject/scripts/configureNginx.sh]
 2#!/bin/bash
 3# Script to install Nginx and enable on boot.
 4
 5# Update your system:
 6apt-get update -y
 7apt-get upgrade -y
 8
 9# Install Nginx:
10apt-get install -y nginx
11
12#Start Nginx service and enable to start on boot:
13systemctl enable nginx
14systemctl start nginx
15
16# Create new 'vhost' directory for domain configuration:
17mkdir /etc/nginx/vhost.d
18
19# Create a new directory to serve new content.
20mkdir -p /var/www/html/newDomain
21
22# Create a copy of original configuration files and import configuration:
23cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.original
24cp /tmp/nginx.conf.new /etc/nginx/nginx.conf
25
26# Copy over the server block configuration:
27cp /tmp/newDomain.conf /etc/nginx/vhost.d/newDomain.conf
28
29# Copy over the html test page:
30cp /tmp/index.html.new /var/www/html/newDomain/index.html
31
32# Restart Nginx:
33systemctl restart nginx

您的模板已经完成,您现在已经准备好验证和构建您的快照。

步骤6 - 验证和构建滴滴

是时候使用Packer的验证子命令来测试您的模板了.一旦您的模板验证成功,您将构建您的Droplet并创建快照。

改变你的项目的根源:

1cd ~/packerProject

验证子命令会检查您的模板是否有有效的语法和配置选项:

1packer validate -var-file=variables.json template.json

「-var-file」的旗帜读取「variables.json」并在「template.json」中设置「my_token」的值。

您将看到以下输出:

1[secondary_label Output]
2Template validated successfully.

如果有任何错误在template.json中,你会收到一个错误消息. 这个消息将取决于错误,但大多数可以通过双重检查语法和纠正任何键。

构建子命令运行您在模板的构建者部分中定义的构建,换句话说,它告诉 Packer 构建您的Droplet,然后在您的DigitalOcean仪表板中创建该Droplet的截图。

拨打packer build来构建 Droplet 并创建快照:

1packer build -var-file=variables.json template.json

请注意,-var 文件的旗帜对构建验证子命令完全相同。

成功构建的结果将看起来如下:

 1[secondary_label Output]
 2digitalocean output will be in this color.
 3
 4==> digitalocean: Creating temporary ssh key for Droplet...
 5==> digitalocean: Creating Droplet...
 6==> digitalocean: Waiting for Droplet to become active...
 7==> digitalocean: Waiting for SSH to become available...
 8==> digitalocean: Connected to SSH!
 9==> digitalocean: Gracefully shutting down Droplet...
10==> digitalocean: Creating snapshot: packer-1488487459
11==> digitalocean: Waiting for snapshot to complete...
12==> digitalocean: Destroying Droplet...
13==> digitalocean: Deleting temporary ssh key...
14Build 'digitalocean' finished.
15
16==> Builds finished. The artifacts of successful builds are:
17--> digitalocean: A snapshot was created: 'packer-1488487459' (ID: 18252043) in region 'nyc1'

成功构建后,您将在您的 DigitalOcean 快照存储库中找到一个新的快照. 在输出中,您可以找到快照的名称。

从这里,访问您的 DigitalOcean 仪表板,选择 ** 图像** ,新 Snapshot 将出现在您的列表中:

Docker snapshot in DigitalOcean dashboard

您现在可以使用这个新的快照创建新的 Droplets. 选择 ** 更多** ,然后选择 ** 创建 Droplet** . 然后填写表格来创建您的新机器。

一旦机器在线,请从仪表板中确定其IP地址并登录到新机器:

1[environment local]
2ssh root@your_new_server_ip_address

然后编辑 Nginx 服务器配置文件:

1[environment second]
2nano /etc/nginx/vhost.d/newDomain.conf

并用机器的IP地址或您将使用的域名替换example.com:

 1[label ~/packerProject/configs/newDomain.conf]
 2server {
 3        listen 80;
 4        listen [::]:80;
 5
 6        server_name your_new_server_ip_address;
 7
 8        location / {
 9                root /var/www/html/newDomain;
10                index index.html index.htm;
11        }
12}

或者,您可以使用sed命令来替换文件中的值,如下:

1sudo sed -i 's/^.*server_name example.com/server_name your_new_server_ip_address/' /etc/nginx/vhost.d/newDomain.conf

您可以在本教程(https://andsky.com/tech/tutorials/the-basics-of-using-the-sed-stream-editor-to-manipulate-text-in-linux)中了解更多关于sed的信息。

然后重新启动 Nginx 服务器以应用这些更改:

1sudo systemctl restart nginx

解决问题

在这些场景中,您可以通过启用调试模式、检查 Packer 日志或两者都提取有关构建的更多细节。

调试模式为远程构建的每个步骤提供构建者特定的调试信息. 启用调试模式为DigitalOcean构建也将生成项目文件夹中的临时私钥,您可以使用它来连接并检查运行 Droplet,然后将其转化为快照。

您可以通过在命令行上将-debug标志传输到packer build来进入调试模式:

1packer build -debug --var-file=variables.json template.json

如果您无法在调试模式中诊断问题,您可以尝试启用 Packer 日志,这些日志主要用于调试本地构建程序,但它们也可能为远程构建提供有用的信息。

若要启用 Packer 日志,请将环境变量 PACKER_LOG 设置为除 0 或空串以外的任何值:

1PACKER_LOG=1 packer build --var-file=variables.json template.json

日志将打印到控制台,除非您还设置PACKER_LOG_PATH环境变量。

如果您仍然有问题,您可能想尝试与 Packer 社区中的某人联系。

结论

现在你已经熟悉了Packer的基本知识,你可能对建立这个基础感兴趣。

尝试在您的模板中添加第二个构建器, 在您的数字海洋快照同时创建一个本地测试环境 。 例如, " Virtualbox-iso " 构建器为VirtualBox生产图像,这是企业和爱好者都使用的一种免费的开源虚拟化产品。 您可以定义 VirtualBox 图像的 后处理器 , 并创建可反映您数字海洋快照的 Vagrant 环境 。 这将允许您在本地测试网站的更改, 然后再将其推向现场 Droplet 。 您可以在 [变相处理后文档] (https://www.packer.io/docs/post-processors/vagrant.html) 中学习更多内容 .

或者您可能想将您的 Web 服务器连接到数据库. 添加第二个digitalocean构建程序,并在供应商部分中使用键,将不同的配置应用于每个构建。

如果您更舒适地使用配置管理工具,那么Packer 将支持 Ansible, Puppet, Chef,等等。 尝试使用这些提供商之一来进一步配置您的 Droplet 以匹配您的使用情况。

Published At
Categories with 技术
comments powered by Disqus