如何在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 存储库中的 Installation 和 Configuration(包括 doproxy config 和 Userdata)部分 在此服务器上安装 DOProxy。 按照说明中的说明,通过复制样本 doproxy.yml
和 user-data.yml
文件来使用它们。 一定要替换 DOproxy 配置文件中的 token
和 ssh_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 是如何配置的。
当您运行 create
或 delete
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 运行时执行,除非没有指定参数。
- 读取
doproxy.yml
配置文件(获取 API 令牌和 droplet 选项)。 2确定。
def get_inventory
检索清单文件中每个液滴的信息。 它必须在执行以下任何方法之前执行。
- 读取库存文件(包含液滴 ID)
- 对于每个液滴 ID,使用 API 检索液滴信息
def print_inventory
当使用“doproxy.rb print”命令时,将液滴信息打印到屏幕上。 它依赖于 get_inventory
。
- 对于清单中的每个 droplet,打印主机名、私有 IP 地址、状态和 ID(由
get_inventory
检索)
def create_server
使用“doproxy.rb create”命令时,创建一个新的Droplet并将其添加到库存文件中,然后调用reload_haproxy
生成HAProxy配置并重新加载负载均衡器。
- 读取用户数据文件
- 使用 API 根据提供的用户数据和选项创建液滴
- 等待液滴状态变为“活动”——使用 API 每 15 秒检索一次液滴信息,直到状态发生变化
- 当状态为“活动”时,将液滴 ID 添加到库存文件
- 调用
reload_haproxy
生成 HAProxy 配置并重新加载负载均衡器
def delete_server(line_number)
使用“doproxy.rb delete”命令时,删除指定的Droplet并从库存文件中删除其ID,然后调用reload_haproxy
生成HAProxy配置并重新加载负载均衡器。
- 从清单文件中删除指定行(删除液滴 ID)
- 使用 API 按 ID 删除 droplet
- 调用
reload_haproxy
生成 HAProxy 配置并重新加载负载均衡器
def generate_haproxy_cfg
这是一种支持方法,可根据清单中的液滴创建新的 HAProxy 配置文件。
- 打开HAProxy配置模板,【X41X】【X45X】
- 对于库存中的每个液滴,添加相应的后端服务器
- 将生成的
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 程序,这些程序可以执行以下操作:
- 创建新的液滴
- 删除现有的飞沫
- 获取有关现有液滴的信息,例如状态、IP 地址、液滴 ID、区域等
本教程重点关注这些特定的 API 端点,但请记住,还有许多其他端点可以帮助您以编程方式管理您的 DigitalOcean 服务器基础架构。
结论
现在您已经了解了一个简单的脚本如何通过利用 DigitalOcean API、云配置和元数据来帮助扩展服务器环境,希望您可以应用这些概念来扩展您自己的服务器设置。 虽然 DOProxy 还没有准备好生产,但它应该为您提供一些实现自己的扩展解决方案的想法。
请记住,此处描述的使用 DOProxy 的缩放设置非常棒,但通过将其与监控系统结合使用可以大大改善它。 这将允许您根据某些条件(例如服务器资源利用率)自动向上和向下扩展应用程序服务器层。
有任何问题或意见吗? 随意在下面发布它们!