如何在DigitalOceanUbuntu16.04Droplets上自动扩展Web应用程序
介绍
在本教程中,我们将演示如何使用 DigitalOcean API 来使用 DOProxy 水平扩展您的服务器设置,这是一个 Ruby 脚本,一旦配置,它会提供一个命令行界面来向上或向下扩展您的 HTTP 应用程序服务器层.
DOProxy 是专门为本教程编写的,旨在通过使用 DigitalOcean API 以及管理 HAProxy 负载均衡器的成员资格来提供一种简单的方法来创建和删除应用程序服务器 Droplets。 这种基本的扩展模型允许用户通过 HAProxy 服务器访问您的应用程序,而 HAProxy 服务器又会以负载平衡的方式将它们转发到后端应用程序服务器。
DOProxy 执行三个主要功能:
- 创建 Droplet 并将它们添加到负载均衡器
- 删除 Droplet 并将其从负载均衡器中移除
- 维护它创建的 Droplet 的清单,直到它们被删除
注意: 本教程的主要目的是教授通过 API 以编程方式扩展 DigitalOcean 服务器架构所需的最低限度概念。 你不应该在生产环境中运行 DOProxy,因为它的设计没有考虑到弹性,它只执行非常基本的错误检查。 话虽如此,熟悉此脚本是让您开始通过 DigitalOcean API 学习水平缩放的好方法。
先决条件
本教程使用以下技术,在继续之前您可能需要了解这些技术:
因为 DOProxy 是用 Ruby 编写的,所以了解 Ruby 会很有帮助。 为了更加熟悉 Ruby,您可以阅读我们关于 如何在 Ruby 中编码 的系列文章。 如果您对 Ruby 不太熟悉,我们提供了一些伪代码来解释 DOProxy 代码的要点。 为了简化对 API 的调用,我们使用 DropletKit,它是官方的 DigitalOcean Ruby 包装器。
在深入了解 DOProxy 的工作原理之前,我们将在服务器上安装和使用它。
现在让我们在 Ubuntu 16.04 Droplet 上安装 DOProxy。
安装 DOProxy
首先,在 NYC3 区域创建一个 Ubuntu 16.04 Droplet,DOProxy 默认使用该区域。 如果您希望使用其他区域,则需要在安装 DOProxy 后在 doproxy.yml
文件中配置 region
变量。 这个 Droplet 将运行 HAProxy 负载均衡器和 DOProxy 扩展脚本,因此请选择一个您认为足以满足您所需扩展潜力的大小。 因为本教程是一个基本的扩展演示,没有预期的实际流量,所以 512MB 的大小可能就足够了。
对于本文档的长度,我们将这个 Droplet 称为 DOProxy 服务器。
接下来,登录服务器并按照 DOProxy 中的 Installation 和 Configuration(包括 doproxy config 和 Userdata)部分GitHub 存储库 README 在此服务器上安装 DOProxy。 请务必替换 DOproxy 配置文件中的 YOUR_DO_API_TOKEN
和 YOUR_SSH_KEY_FINGERPRINT
值,否则脚本将不起作用。
现在您已经在服务器上安装了 DOProxy 和 HAProxy,让我们尝试扩展环境。
运行 DOProxy
以 root 身份登录您的 DOProxy 服务器,然后进入您克隆 DOProxy 的目录。
不带任何参数运行 DOProxy:
ruby doproxy.rb
这应该打印出可用的命令:
OutputCommands: doproxy.rb print # Print backend Droplets in inventory file doproxy.rb create # Create a new backend Droplet and reload doproxy.rb delete <LINE_NUMBER> # Delete a Droplet and reload doproxy.rb reload # Generate HAProxy config and reload HAProxy doproxy.rb generate # Generate HAProxy config based on inventory
此时,DOProxy 还没有创建任何 Droplets。 让我们创建一些来让我们的 HTTP 服务在线,并扩大规模。
放大(创建)
运行 create
命令创建由 DOProxy 管理的第一个 Droplet:
ruby doproxy.rb create
这将需要一些时间才能返回提示(因为脚本通过 API 创建了一个新的 Droplet 并等待它启动)。 当我们通过伪代码时,我们将讨论如何进行 API 调用。
脚本完成后,您应该会看到一条包含 Droplet ID 的成功消息:
OutputSuccess: 4202645 created and added to backend.
建议您在提示返回后等待几分钟,然后再继续下一步,因为 userdata 脚本可能尚未运行,因此 HAProxy 可能尚未开始传递流量。
一旦您准备好继续,请在 Web 浏览器中访问您的 DOProxy 服务器的公共 IP 地址。 您应该会看到一个页面,其中列出了您的新 Droplet 的 主机名、id 和 公共 IP 地址。
我们将使用 DOProxy 再创建两个 Droplet,总共三个。 如果您愿意,请随意创建更多内容:
ruby doproxy.rb create ruby doproxy.rb create
现在再次在 Web 浏览器中访问您的 DOProxy 服务器的公共 IP 地址。 如果刷新页面,您会注意到页面上的信息会在循环浏览您创建的 Droplet 时发生变化。 这是因为它们都由 HAProxy 进行负载平衡,HAProxy 在使用 DOProxy 创建时将每个 Droplet 添加到其配置中。
如果您碰巧查看 DigitalOcean 控制面板,您会注意到这些新的 Droplet 将列在那里(连同您的其余 Droplet):
让我们仔细看看通过查看 DOProxy 的库存创建的 Droplet。
打印库存
DOProxy 提供了一个 print
命令,该命令将打印出属于其库存的所有 Droplet:
ruby doproxy.rb print
您应该会看到如下所示的输出:
Output0) auto-nginx-0 (pvt ip: 192.0.2.175, status: active, id: 4202645) 1) auto-nginx-1 (pvt ip: 192.0.2.176, status: active, id: 4205587) 2) auto-nginx-2 (pvt ip: 192.0.2.172, status: active, id: 4205675)
在示例输出中,我们看到有关我们创建的三个 Droplet 的信息,包括它们的主机名、状态和 Droplet ID。 当您访问 HAProxy 负载平衡器(通过 DOProxy 的公共 IP 地址)时,主机名和 ID 应与您在 Web 浏览器中看到的一致。
您可能已经注意到,DOProxy 仅打印有关它创建的 Droplets 的信息。 这是因为它维护了它创建的 Droplet 的清单。
现在查看 inventory
文件的内容:
cat inventory
您应该看到每个 Droplet 的 ID,每行一个。 每次创建 Droplet 时,其 ID 都会存储在此清单文件中。
您可能已经猜到了,DOProxy 的 print
命令遍历清单文件中的 Droplet ID,并执行 API 调用以检索有关它们中的每一个的信息。
应该注意的是,将服务器清单存储在单个文件中并不是最好的解决方案——它很容易被损坏或删除——但它展示了一个有效的简单实现。 分布式键值存储,例如 etcd,将是更好的解决方案。 您还希望在清单中保存的不仅仅是 Droplet ID(因此您不必每次要查看某些 Droplet 信息时都进行 API 调用)。
缩小(删除)
DOProxy 还有一个 delete
命令,可让您删除库存中的液滴。 delete
命令要求您提供要删除的 Droplet 的行号(由 print
命令显示)。
在运行此命令之前,您可能需要打印您的库存:
ruby doproxy.rb print
因此,例如,如果要删除第三个 Droplet,则应提供 2
作为行号:
ruby doprorxy.rb delete 2
片刻之后,您将看到确认消息:
OutputSuccess: 4205675 deleted and removed from backend.
delete
命令通过 API 删除 Droplet,将其从 HAProxy 配置中删除,并将其从清单中删除。 随意使用 DOProxy 打印命令或检查 DigitalOcean 控制面板来验证 Droplet 是否已删除。 您还会注意到它不再是负载均衡器的一部分。
HAProxy 配置
我们尚未讨论的最后一个 DOProxy 是 HAProxy 是如何配置的。
当您运行 create
或 delete
DOProxy 命令时,将检索清单中每个 Droplet 的信息,其中一些信息用于修改 HAProxy 配置文件。 特别是,Droplet ID 和私有 IP 地址用于将每个 Droplet 添加为后端服务器。
查看生成的 haproxy.cfg
文件的最后几行,如下所示:
tail haproxy.cfg
您应该看到如下内容:
haproxy.cfg 的尾部
frontend www-http bind 203.0.113.43:80 reqadd X-Forwarded-Proto:\ http default_backend www-backend backend www-backend server www-4202645 192.0.2.175:80 check # id:4202645, hostname:auto-nginx-0 server www-4205587 192.0.2.176:80 check # id:4205587, hostname:auto-nginx-1
frontend
部分应包含您的 DOProxy 服务器的公共 IP 地址,而 backend
部分应包含引用创建的每个 Droplet 的行。
注意: 此时,您可能需要删除使用 DOProxy 创建的其余 Droplet(ruby doproxy.rb delete 0
直到所有服务器都消失)。
现在您已经看到了 DOProxy 的缩放效果,让我们仔细看看代码。
DO代理代码
在本节中,我们将查看使 DOProxy 工作的相关文件和代码行。 了解 DOProxy 是如何实现的应该会让您了解如何使用 API 来管理和自动化您自己的服务器基础架构。
由于您将存储库克隆到服务器,因此您可以查看那里的文件,也可以查看 DOProxy 存储库 (https://github.com/scanevari/doproxy) 中的文件。
重要文件:
- doproxy.rb:DOProxy Ruby 脚本。 提供 DOProxy 背后的命令行界面和逻辑
- doproxy.yml:DOProxy 配置文件。 包含 API 令牌并指定 Droplet 创建选项
- haproxy.cfg.erb:HAProxy 配置模板。 用于生成具有适当后端服务器信息的负载均衡器配置
- inventory:Droplet 库存文件。 存储创建的 Droplet 的 ID
- user-data.yml:用户数据文件。 一个云配置文件,在创建时将在新的 Droplet 上运行
让我们首先深入了解配置文件。
多代理.yml
这些是 doproxy.yml
中的重要行:
多代理.yml
token: YOUR_DO_API_TOKEN ssh_key_ids: - YOUR_SSH_KEY_FINGERPRINT ... droplet_options: hostname_prefix: auto-nginx region: nyc3 size: 1gb image: ubuntu-16-04-x64
token
属性是必须持有您的 读写 API 令牌的属性。
其他行指定 DOProxy 创建新 Droplet 时将使用的选项。 例如,安装指定的 SSH 密钥(通过 ID 或指纹)并在主机名前加上“auto-nginx”。
有关有效 Droplet 选项的更多信息,请参阅 DigitalOcean API 文档。
用户数据.yml
这是创建每个新 Droplet 时 cloud-init 将执行的文件。 这意味着您可以提供一个云配置文件或脚本来在每个新的 Droplet 上安装您的应用程序软件。
示例用户数据文件包含一个简单的 bash 脚本,该脚本在 Ubuntu 服务器上安装 Nginx,并将其默认配置文件替换为 Droplet 的主机名、ID 和公共 IP 地址:
用户数据.yml
#!/bin/bash apt-get -y update apt-get -y install nginx export DROPLET_ID=$(curl http://169.254.169.254/metadata/v1/id) export HOSTNAME=$(curl -s http://169.254.169.254/metadata/v1/hostname) export PUBLIC_IPV4=$(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address) echo Droplet: $HOSTNAME, ID: $DROPLET_ID, IP Address: $PUBLIC_IPV4 > /var/www/html/index.html
那些 curl
命令正在使用 DigitalOcean 元数据服务检索有关 Droplet 的信息(主机名、ID 和 IP 地址)。
在生产实现中,此文件将包含例如安装和配置应用程序的命令。 您还可以通过自动安装 SSH 密钥和连接到您的配置管理或监控工具等操作,使用它来自动将您的 Droplet 集成到您的整体基础架构中。
要了解有关用户数据、云配置和元数据的更多信息,请查看以下链接:
haproxy.cfg.erb
HAProxy 配置模板包含大部分负载均衡器配置,其中一些 Ruby 代码将替换为后端 Droplet 信息。
我们将只看生成后端配置的 Ruby 部分:
haproxy.cfg.erb
backend www-backend <% @Droplets.each_with_index do |droplet, index| %> server www-<%= droplet.id %> <%= droplet.private_ip %>:80 check # id:<%= droplet.id %>, hostname:<%= droplet.name -%> <% end %>
此代码遍历清单中的每个 Droplet,并为每个 Droplet 添加一个新的 HAProxy 后端条目(基于私有 IP 地址)。
例如,将为每个 Droplet 生成这样的行:
haproxy.cfg
server www-4202645 192.0.2.175:80 check # id:4202645, hostname:auto-nginx-0
每当创建或删除 Droplet 时,DOProxy 都会生成一个包含更改的新 HAProxy 配置文件。
多代理.rb
这个 Ruby 脚本主要由一个 DOProxy 类组成,该类包含执行 Droplet 创建和删除、库存管理和 HAProxy 配置生成的方法。
如果您了解 Ruby,请查看 GitHub 上的文件:https://github.com/scanevari/doproxy/blob/master/doproxy.rb。
如果您不了解 Ruby,这里有一些简化的 pseudocode
来解释每种方法。 将它与实际的 Ruby 代码进行比较可能很有用,以帮助您了解正在发生的事情。
def initialize
每次 DOProxy 使用任何有效参数运行时执行:
- 读取
doproxy.yml
配置文件并获取 API 令牌和 Droplet 选项。
def get\_inventory
检索清单文件中每个 Droplet 的信息。 它必须在执行任何其他方法之前执行。
- 读取库存文件(包含 Droplet ID)
- 对于每个 Droplet ID,使用 API 检索 Droplet 信息
def print\_inventory
此方法打印库存文件中每个 Droplet ID 的 Droplet 信息。 它通过 doproxy.rb print
命令调用。
- 对于清单中的每个 Droplet,打印主机名、私有 IP 地址、状态和 ID
def create\_server
当通过 doproxy.rb create
命令调用时,此方法会创建一个新的 Droplet 并将其添加到清单文件中。 然后,它调用 reload_haproxy
重新生成 HAProxy 配置文件并重新加载负载均衡器。
- 读取用户数据文件
- 使用 API 根据提供的用户数据和选项创建 Droplet
- 等待 Droplet 状态变为“活动”——使用 API 每 15 秒检索一次 Droplet 信息,直到状态发生变化
- 当状态为“活动”时,将 Droplet ID 添加到库存文件
- 调用
reload_haproxy
重新生成 HAProxy 配置文件并重新加载负载均衡器
def delete\_server(line\_number)
当使用 doproxy.rb delete
命令时,该方法会删除指定的 Droplet 并从清单文件中删除其 ID。 然后调用 reload_haproxy
重新生成 HAProxy 配置文件并重新加载负载均衡器。
- 从库存文件中删除指定行(删除 Droplet ID)
- 使用 API 按 ID 删除 Droplet
- 调用
reload_haproxy
重新生成 HAProxy 配置文件并重新加载负载均衡器
def generate\_haproxy\_cfg
这是一种支持方法,可根据清单中的 Droplet 创建新的 HAProxy 配置文件。
- 打开HAProxy配置模板(
haproxy.cfg.erb
) - 对于库存中的每个 Droplet,添加相应的后端服务器条目
- 将生成的
haproxy.cfg
文件写入磁盘
def reload\_haproxy
这是另一种支持方法,将 HAProxy 配置文件复制到正确的位置并重新加载 HAProxy。 这依赖于 generate_haproxy_cfg
。
- 将 HAProxy 配置文件
haproxy.cfg
复制到 HAProxy 将在重新加载时查找它的位置 - 重新加载 HAProxy
这就是使 DOProxy 工作的所有重要代码。 我们将讨论的最后一件事是 DropletKit,我们在 DOProxy 中使用的 API 包装器。
DropletKit 宝石
DOProxy 使用 DropletKit gem 这是官方的 DigitalOcean API v2 Ruby 包装器,可促进对 DigitalOcean API 的调用。 DropletKit 允许我们轻松编写 Ruby 程序,这些程序可以执行以下操作:
- 创建新的液滴
- 删除现有的 Droplet
- 获取有关现有 Droplet 的信息,例如状态、IP 地址、Droplet ID、区域等
本教程侧重于这些特定的 API 端点,但请记住,还有许多其他端点可以帮助您以编程方式管理您的 DigitalOcean 服务器基础架构。
结论
现在您已经了解了一个简单的脚本如何通过利用 DigitalOcean API、云配置和元数据来帮助扩展服务器环境,您可以应用所有这些概念来扩展您自己的服务器设置。 虽然 DOProxy 不适合生产使用,但它应该为您提供一套很好的想法来实现您自己的扩展解决方案。
请记住,此处使用 DOProxy 描述的缩放设置是信息性的,但通过将其与我们的 监控系统 结合使用,可以大大改善它。 这将允许您根据某些条件(例如服务器资源利用率)自动向上和向下扩展应用程序服务器层。