如何在DigitalOcean Ubuntu 16.04 Droplets上自动扩展网络应用程序

简介

在本教程中,我们将演示如何利用DigitalOcean API,使用DOPROxy横向扩展服务器设置。DOPROxy是一个Ruby脚本,一旦配置完成,它就会提供一个命令行界面,用于向上或向下扩展HTTP应用服务器层。

DOProxy是专为本教程编写的,它提供了一种简单的方法,可通过使用DigitalOcean API创建和删除应用服务器Droplets,并管理它们在HAProxy负载平衡器中的成员资格。这种基本的扩展模式允许用户通过 HAProxy 服务器访问应用程序,而 HAProxy 服务器又会以负载平衡的方式将用户转发到后端应用程序服务器。

DOProxy 有三个主要功能:

  • 创建 Droplet 并将其添加到负载平衡器中
  • 删除 Droplet 并将其从负载平衡器中移除
  • 维护所创建 Droplet 的库存,直至其被删除

![DOProxy create](assets/apiv2/doproxy/doproxy_create.png)

<$>[注] 注: 本教程的主要目的是教授通过API以编程方式扩展DigitalOcean服务器架构所需的最基本概念。你不应在生产环境中运行DOProxy,因为它在设计时没有考虑到弹性,而且只执行非常基本的错误检查。尽管如此,熟悉这个脚本是开始学习通过DigitalOcean API进行水平扩展的好方法。 <$>

先决条件

本教程使用了以下技术,在继续学习之前,您可能需要了解一下:

由于 DOProxy 是用 Ruby 编写的,因此了解 Ruby 会对您有所帮助。要进一步熟悉 Ruby,可以阅读我们的[如何用 Ruby 编程]系列(https://www.digitalocean.com/community/tutorial_series/how-to-code-in-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 GitHub 仓库 README中的安装 和** 配置** (包括** doproxy config** 和** Userdata** )部分在该服务器上安装 DOProxy。请务必替换 DOproxy 配置文件中的 YOUR_DO_API_TOKENYOUR_SSH_KEY_FINGERPRINT 值,否则脚本将无法运行。

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

运行 DOProxy

root 的身份登录 DOProxy 服务器,进入克隆 DOProxy 的目录。

不带任何参数运行 DOProxy:

1ruby doproxy.rb

这将打印出可用的命令:

1[secondary_label Output]
2Commands:
3doproxy.rb print                   # Print backend Droplets in inventory file
4doproxy.rb create                  # Create a new backend Droplet and reload
5doproxy.rb delete <LINE_NUMBER>    # Delete a Droplet and reload
6doproxy.rb reload                  # Generate HAProxy config and reload HAProxy
7doproxy.rb generate                # Generate HAProxy config based on inventory

此时,DOProxy 尚未创建任何 Droplets。让我们创建一些,让我们的 HTTP 服务上线,并扩大规模。

扩大规模(创建)

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

1ruby doproxy.rb create

这需要一些时间才能返回提示(因为脚本会通过 API 创建一个新的 Droplet,并等待它启动)。我们将在学习伪代码时讨论如何调用 API。

脚本完成后,你应该会看到一条包含 Droplet ID 的成功信息:

1[secondary_label Output]
2Success: 4202645 created and added to backend.

建议您在提示返回后等待几分钟,然后再执行下一步操作,因为用户数据脚本可能尚未运行,因此 HAProxy 可能尚未开始传输流量。

准备好后,请在网页浏览器中访问您的 DOProxy 服务器的公共 IP 地址。您应该会看到一个页面,其中列出了新 Droplet 的_hostname_、id_和_public IP 地址

我们将使用 DOProxy 再创建两个 Droplets,总共三个。如果你愿意,也可以创建更多:

1ruby doproxy.rb create
2ruby doproxy.rb create

现在,再次通过网络浏览器访问 DOProxy 服务器的公共 IP 地址。如果刷新页面,您会发现页面上的信息会随着您创建的 Droplet 的循环而改变。这是因为它们都由 HAProxy 进行负载平衡,HAProxy 在使用 DOProxy 创建时将每个 Droplet 添加到其配置中。

如果你碰巧在DigitalOcean控制面板中查看,你会发现这些新的Droplets(与你的其他Droplets一起)将会在那里列出:

控制面板中的水滴](assets/apiv2/doproxy/control_panel_nginx_droplets.png)

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

打印库存

DOProxy 提供了一个 print 命令,可以打印出其库存中的所有 Droplet:

1ruby doproxy.rb print

你应该会看到类似这样的输出:

1[secondary_label Output]
20) auto-nginx-0  (pvt ip: 192.0.2.175, status: active, id: 4202645)
31) auto-nginx-1  (pvt ip: 192.0.2.176, status: active, id: 4205587)
42) auto-nginx-2  (pvt ip: 192.0.2.172, status: active, id: 4205675)

在示例输出中,我们可以看到关于我们创建的三个 Droplet 的信息,包括它们的主机名、状态和 Droplet ID。主机名和 ID 应与您访问 HAProxy 负载均衡器(通过 DOProxy 的公共 IP 地址)时在 Web 浏览器中看到的一致。

您可能已经注意到,DOProxy 只打印它创建的 Droplet 的信息。这是因为它维护着自己创建的 Droplet 清单。

现在查看 inventory 文件的内容:

1cat inventory

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

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

需要注意的是,将服务器清单存储在单个文件中并不是最好的解决方案--它很容易被损坏或删除--但它展示了一个可行的简单实现方法。分布式键值存储(如 etcd )将是更好的解决方案。您还希望在清单中保存更多信息,而不仅仅是 Droplet ID(这样您就不必在每次要查看某些 Droplet 信息时都调用 API)。

缩小(删除)

DOProxy 还有一个 delete 命令,可以让你删除库存中的 Droplet。删除 "命令要求提供要删除的 Droplet 的行号(如 "打印 "命令所显示)。

运行此命令前,您可能需要打印清单:

1ruby doproxy.rb print

因此,举例来说,如果要删除第三个 Droplet,就需要提供 2 作为行号:

1ruby doprorxy.rb delete 2

稍等片刻,您将看到确认信息:

1[secondary_label Output]
2Success: 4205675 deleted and removed from backend.

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

HAProxy 配置

我们尚未讨论的 DOProxy 的最后一个部分是如何配置 HAProxy。

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

像这样查看生成的 haproxy.cfg 文件的最后几行:

1tail haproxy.cfg

你应该看到这样的内容:

 1[label tail of haproxy.cfg]
 2    frontend www-http
 3       bind 203.0.113.43:80
 4       reqadd X-Forwarded-Proto:\ http
 5       default_backend www-backend
 6
 7    backend www-backend
 8
 9       server www-4202645 192.0.2.175:80 check # id:4202645, hostname:auto-nginx-0
10       server www-4205587 192.0.2.176:80 check # id:4205587, hostname:auto-nginx-1

前端 "部分应包含 DOProxy 服务器的公共 IP 地址,"后台 "部分应包含指向创建的每个 Droplet 的行。

<$>[注] 注意: 此时,您可能需要删除使用 DOProxy 创建的其他 Droplet(ruby doproxy.rb delete 0 直到所有服务器都删除为止)。 <$>

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

DOProxy 代码

在本节中,我们将了解 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 时将在其上运行的云配置文件

我们先来看看配置文件。

doproxy.yml

这些是 doproxy.yml 中的重要行:

 1[label doproxy.yml]
 2token: YOUR_DO_API_TOKEN
 3ssh_key_ids:
 4  - YOUR_SSH_KEY_FINGERPRINT
 5...
 6droplet_options:
 7  hostname_prefix: auto-nginx
 8  region: nyc3
 9  size: 1gb
10  image: ubuntu-16-04-x64

token "属性必须包含_read 和 write_ API 令牌。

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

关于有效的Droplet选项的更多信息,请参阅DigitalOcean API文档

user-data.yml

这是 Cloud-init 在创建每个新 Droplet 时要执行的文件。这意味着您可以提供云配置文件或脚本,在每个新的 Droplet 上安装应用软件。

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

1[label user-data.yml]
2#!/bin/bash
3
4apt-get -y update
5apt-get -y install nginx
6export DROPLET_ID=$(curl http://169.254.169.254/metadata/v1/id)
7export HOSTNAME=$(curl -s http://169.254.169.254/metadata/v1/hostname)
8export PUBLIC_IPV4=$(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address)
9echo Droplet: $HOSTNAME, ID: $DROPLET_ID, IP Address: $PUBLIC_IPV4 > /var/www/html/index.html

这些 "curl "命令正在使用DigitalOcean Metadata服务检索有关Droplet的信息(主机名、ID和IP地址)。

在生产实施中,该文件将包含安装和配置应用程序等命令。通过自动安装 SSH 密钥和连接到配置管理或监控工具等操作,您还可以使用它将 Droplet 自动集成到整体基础设施中。

要了解有关 userdata、cloud-config 和元数据的更多信息,请查看这些链接:

haproxy.cfg.erb

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

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

1[label haproxy.cfg.erb]
2backend www-backend
3   <% @Droplets.each_with_index do |droplet, index| %>
4   server www-<%= droplet.id %> <%= droplet.private_ip %>:80 check # id:<%= droplet.id %>, hostname:<%= droplet.name -%>
5   <% end %>

这段代码会遍历清单中的每个 Droplet,并为每个 Droplet 添加一个新的 HAProxy 后端条目(基于私有 IP 地址)。

例如,每个 Droplet 都会生成这样一行:

1[label haproxy.cfg]
2server www-4202645 192.0.2.175:80 check # id:4202645, hostname:auto-nginx-0

无论何时创建或删除 Droplet,DOProxy 都会生成一个新的 HAProxy 配置文件,其中包含更改内容。

doproxy.rb

这个 Ruby 脚本主要由一个 DOProxy 类组成,其中包含执行 Droplet 创建和删除、库存管理和 HAProxy 配置生成的方法。

如果你懂 Ruby,请查看 GitHub 上的文件:https://github.com/scanevari/doproxy/blob/master/doproxy.rb.

如果你不懂 Ruby,这里有一些简化的 "伪代码 "来解释每种方法。将这些代码与实际的 Ruby 代码进行比较,可能有助于理解发生了什么。

1def initialize

每次 DOProxy 运行时,在使用任何有效参数时都会执行:

  • 读取 doproxy.yml 配置文件,获取 API 令牌和 Droplet 选项。
1def get\_inventory

检索清单文件中每个 Droplet 的信息。必须在执行其他方法之前执行。

  • 读取库存文件(其中包含 Droplet ID)
  • 对于每个 Droplet ID,使用 API 检索 Droplet 信息
1def print\_inventory

该方法会打印清单文件中每个 Droplet ID 的 Droplet 信息。它与 doproxy.rb print 命令一起调用。

  • 为清单中的每个 Droplet 打印主机名、专用 IP 地址、状态和 ID
1def create\_server

通过 doproxy.rb create 命令调用时,该方法会创建一个新的 Droplet 并将其添加到清单文件中。然后,它会调用 reload_haproxy 重新生成 HAProxy 配置文件,并重新加载负载平衡器。

  • 读取用户数据文件
  • 使用 API 根据提供的用户数据和选项创建 Droplet
  • 等待 Droplet 状态变为 "激活"--使用 API 每 15 秒检索一次 Droplet 信息,直到状态发生变化
  • 当状态为 "激活 "时,将 Droplet ID 添加到库存文件中
  • 调用 reload_haproxy 重新生成 HAProxy 配置文件并重新加载负载平衡器
1def delete\_server(line\_number)

使用 doproxy.rb delete 命令时,该方法会删除指定的 Droplet,并从清单文件中删除其 ID。然后调用 reload_haproxy 重新生成 HAProxy 配置文件,并重新加载负载平衡器。

  • 从清单文件中删除指定行(删除 Droplet ID)
  • 使用 API 按其 ID 删除 Droplet
  • 调用 reload_haproxy 重新生成 HAProxy 配置文件并重新加载负载平衡器
1def generate\_haproxy\_cfg

这是一种支持方法,可根据库存中的 Droplet 创建新的 HAProxy 配置文件。

  • 打开 HAProxy 配置模板 (haproxy.cfg.erb)
  • 为库存中的每个 Droplet 添加相应的后端服务器条目
  • 将生成的 haproxy.cfg 文件写入磁盘
1def 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程序,以完成以下工作:

  • 创建新的 Droplets
  • 删除现有的 Droplet
  • 获取现有 Droplet 的信息,如状态、IP 地址、Droplet ID、地区等

本教程重点介绍了这些特定的API端点,但请记住,还有许多其他端点可以帮助您对DigitalOcean服务器基础设施进行编程式管理。

结论

现在,你已经看到了一个简单的脚本如何通过利用DigitalOcean API、云配置和元数据来帮助扩展服务器环境,你可以应用所有这些概念来扩展自己的服务器设置。虽然 DOProxy 并不打算用于生产,但它应该能为你实施自己的扩展解决方案提供一套不错的思路。

请记住,这里描述的使用 DOProxy 的扩展设置只是参考,但如果将其与我们的监控系统 结合使用,效果会大大改善。这样,您就可以根据某些条件(如服务器资源利用率)自动上下扩展应用服务器层。

Published At
Categories with 技术
comments powered by Disqus