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

简介

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

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

DOProxy 有三个主要功能:

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

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

注: 本教程的主要目的是传授通过API以编程方式扩展DigitalOcean服务器架构所需的基本概念。你不应在生产环境中运行当前形式的DOProxy,因为它在设计时并未考虑到弹性问题,其错误检查功能仅够凑合使用。尽管如此,如果你想通过API学习水平扩展,它不失为一个入门的好方法。

先决条件

本教程涉及多种技术,在继续学习之前,您可能需要了解这些技术,包括

由于DOProxy是用Ruby编写的,因此了解Ruby是一个优势,但不是必要条件;我们将提供伪代码来解释DOProxy代码的要点。此外,我们还将使用 DigitalOcean 官方的 Ruby 封装程序 DropletKit,这使我们能够在 Ruby 代码中轻松调用 API。

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

安装 DOProxy

首先,在 NYC3 区域创建一个 Ubuntu 14.04 主机(如果您在安装 DOProxy 后配置了 doproxy.yml 文件中的 region 变量,则可以使用任何支持 ** 私有网络** 和 ** 用户数据** 的区域)。这个 droplet 将运行 HAProxy 负载均衡器和 DOProxy 扩展脚本,因此请选择一个你认为足以满足所需扩展潜力的大小。由于本教程只是一个基本的扩展演示,不会收到任何实际流量,因此 1GB 大小可能就足够了。

我们将把这个 droplet 称为 _DOProxy 服务器。

接下来,登录并按照DOProxy GitHub 仓库中的安装 和** 配置** (包括** doproxy config** 和** Userdata** )部分在该服务器上安装 DOProxy。按照说明复制示例 doproxy.ymluser-data.yml 文件。请务必替换 DOproxy 配置文件中的 tokenssh_key_ids 值,否则脚本将无法运行。

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

运行 DOProxy

root 的身份登录 DOProxy 服务器,并更改到克隆 DOProxy 的目录(如果尚未更改)。

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

1ruby doproxy.rb

这样就可以打印出可用的命令:

1Commands:
2doproxy.rb print                   # Print backend droplets in inventory file
3doproxy.rb create                  # Create a new backend droplet and reload
4doproxy.rb delete <LINE_NUMBER>    # Delete a droplet and reload
5doproxy.rb reload                  # Generate HAProxy config and reload HAProxy
6doproxy.rb generate                # Generate HAProxy config based on inventory

目前,DOProxy 尚未创建任何液滴。让我们创建一些,让我们的 HTTP 服务上线并扩大规模。

扩大规模(创建)

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

1ruby doproxy.rb create

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

完成后,您应该会看到一条包含液滴 ID 的成功消息,就像这样:

1Success: 4202645 created and added to backend.

如果你在网络浏览器中访问 DOProxy 服务器的公共 IP 地址。你应该会看到一个页面,其中列出了新液滴的_hostname_、id_和_public IP address

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

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

现在,再次通过网络浏览器访问 DOProxy 服务器的公共 IP 地址。如果刷新页面,你会发现页面上的信息会发生变化--它会循环浏览你创建的液滴。这是因为 HAProxy 正在对它们进行负载平衡--每个液滴在创建时都会被添加到负载平衡器配置中。

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

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

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

打印库存

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

1ruby doproxy.rb print

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

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

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

您可能已经注意到,DOPROxy 只打印它创建的液滴的信息。这是因为它维护着自己创建的液滴的库存。

现在查看 inventory 文件的内容:

1cat inventory

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

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

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

缩小(删除)

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

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

1ruby doproxy.rb print

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

1ruby doprorxy.rb delete 2

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

1Success: 4205675 deleted and removed from backend.

删除命令通过应用程序接口删除液滴,将其从HAProxy配置中删除,并从清单中删除。你可以通过使用DOProxy打印命令或查看DigitalOcean控制面板来验证是否删除了该数据包。你还会发现,它不再是负载平衡器的一部分。

HAProxy 配置

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

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

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

1tail haproxy.cfg

你应该看到这样的内容:

1frontend www-http
2       bind 104.236.236.43:80
3       reqadd X-Forwarded-Proto:\ http
4       default_backend www-backend
5
6    backend www-backend
7
8       server www-4202645 10.132.224.168:80 check # id:4202645, hostname:auto-nginx-0
9       server www-4205587 10.132.228.224:80 check # id:4205587, hostname:auto-nginx-1

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

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

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

DOProxy 代码

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

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

重要文件:

doproxy.rb :DOProxy Ruby 脚本。提供命令行界面和 DOProxy 的大脑 doproxy.yml :DOProxy 配置文件。包含应用程序接口令牌,并指定了液滴创建选项 haproxy.cfg.erb :HAProxy 配置模板。用于生成包含适当后端服务器信息的负载平衡器配置 inventory :Droplet 清单文件。存储已创建的液滴的 ID user-data.yml :用户数据文件。创建新液滴时将在其上运行的云配置文件

我们先来看看配置文件。

doproxy.yml

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

1token: 878a490235d53e34b44369b8e78
2ssh_key_ids:           # DigitalOcean ID for your SSH Key
3  - 163420
4...
5droplet_options:
6  hostname_prefix: auto-nginx
7  region: nyc3
8  size: 1gb
9  image: ubuntu-14-04-x64

令牌 "用于配置_读取和写入 API 令牌。

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

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

user-data.yml

用户数据文件 "user-data.yml "是 Cloud-init 将在每个新液滴创建时执行的文件。这意味着您可以提供云配置文件或脚本,以便在每个新液滴上安装应用软件。

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

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

液滴信息(主机名、ID和IP地址)是通过DigitalOcean Metadata服务获取的--这就是 "curl "命令的作用。

显然,您希望做比这更有用的事情,比如安装和配置您的应用程序。通过自动安装 SSH 密钥和连接到配置管理或监控工具等操作,您可以使用它将您的小型机自动集成到您的整体基础设施中。

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

haproxy.cfg.erb

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

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

1backend www-backend
2   <% @droplets.each_with_index do |droplet, index| %>
3   server www-<%= droplet.id %> <%= droplet.private_ip %>:80 check # id:<%= droplet.id %>, hostname:<%= droplet.name -%>
4   <% end %>

这段代码会遍历库存中的每个液滴,并为每个液滴添加一个新的 HAProxy 后端(基于私有 IP 地址)。

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

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

每当创建或删除一个液滴时,DOProxy 都会生成一个新的 HAProxy 配置文件--也就是你之前看过的 "haproxy.cfg "文件。

doproxy.rb

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

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

如果您不了解 Ruby,这里有一些简化的伪代码,可以解释每种方法。将其与实际的 Ruby 代码对照可能会有所帮助,有助于理解发生了什么。

def initialize

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

1.读取 doproxy.yml 配置文件(获取 API 标记和 droplet 选项)。2 已验证。

def get_inventory

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

1.读取清单文件(其中包含液滴 ID) 2.对于每个液滴 ID,使用 API 获取液滴信息

def print_inventory

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

1.为清单中的每个液滴打印主机名、私有 IP 地址、状态和 ID(通过 get_inventory 获取)。

def create_server

当使用 "doproxy.rb create "命令时,会创建一个新的 droplet 并将其添加到清单文件中,然后调用 reload_haproxy 生成 HAProxy 配置并重新加载负载平衡器。

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

def delete_server(line_number)

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

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

def generate_haproxy_cfg

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

1.打开 HAProxy 配置模板,"haproxy.cfg.erb 2.为库存中的每个 droplet 添加一个相应的后端服务器 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 的扩展设置非常好,但如果与监控系统结合使用,效果会大大改善。这样就能根据某些条件(如服务器资源利用率)自动上下扩展应用服务器层。

有任何问题或意见?欢迎在下方留言!

Published At
Categories with 技术
comments powered by Disqus