如何在 Ubuntu 16.04 上使用 Rancher 部署 Node.js 和 MongoDB 应用程序

介绍

Rancher是一个开源,自我托管和完整的平台,可在生产中运行和轻松管理集装箱。

一些使Rancher成为一个有吸引力的解决方案的关键特征是:

*交叉-东道方联网 : 所有添加到Rancher的服务器都连接起来,允许容器之间的安全通信. *平衡损失 : 货物平衡服务包括在集装箱之间,甚至跨越多层云分配工作量。 *服务发现 :Rancher包括一个内部的DNS系统,能够按名称识别集装箱和服务,从而可以在网络上的其他服务中使用. 基础设施管理 : 有了Rancher,您可以添加、监视和管理来自任何云端提供者的计算资源。 *管弦乐引擎 :兰彻是唯一支持最受欢迎的集装箱管弦乐框架的集装箱管理平台,包括Catle, Swarm, Kubernetes,和Mesos. 所以,如果你已经有你的基础设施 与其中的一个框架工作, 那么,你可以轻松地使用朗彻。 *开放来源 :Rancher是自由、开放和透明的。 你绝对能控制你的基础设施 .

在本指南中,您将构建一个Rancher集群来部署负载均衡的 Node.js应用程序,并支持使用 MongoDB的数据存储。

在本教程结束时,您将有四个负载均衡的实例,一个简单的Node.js应用程序和一个MongoDB服务器,具有单独的数据容器,用于持久存储。

<美元 > [注] 注: 截至2022年12月15日,DigitalOcean不再通过控制面板或API支持创建新的RancherOS Droplets. 然而,任何在2022年12月15日之前创建的现有RancherOS Droplets,尽管祭品有变化,但还是会发挥作用. 此外,您还可以使用自定义图像旋转 RancherOS Droplets 。 通过遵循我们的产品文档来学习如何从自定义图像导入到 DigitalOcean. < $ > (美元)

前提条件

  • 1GB Ubuntu 16.04 Droplet并安装了Rancher。 我们用Rancher来创造另外6个Droplets,每个都有1GB的RAM. 遵循 Ubuntu 16.04 上的 [如何用 Rancher 和 Docker Machine 管理您的多节点部署] (https://andsky.com/tech/tutorials/how-to-manage-multi-node-deployments-with-rancher-and-docker-machine-on-ubuntu-16-04) 步骤1和2, 设置您与 Rancher 的初始 Droplet 。
  • 使用MongoDB进行数据存储的Node.js应用程序。 此教程提供了使用 [Hapi.js] (http://hapijs.com/ ) 库的简单示例, 如果您还没有准备好自己的应用程序的话。 您可以在 [这个 Github source] (https://github.com/do-community/hapi-example] 中找到这个示例应用程序,我们将在步骤一中详细探索.
  • 联合国 Git 安装在您的本地机上, 这样您就可以克隆示例应用程序 。 如果您需要满足这一先决条件, 请遵循 [官方 Git 安装文档] (https://git-scm.com/book/en/v2/Getting-Started-Installing-Git ) 。
  • Docker安装在您的本地机器上,这样你就可以构建我们将部署的应用程序图像. 您可以为此遵循正式文件
  • 联合国 在 [Docker Hub] (https://hub.docker.com/) 上的一个账户,这是Docker图像的免费和公开的注册. 这就是我们要托管我们的应用代码的地方 这样我们就可以使用Rancher 将其部署到多个主机上. 您需要您的多克枢纽用户名来完成此教程中的步骤 。
  • DigitalOcean Access Token,兼有读取和写取功能,通过访问应用程序和API页面可以生成. 复制此令牌, 因为您需要输入到 Rancher 以创建额外的主机 。 .

您还应该对 Docker 概念有基本知识,如容器,图像和 Dockerfiles。 请参阅 如何在 Ubuntu 16.04 上安装和使用 Docker有关使用 Docker 的更多信息。

第1步:探索 Node.js 应用程序

对于本教程,我们将使用基于Hapi.js框架的简单的Node.js应用程序,该应用程序接收消息,记录它,并列出之前提交的所有消息。

您将在本地开发机器上准备应用程序和Docker图像,而不是服务器。

使用以下命令将示例应用程序克隆到本地机器:

1git clone https://github.com/do-community/hapi-example

然后导航到项目目录:

1cd hapi-example

让我们看看应用程序的主要文件, server.js. 它包含了 MongoDB 连接和初始化服务器的代码. 在本地文本编辑器中打开此文件,你会看到以下内容:

 1[label server.js]
 2const Hapi = require('hapi');
 3const mongojs = require('mongojs');
 4
 5// Loads environment variables
 6// Used only in development
 7require('dotenv').config({silent: true});
 8
 9const server = new Hapi.Server();
10server.connection({ port: process.env.PORT || 3000 });
11
12// Connect with the database
13server.app.db = mongojs(process.env.MONGO_HOST + '/api');
14
15// Add the routes
16server.register(require('./routes'), (err) => {
17
18  if (err) {
19    console.error('Failed to load plugin:', err);
20  }
21
22  // Start the server
23  server.start((err) => {
24    if (err) {
25      throw err;
26    }
27
28    console.log('Server running at:', server.info.uri);
29  });
30});

路线的代码被封装为Hapi.js插件,以节省本教程中的空间,但如果你好奇,你可以看看文件routes.js

server.js文件的关键部分如下:

1[label server.js]
2require('dotenv').config({silent: true});

您可以查看在其 Github 存储库中对 .env 文件的文档,如果您感兴趣的环境变量是如何运作的。我们只将此文件中的变量保存为开发过程;这比手动在终端中写变量更容易。 在生产中,我们将通过 Rancher 从 Docker 获取变量。

接下来,我们设置服务器的端口,使用名为PORT的环境变量,如果变量未定义,则其倒退值为3000:

1[label server.js]
2server.connection({ port: process.env.PORT || 3000 });

该值在必要时可以更改;唯一的要求是它应该是(在)(http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml)。

最后,在加载路线并启动服务器之前,我们使用一个名为MONGO_HOST的环境变量连接到MongoDB服务器:

1[label server.js]
2server.app.db = mongojs(process.env.MONGO_HOST + '/api');

此环境值将通过Rancher定义为MongoDB服务器的主机名称,一旦我们创建MongoDB容器,值api是我们要连接的数据库的名称,如果它不存在,它将自动设置。

现在你已经了解了应用程序正在寻找什么,以及我们如何配置其端口和数据库连接的背景,让我们把Docker带到图片中。

步骤2 - 构建 Docker 图像

Rancher 使用 Docker 图像来部署应用程序到服务器上,所以让我们为我们的应用程序创建一个 Docker 图像。为了为我们的应用程序创建一个 Docker 图像,我们需要一个名为Dockerfile的文件,其中包含一系列步骤,Docker 会按照这些步骤来构建图像。这个文件已经包含在您克隆的应用程序存储库中。让我们看看其内容,以了解它如何工作。在文本编辑器中打开它,您将看到以下代码:

 1[label Dockerfile]
 2FROM node:6
 3MAINTAINER James Kolce <[email protected]>
 4
 5RUN mkdir -p /usr/api
 6COPY . /usr/api
 7WORKDIR /usr/api
 8RUN npm install --production
 9
10ENV PORT 3000
11EXPOSE  $PORT
12
13CMD ["npm", "start"]

让我们仔细看看每一个步骤,首先,我们看到这条线:

1[label Dockerfile]
2FROM node:6

此行声明,我们的图像是建立在Docker Hub的官方Node.js图像(https://hub.docker.com/_/node/)上面,我们正在选择Node.js的版本6,因为我们的应用程序只使用某些ES6功能,仅在该版本或更高版本中可用。

在这一行之后,我们创建了我们的工作目录:

1[label Dockerfile]
2RUN mkdir -p /usr/api
3COPY . /usr/api
4WORKDIR /usr/api

首先,我们运行mkdir命令创建一个名为/usr/api的新目录,这是我们的应用程序将生活的地方。-p旗帜意味着mkdir将根据需要创建中间目录。

下一行运行npm命令,并为我们的应用程序安装生产依赖。

1[label Dockerfile]
2RUN npm install --production

接下来,我们看到这两条线:

1[label Dockerfile]
2ENV PORT 3000
3EXPOSE  $PORT

第一行定义了一个名为PORT的环境变量,我们的应用程序将用于其倾听端口。如果这个变量没有被定义,我们将3000设置为默认值,然后我们将该端口曝光,以便我们可以从容器外部访问它。

Dockerfile 中的最后一步是通过发出npm start命令来运行 Node.js 服务器:

1[label Dockerfile]
2CMD ["npm", "start"]

要从此文件中创建我们的应用程序的Docker图像,请确保您位于您的终端中的hapi-example文件夹中,并执行以下命令:

1docker build -t your_dockerhub_username/hapi-example .

此命令使用我们的 Docker file 创建了 Docker 图像。 在命令末尾注意点. 它指定了当前文件夹中 Dockerfile的路径。 -t'旗为我们的形象设置了标签,我们将使用你的'-dockerhub_username/hapi-example'作为标签,这是我们适用于图像的标签,因此我们可以使用它从图像中创建容器实例。 我们使用多克枢纽用户名作为前缀,因为我们正准备在测试后发布此图像,多克枢纽图像的本地标记必须与多克枢纽上寄存器名称相匹配.

<$>[注] :如果您收到消息无法连接到Docker的Demon,Docker的Demon在这个主机上运行吗?当您运行此命令时,请确保Docker应用程序正在运行并启动Docker。

现在让我们测试我们刚刚构建的图像,以便我们可以确定一切都按预期运行。正如您之前所看到的那样,我们的应用程序依赖MongoDB,所以让我们创建一个MongoDB容器,我们的应用程序可以使用它来存储数据。

1docker run --name testdb -p 27017:27017 -d mongo:3

我们将给容器指定一个临时名称,并加上 " -- -- 名称 " 选项;在我们完成测试应用程序时,我们将使用这个名称阻止服务器。 我们还将东道港口 " 27017 " 与集装箱所暴露的港口相接,以便测试MongoDB正在使用我们的本地网页浏览器运行。 最后,我们具体说明我们想要使用的形象。 使用与应用程序开发时相同的MongoDB,以确保一切如所期望的那样运作,这是一个好主意,因此在此情况下,我们指定了"3"版本.

执行该命令后,请访问您的浏览器中的http://localhost:27017,您将看到消息:看起来你正在尝试通过HTTP访问MongoDB在原生驱动器端口,这意味着MongoDB正在运行。

现在运行您的应用程序容器并将其链接到MongoDB容器,运行此命令:

1docker run --name hapi-app -p 3000:3000 -d -e MONGO_HOST=testdb --link testdb your_dockerhub_username/hapi-example

这个命令类似于我们启动MongoDB容器的命令,但这次我们使用我们的应用图像(你的'dockerhub_username/hapi-example'),用容器所暴露的港口绘制我们主机的 " 3000 " 地图。 这是我们在创建 " Dockerfile " 时使用的同一港口。 此外,我们增加了一个称为MONGO-HOST ' 的环境变量,指定了我们MongoDB容器的名称,我们的应用程序将用来连接数据库服务器。 `-link testdb' 参数允许我们使用数据库容器的名称作为应用程序容器内的主机.

运行命令后,通过浏览器中访问http://localhost:3000来测试应用程序,它应该显示一个空页 没有任何错误

<$>[注] :当您访问http://localhost:3000时,您可能会在Firefox上看到空数组([ ]`)或JSON视图。

现在我们已经证明 Docker 图像在本地工作了,让我们停止并删除我们的本地容器。请记住,删除容器并不等于删除图像。

首先,使用您之前定义的数据库容器名称来停止数据库容器:

1docker stop testdb

现在容器已停止,您可以从您的机器中删除它,因为您将不再需要它:

1docker rm testdb

重复应用容器的相同步骤. 首先停止,然后删除。

1docker stop hapi-app && docker rm hapi-app

现在让我们发布工作图像,这样我们就可以与Rancher一起使用它。

步骤 3 — 将图像上传到 Docker Hub

要使用 Rancher 部署容器,我们需要访问一个 _Docker 注册表,在那里我们可以创建一个存储库来存储我们的 Docker 图像。我们将使用 Docker Hub 这是 Docker 的官方注册表。

使用您的用户名和密码登录到 Docker Hub. 登录后,点击屏幕右侧的 Create Repository 按钮。

*名称(需要) : 您的仓库名称,在这种情况下,它是`hapi-example'。 *Description :一个简短的描述,以在未来迅速识别出您的形象. *全面说明 : 您可以在此添加一个标记下文档作为您图像的参考, 但是由于我们的应用程序非常简单, 您可以让这个字段空出 。 *可视性 :你可以将你的相片设定为私人的,只有你才能接触到,或者作为公众的,每个人都可以使用你相片. 对于此教程, 创建一个公共寄存器 。 .

注意:如果您将存储库设置为私有,则必须在Rancher UI中的Infrastructure -> Registries页面中添加 Docker Hub 凭证。

填写所有所需字段后,点击创建按钮,完成此过程后,您将被重定向到您的新存储网站。

要上传您的 Docker 图像,您必须通过docker命令登录 Docker Hub。

1docker login

您将被要求输入您的用户名和密码,就像大多数CLI工具一样,您在输入时不会看到您的密码。

一旦登录,将图像上传到Docker Hub,使用以下命令将所有文件上传到存储库:

1docker push your_dockerhub_username/hapi-example

按下图像可能需要几分钟,取决于您的本地互联网连接,一旦图像成功发布,我们可以使用Rancher设置我们的主机。

步骤4 — 在Rancher中创建和标记主机服务器

让我们使用Rancher来创建我们需要部署我们的服务的所有主机. 我们需要两个用于Node.js应用程序,一个用于MongoDB服务器,一个用于负载平衡器。

在浏览器中访问您的Rancher界面,访问http://your_rancher_ip_address,并按照以下步骤创建我们需要的四个主机:

  1. 联合国 转到 基础设施 > 主机 并点击页面上方的** Add主机** 按钮.
  2. 选择数字海洋 为主机提供者。 3个 粘贴您生成的数字海洋应用程序托肯到 Access Token 字段,并点击 ** Next: 配置 Droplet** 。
  3. 指定一个名称。 输入主机,自动生成主机主机4的名称。 5 (韩语). 将 QQ 数量 滑动器移动到 4 ** 主机 。
  4. 国家 对于Image ,使用** Ubuntu 16.04.1 x64** 的默认值.
  5. 对于Size ,使用** 1克b内存的默认值,30克b 磁盘, 1 vCPU** .
  6. 联合国 您可以离开 SSH 用户 字段为** root ** 。
  7. 国家 点击 Create 按钮, 在服务器创建和添加到 Rancher 时再等几分钟. .

一旦Rancher完成所有主机的创建, 我们会在每一个主机上添加一个标签来分类它们的类型, 这样我们就可以组织我们把每个组件放在哪里。 标签主机也让我们能够根据服务器的类型进行大小调整. 例如,如果我们对我们的应用程序的需求过高,我们可以增加这种类型的服务器的数量,而兰彻将自动为我们部署合适的多克容器. 我们将创造的标签是: " 负载平衡器 " 、 " 应用 " 和 " 数据库 " .

让我们创建第一个标签,负荷平衡器

  1. 转到 基础设施 > 主机 ,然后选择第一个主机, host1。 2 点击** 选项** 按钮(页面顶部有三个垂直点的图标),然后选择** 编辑** 选项。 3 点击** + 添加标签** 按钮,在** 键入中输入类型,然后输入负载平衡器

注意:您的主机可能显示为host1.localdomain;这是一个正常的行为,并且可能取决于您的环境。

接下来,标记应用程序主机. 重复前两个主机的过程,但这次在 Value 输入中使用应用程序

对于最后一个主机,重复该过程,但在 Value 输入中使用数据库

现在所有四个主机都应该有标签,所以让我们设置服务,我们将从数据库开始。

第5步:部署MongoDB服务器

我们将在 Docker Hub 上使用官方的 MongoDB Docker 图像来部署我们的数据库服务器。 MongoDB 容器还将有一个 sidekick容器来存储我们所有的数据。

要做到这一点,请在 Rancher 用户界面中遵循以下步骤:

  1. 联合国 选择 Stacks 菜单,选择 ** User** 选项,然后单击** Define a Service** 按钮。
  2. 联合国 在Add Service 页中,确保将** 分级** 滑盘设置为** 径 1 容器** 。 3个 服务名称使用 " MongoDB " 。 4.四. 图像请输入mongo:3。 5 (韩语). 点击顶部的 Add Sidekick 容器 按钮。
  3. 国家 将这个新容器命名为数据。 这个容器将作为一卷来存储MongoDB数据.
  4. 联合国 由于我们只将这个容器用于数据,所以使用 " busybox " 图像。
  5. 联合国 在下面的Command 标签中,将** 自动启动** 选项改为** Never(Start Once)** ,因为我们只使用这个容器进行储存。
  6. 国家 切换到 Volumes 标签并点击 ** Add Volumes** 按钮添加出一卷. 将/dd/db输入显示的文字字段。 这是 MongoDB 存储数据的默认路径 。 10个 切换到Scheduling 标签,点击** Add Schedule Rules** 按钮并输入以下参数: "主机必须有一个类型=数据库的主机标签". 使用下拉来帮助您创建此规则 。 11个 点击MongoDB 服务标签,然后滚动到** Command** 标签,并确保将** 自动启动** 选项设置为** 永远** 。
  7. 切换到Volumes 标签,并在** Volumes** 选项中选择** Data** 。 13个 切换到 排程 标签, 并添加一个新的调度规则, 参数如下 : 主机必须有一个类型 = 数据库的主机标签 14个 最后,点击下方的Create 按钮,在服务启动时等待几分钟. .

现在,让我们配置应用服务。

第6步:部署 Node.js 应用程序

我们将使用类似的方法来部署我们之前准备的 Node.js 应用程序. 我们在 Docker Hub 上存储的图像将在标记为应用程序的主机上部署,并将链接到 MongoDB 服务来存储和访问数据。

  1. 联合国 选择 Stacks 菜单,选择 ** User** 选项,然后在 ** Default** 堆栈中单击** Add Service** 按钮。
  2. 联合国 在 比例 部分中,选择选项** 始终在每个主机上运行一个这样的容器实例** 。 3个 我们将使用NodeJS ' 这一服务的名称。 4.四. 对于图像,我们将使用 我们部署到多克枢纽。 输入您的 dockerhub_username/hapi-example 。 5 (韩语). 点击Service Links 按钮,选择** Destination Service** 并选择** MongoDB** . 然后选择** 作为名称** 并输入db',因此我们的NodeJS ' 服务可以使用这个名称访问MongoDB服务。
  3. 国家 在页下方的Command 标签中,单击** Add环境变量** 按钮,并添加一个名为MONGO-HOST'的变量,其值为db',该变量将图示到我们在前一步骤中使用的目的地服务名称。 记住我们的应用程序依赖于这个环境变量来定位数据库服务器.
  4. 联合国 切换到Scheduling 标签,点击** Add Schlearing Rules** 按钮并用滴放来构建一条规则,该规则写道:"主机必须有一个类型=应用程序的主机标签".
  5. 联合国 最后,点击Create 等待兰彻建立服务. .

在短时间内,你会看到新的NodeJS服务已经推出两个容器。选择基础设施菜单,点击主机,你会看到两个标记为应用程序的主机现在正在运行这个新服务。

第7步:部署负载平衡器

我们的负载平衡器将连接到我们的NodeJS服务,以平衡应用程序主机的所有容器之间的工作负载。

  1. 联合国 要创建负载平衡器,请选择Stacks 菜单并选择** User** 选项. 本次单击** Add Service ** 按钮旁边的箭头, 从下拉列表中选择** Add 载入平衡器 ** 。
  2. 联合国 ,请输入LoadBalancer'。 3个 在**港口规则** 节中,将** 请求主港** (第一个港场)设为80';将** 目标港** (第二个)设为3000',这是我国NodeJS'集装箱所暴露的港口。 4.四. 在目标服务 选项中选择** NodeJS** ,这是我们最近创建的服务. 5 (韩语). 在页面下方的Scheduling 标签中,点击** Add Schlearing Rules** 按钮并创建一条规则,该规则称:"主机必须有一个类型=负载平衡器的主机标签".
  3. 国家 最后,点击Create 并在Rancher激活服务时等待. .

每次我们创建一个服务,我们都使用我们创建的标签来确定该服务是如何部署的。

第8步:测试应用程序

要测试我们的应用程序,我们需要获取负荷平衡器主机的地址. 选择 LoadBalancer 服务,您将在** Port** 卡中看到IP地址。

要测试我们的应用程序是否工作,请在终端中执行以下命令:

1curl your_load_balancer_ip

此命令将向服务器发送 GET 请求,您将看到包含空数组([])的响应,因为我们的数据库是空的。

执行以下命令,将消息添加到数据库中,并确保应用程序可以保存数据:

1curl -i -X POST -H "Content-Type:application/json" your_load_balancer_ip -d '{"message":"This is a test"}'

此命令会向服务器发送一个 POST 请求,其中包含一个消息密钥,其值为这是一个测试。发送请求后,您应该收到您作为响应发送的相同消息,以及来自 MongoDB 的_id

<$>[注]本应用程序只会接受一个消息密钥,任何其他名称都将被丢弃。

现在,要双重检查应用程序是否正常工作,请再次执行第一个命令,您应该收到您在上一步中添加的消息。

1curl your_load_balancer_ip

结果将是这样的:

1HTTP/1.1 200 OK
2content-type: application/json; charset=utf-8
3cache-control: no-cache
4content-length: 61
5Date: Wed, 05 Jan 2017 20:07:02 GMT
6Connection: keep-alive
7
8{"message":"This is a test","_id":"e64d85579aee7d1000b075a2"}

<$>[警告] 警告 :此示例应用程序不安全;任何知道地址和API的人都可以将消息添加到系统中。

此时,您已经配置了两个应用服务器、一个数据库和一个负载平衡器,并准备好使用,让我们看看如何扩展我们的服务以处理更多流量。

第9步:扩展 Node.js 服务器

當您的應用程式開始受到大量需求,而您的伺服器無法處理負載時,您可以增加 Node.js 伺服器的數量,負載將自動在應用程式主機的容器之間分配。

  1. 联合国 转到基础设施 > 主机 页面并点击** Add主机** 按钮.
  2. 联合国 在同名领域添加您的 DigitalOcean Access Token . 3个 使用 " host5 " 作为第一个新主机的名称,因为我们创建的最后一个主机是 " host4 " 。 因为我们将创建两个新的主机,兰彻将自动将下一个主机命名为"主机6". 4.四. 选择您想要的数量; 在这种情况下, 我们将添加 2 更多的主机 。 5 (韩语). 对于Image ,使用** Ubuntu 16.04.1 x64** 的默认值.
  3. 国家 对于Size ,使用** 1gb RAM,30gb的默认值. 磁盘, 1 vCPU** .
  4. 联合国 单击Add标签 按钮,并在** Key** 输入中输入类型,然后在** Value** 输入中输入应用程序
  5. 联合国 点击 Create 按钮, 在新主机启动并添加到 Rancher 时等待 。 .

在新主机在线后,因为它们被标记为应用程序主机,将自动配置和部署NodeJS应用程序的新实例,负载平衡器将在四个主机之间分配工作负载。

结论

在本教程中,您了解了如何准备,部署和扩展功能性Node.js应用程序,支持MongoDB的数据存储,正如您所看到的,随着Rancher及其GUI的过程非常直观,并且很容易扩展完整的应用程序。

Published At
Categories with 技术
comments powered by Disqus