如何在DigitalOceanUbuntu14.04Droplets上自动扩展Web应用程序

来自菜鸟教程
跳转至:导航、​搜索

介绍

在本教程中,我们将演示如何使用 DigitalOcean API 来水平扩展您的服务器设置。 为此,我们将使用 DOProxy,这是一个相对简单的 Ruby 脚本,一旦配置完成,它就会提供一个命令行界面来向上或向下扩展 HTTP 应用程序服务器层。

DOProxy 是专门为本教程编写的,它提供了一种简单的方法来创建和删除应用程序服务器 droplet,使用 DigitalOcean API,并在 HAProxy 负载平衡器后面自动管理它们。 这种基本的扩展模型允许您的用户通过 HAProxy 服务器访问您的应用程序,该服务器会将他们转发到负载平衡的后端应用程序服务器。

DOProxy 执行三个主要功能:

  • 创建一个 Droplet,并将其添加到负载均衡器
  • 删除 Droplet,并将其从负载均衡器中移除
  • 维护它创建的液滴的清单,直到它们被删除

注意: 本教程的主要目的是教授通过 API 以编程方式扩展 DigitalOcean 服务器架构所需的最低限度概念。 您不应该在生产环境中以当前形式运行 DOProxy; 它的设计并没有考虑到弹性,它只执行了足够的错误检查。 话虽如此,如果您对通过 API 了解水平扩展感到好奇,这是一个很好的入门方式。

先决条件

本教程涉及在继续之前您可能需要阅读的各种技术,包括:

因为 DOProxy 是用 Ruby 编写的,所以了解 Ruby 是加分项,但不是必需的; 我们将提供伪代码来解释 DOProxy 代码的要点。 此外,我们将使用官方的 DigitalOcean Ruby 包装器 DropletKit,它使我们能够轻松地在 Ruby 代码中进行 API 调用。

在我们深入了解 DOProxy 的工作原理之前,我们将在服务器上安装和使用它。 现在让我们在 Ubuntu 14.04 droplet 上安装 DOProxy。

安装 DOProxy

首先,在 NYC3 区域创建一个 Ubuntu 14.04 droplet(如果您在 [X192X ] 安装 DOProxy 后的文件)。 此 Droplet 将运行 HAProxy 负载均衡器和 DOProxy 扩展脚本,因此请选择您认为足以满足您所需扩展潜力的大小。 因为本教程是扩展的基本演示,不会接收任何实际流量,所以 1GB 大小可能就足够了。

我们将此液滴称为 DOProxy 服务器

接下来,登录并关注 DOProxy GitHub 存储库中的 InstallationConfiguration(包括 doproxy configUserdata)部分 在此服务器上安装 DOProxy。 按照说明中的说明,通过复制样本 doproxy.ymluser-data.yml 文件来使用它们。 一定要替换 DOproxy 配置文件中的 tokenssh_key_ids 值,否则脚本将不起作用。

现在您已经在服务器上安装了 DOProxy 和 HAProxy,让我们尝试扩展我们的环境。

运行 DOProxy

root 身份登录到您的 DOProxy 服务器,然后切换到您克隆 DOProxy 的目录(如果您还没有这样做的话)。

现在运行 DOProxy 不带任何参数:

ruby doproxy.rb

这应该打印出可用的命令,如下所示:

Commands:
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 尚未创建任何液滴。 让我们创建一些来让我们的 HTTP 服务在线,并扩大规模。

放大(创建)

运行 create 命令创建由 DOProxy 管理的第一个 droplet:

ruby doproxy.rb create

这将需要一些时间才能返回到提示(因为脚本通过 API 创建了一个新的 droplet 并等待它启动)。 稍后,当我们浏览 DOProxy 代码时,我们将讨论如何进行 API 调用。

完成后,您应该会看到一条包含液滴 ID 的成功消息,如下所示:

Success: 4202645 created and added to backend.

如果您在网络浏览器中访问您的 DOProxy 服务器的公共 IP 地址。 您应该会看到一个页面,其中列出了新 droplet 的 主机名id公共 IP 地址

我们将使用 DOProxy 再创建两个液滴,总共三个。 如果您愿意,请随意创建更多内容:

ruby doproxy.rb create
ruby doproxy.rb create

现在再次在 Web 浏览器中访问您的 DOProxy 服务器的公共 IP 地址。 如果刷新页面,您会注意到页面上的信息会发生变化——它会循环显示您创建的液滴。 这是因为它们都由 HAProxy 进行负载平衡——每个 Droplet 在创建时都被添加到负载平衡器配置中。

如果您碰巧查看 DigitalOcean 控制面板,您会注意到这些新的水滴将列在那里(与您的其余水滴一起):

让我们仔细看看通过查看 DOProxy 的库存创建的液滴。

打印库存

DOProxy 提供了一个 print 命令,它将打印出所有属于其库存的液滴:

ruby doproxy.rb print

您应该会看到如下所示的输出:

0) auto-nginx-0  (pvt ip: 10.132.224.168, status: active, id: 4202645)
1) auto-nginx-1  (pvt ip: 10.132.228.224, status: active, id: 4205587)
2) auto-nginx-2  (pvt ip: 10.132.252.42, status: active, id: 4205675)

在示例输出中,我们看到了有关我们创建的三个 Droplet 的信息,例如它们的主机名、状态和 Droplet ID。 主机名和 ID 应该与您在访问 HAProxy 负载平衡器时看到的一致(通过 DOProxy 的公共 IP 地址)。

您可能已经注意到,DOProxy 仅打印有关它创建的液滴的信息。 这是因为它保留了它产生的液滴的清单。

现在查看 inventory 文件的内容:

cat inventory

您应该看到每个液滴的 ID,每行一个。 每次创建 Droplet 时,其 ID 都会存储在此清单文件中。

您可能已经猜到了,DOProxy 的 print 命令遍历清单文件中的液滴 ID,并执行 API 调用以检索每个液滴的信息。

应该注意的是,将服务器清单存储在单个文件中并不是最好的解决方案——它很容易被损坏或删除——但它展示了一个有效的简单实现。 分布式键值存储,例如 etcd,将是更好的解决方案。 您还希望在清单中保存的不仅仅是液滴 ID(因此您不必每次要查看某些液滴信息时都进行 API 调用)。

缩小(删除)

DOProxy 还有一个删除命令,可让您删除库存中的液滴。 删除命令要求您提供要删除的液滴的行号(如 print 命令所示)。

在运行此命令之前,您可能需要打印您的库存:

ruby doproxy.rb print

因此,例如,如果您想删除第三个水滴,您可以提供 2 作为行号:

ruby doprorxy.rb delete 2

片刻之后,您将看到确认消息:

Success: 4205675 deleted and removed from backend.

delete 命令通过 API 删除 droplet,将其从 HAProxy 配置中删除,并将其从清单中删除。 随意使用 DOProxy 打印命令或检查 DigitalOcean 控制面板来验证液滴是否已删除。 您还会注意到它不再是负载均衡器的一部分。

HAProxy 配置

我们没有讨论的最后一个 DOProxy 是 HAProxy 是如何配置的。

当您运行 createdelete DOProxy 命令时,将检索清单中每个液滴的信息,其中一些信息用于创建 HAProxy 配置文件。 特别是,Droplet ID 和私有 IP 地址用于将每个 Droplet 添加为后端服务器。

查看生成的 haproxy.cfg 文件的最后几行,如下所示:

tail haproxy.cfg

您应该看到如下内容:

 frontend www-http
       bind 104.236.236.43:80
       reqadd X-Forwarded-Proto:\ http
       default_backend www-backend

    backend www-backend

       server www-4202645 10.132.224.168:80 check # id:4202645, hostname:auto-nginx-0
       server www-4205587 10.132.228.224:80 check # id:4205587, hostname:auto-nginx-1

frontend 部分应包含您的 DOProxy 服务器的公共 IP 地址,而 backend 部分应包含引用创建的每个液滴的行。

注意: 此时,您可能需要删除使用 DOProxy 创建的其余 Droplet(ruby doproxy.rb delete 0 直到所有服务器都消失)。

现在您已经看到了 DOProxy 的缩放效果,让我们仔细看看代码。

DO代理代码

在本节中,我们将查看使 DOProxy 工作的相关文件和代码行。 了解 DOProxy 是如何实现的应该会让您了解如何使用 API 来管理和自动化您自己的服务器基础架构。

由于您将存储库克隆到服务器,因此您可以查看那里的文件,也可以查看 DOProxy 存储库 (https://github.com/thisismitch/doproxy) 中的文件。

重要文件:

  • doproxy.rb:DOProxy Ruby 脚本。 提供DOProxy背后的命令行界面和大脑
  • doproxy.yml:DOProxy 配置文件。 包含 API 令牌并指定液滴创建选项
  • haproxy.cfg.erb:HAProxy 配置模板。 用于生成具有适当后端服务器信息的负载均衡器配置
  • inventory:Droplet 库存文件。 存储已创建液滴的 ID
  • user-data.yml:用户数据文件。 一个 cloud-config 文件,在创建时将在新的 droplet 上运行

让我们首先深入了解配置文件。

多代理.yml

DOProxy 配置文件 doproxy.yml 中的重要行如下:

token: 878a490235d53e34b44369b8e78
ssh_key_ids:           # DigitalOcean ID for your SSH Key
  - 163420
...
droplet_options:
  hostname_prefix: auto-nginx
  region: nyc3
  size: 1gb
  image: ubuntu-14-04-x64

token 是您可以配置 读写 API 令牌的地方。

其他行指定 DOProxy 创建新液滴时将使用的选项。 例如,它将安装指定的 SSH 密钥(通过 ID 或指纹),并在主机名前加上“auto-nginx”。

有关有效液滴选项的更多信息,请查看 DigitalOcean API 文档

用户数据.yml

用户数据文件 user-data.yml 是 cloud-init 在创建时在每个新液滴上执行的文件。 这意味着您可以提供一个 cloud-config 文件或脚本来在每个新的 droplet 上安装您的应用程序软件。

示例 userdata 文件包含一个简单的 bash 脚本,用于在 Ubuntu 服务器上安装 Nginx,并将其默认配置文件替换为 droplet 主机名、ID 和公共 IP 地址:

#!/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 > /usr/share/nginx/html/index.html

通过 DigitalOcean 元数据服务检索液滴信息(主机名、ID 和 IP 地址)——这就是那些 curl 命令正在执行的操作。

显然,您会想做一些比这更有用的事情,例如安装和配置您的应用程序。 您可以使用它来自动将您的 Droplet 集成到您的整体基础架构中,方法是自动安装 SSH 密钥并连接到您的配置管理或监控工具。

要了解有关用户数据、云配置和元数据的更多信息,请查看以下链接:

haproxy.cfg.erb

HAProxy 配置模板 haproxy.cfg.erb 包含大部分负载均衡器配置,其中一些 Ruby 代码将替换为后端 Droplet 信息。

我们将只看生成后端配置的 Ruby 部分:

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 %>

此代码遍历清单中的每个液滴,并为每个液滴添加一个新的 HAProxy 后端(基于私有 IP 地址)。

例如,将为每个液滴生成这样的行:

server www-4202645 10.132.224.168:80 check # id:4202645, hostname:auto-nginx-0

每当创建或删除 droplet 时,DOProxy 都会生成一个新的 HAProxy 配置文件——您之前看到的 haproxy.cfg 文件。

多代理.rb

DOProxy Ruby 脚本 doproxy.rb 主要由一个 DOProxy 类组成,该类包含执行液滴创建和删除、库存管理和 HAProxy 配置生成的方法。

如果您了解 Ruby,请查看 GitHub 上的文件:https://github.com/thisismitch/doproxy/blob/master/doproxy.rb。

如果您不了解 Ruby,这里有一些解释每种方法的简化伪代码。 参考实际的 Ruby 代码可能很有用,以帮助您了解正在发生的事情。

定义初始化

每次 DOProxy 运行时执行,除非没有指定参数。

  1. 读取 doproxy.yml 配置文件(获取 API 令牌和 droplet 选项)。 2确定。

def get_inventory

检索清单文件中每个液滴的信息。 它必须在执行以下任何方法之前执行。

  1. 读取库存文件(包含液滴 ID)
  2. 对于每个液滴 ID,使用 API 检索液滴信息

def print_inventory

当使用“doproxy.rb print”命令时,将液滴信息打印到屏幕上。 它依赖于 get_inventory

  1. 对于清单中的每个 droplet,打印主机名、私有 IP 地址、状态和 ID(由 get_inventory 检索)

def create_server

使用“doproxy.rb create”命令时,创建一个新的Droplet并将其添加到库存文件中,然后调用reload_haproxy生成HAProxy配置并重新加载负载均衡器。

  1. 读取用户数据文件
  2. 使用 API 根据提供的用户数据和选项创建液滴
  3. 等待液滴状态变为“活动”——使用 API 每 15 秒检索一次液滴信息,直到状态发生变化
  4. 当状态为“活动”时,将液滴 ID 添加到库存文件
  5. 调用 reload_haproxy 生成 HAProxy 配置并重新加载负载均衡器

def delete_server(line_number)

使用“doproxy.rb delete”命令时,删除指定的Droplet并从库存文件中删除其ID,然后调用reload_haproxy生成HAProxy配置并重新加载负载均衡器。

  1. 从清单文件中删除指定行(删除液滴 ID)
  2. 使用 API 按 ID 删除 droplet
  3. 调用 reload_haproxy 生成 HAProxy 配置并重新加载负载均衡器

def generate_haproxy_cfg

这是一种支持方法,可根据清单中的液滴创建新的 HAProxy 配置文件。

  1. 打开HAProxy配置模板,【X41X】【X45X】
  2. 对于库存中的每个液滴,添加相应的后端服务器
  3. 将生成的 haproxy.cfg 文件写入磁盘

def reload_haproxy

这是一种将 HAProxy 配置文件复制到正确位置并重新加载 HAProxy 的支持方法。 这依赖于 generate_haproxy_cfg

  1. 将 HAProxy 配置文件 haproxy.cfg 复制到 HAProxy 将在重新加载时读取的位置
  2. 重新加载 HAProxy

这就是使 DOProxy 工作的所有重要代码。 我们将讨论的最后一件事是 DropletKit,我们在 DOProxy 中使用的 API 包装器。

DropletKit 宝石

DOProxy 使用 DropletKit gem,官方 DigitalOcean API v2 Ruby 包装器,进行 DigitalOcean API 调用。 DropletKit 允许我们轻松编写 Ruby 程序,这些程序可以执行以下操作:

  • 创建新的液滴
  • 删除现有的飞沫
  • 获取有关现有液滴的信息,例如状态、IP 地址、液滴 ID、区域等

本教程重点关注这些特定的 API 端点,但请记住,还有许多其他端点可以帮助您以编程方式管理您的 DigitalOcean 服务器基础架构。

结论

现在您已经了解了一个简单的脚本如何通过利用 DigitalOcean API、云配置和元数据来帮助扩展服务器环境,希望您可以应用这些概念来扩展您自己的服务器设置。 虽然 DOProxy 还没有准备好生产,但它应该为您提供一些实现自己的扩展解决方案的想法。

请记住,此处描述的使用 DOProxy 的缩放设置非常棒,但通过将其与监控系统结合使用可以大大改善它。 这将允许您根据某些条件(例如服务器资源利用率)自动向上和向下扩展应用程序服务器层。

有任何问题或意见吗? 随意在下面发布它们!