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

Rancher是一个开源,自托管和完整的平台,可以在生产环境中运行和轻松管理容器。作为一个Docker镜像本身,一个Rancher服务器可以在任何有Docker可用的Linux主机上工作。一些关键功能...

介绍

Rancher是一个开源的,自托管,以及完整平台运行,并很容易地在生产管理的容器中。作为一个Docker镜像本身,一个Rancher服务器可以在任何有Docker可用的Linux主机上工作。 使Rancher成为一个有吸引力的解决方案的一些关键功能是:
  • 跨主机网络 :加入Rancher的所有服务器都挂允许容器之间的安全通信。
  • 负载均衡 :包括负载平衡服务分配容器之间甚至可以跨越多个云的工作负载。
  • 服务发现 :高的农场包括一个内部的DNS系统,使容器和服务名称标识,这样他们可以其他服务中的网络上使用。
  • 基础设施管理 :随着Rancher可以添加,监控,并从任何云供应商管理的计算资源。
  • 编排引擎 :Rancher是唯一的容器管理平台,支持最流行的容器业务流程框架,包括牛,群,Kubernetes和Mesos。所以如果你已经有你的基础设施工作与这些框架之一,那么你将能够使用Rancher轻松。
  • 开源 :Rancher是免费的,开放的,透明的。你对你的基础设施有绝对的控制。
在本指南中,你将建立一个Rancher集群部署负载平衡的Node.js应用程序,并为使用数据存储支持MongoDB 。 在本教程的最后,您将有一个简单的Node.js应用程序和MongoDB服务器的四个负载平衡实例,并具有用于持久存储的单独数据容器。

先决条件

  • 一个1GB Ubuntu 16.04 Droplet与Rancher安装。 我们将使用Rancher创建6个额外的Droplet,每个都有1GB的RAM。 按照第1步和2 如何管理您的Rancher与Docker和机多节点部署在Ubuntu 16.04来设置与Rancher初始滴。
  • 使用MongoDB进行数据存储的Node.js应用程序。本教程提供了使用一个简单的例子Hapi.js库您可以在使用的情况下,你没有自己的应用程序还没有准备好。 你可以找到在这个例子中应用这个Github上库 ,我们将在第1步探究它的细节。
  • Git安装在本地机器上,因此可以克隆示例应用程序。按照官方的Git安装文档 ,如果你需要实现这一先决条件。
  • Docker安装在本地机器上,因此您可以构建我们将部署的应用程序映像。您可以按照官方文档这一点。
  • 在帐户Docker集线器 ,这是Docker图像的自由和公共注册。这是我们将要托管我们的应用程序代码,所以我们可以使用Rancher部署到多个主机。您需要使用Docker Hub用户名才能完成本教程中的步骤。
  • 一个DigitalOcean访问令牌既读取和写入权限,您可以通过访问生成的应用程序和API页面。复制此标记,因为您需要在Rancher中输入此标记才能创建其他主机。
你也应该有基本知识Docker窗的概念像容器,图像和Dockerfiles。 请参阅如何安装和在Ubuntu 16.04使用Docker窗更多有关使用Docker窗。

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

对于本教程,我们将使用一个基于Hapi.js框架的简单Node.js应用程序,该框架接收消息,记录消息并列出先前提交的所有消息。让我们来探讨应用程序的工作原理以及它如何接收配置值,这样我们可以在创建图像时使用Docker设置这些值。 您将在本地开发机器上准备应用程序和Docker映像,而不是服务器。 使用以下命令将示例应用程序克隆到本地计算机:
git clone https://github.com/do-community/hapi-example
然后导航到项目目录:
cd hapi-example
让我们看一下应用程序的主文件, server.js 。它包含MongoDB连接和初始化服务器的代码。在本地文本编辑器中打开此文件,您将看到以下内容:
server.js
const Hapi = require('hapi');
const mongojs = require('mongojs');

// Loads environment variables
// Used only in development
require('dotenv').config({silent: true});

const server = new Hapi.Server();
server.connection({ port: process.env.PORT || 3000 });

// Connect with the database
server.app.db = mongojs(process.env.MONGO_HOST + '/api');

// Add the routes
server.register(require('./routes'), (err) => {

  if (err) {
    console.error('Failed to load plugin:', err);
  }

  // Start the server
  server.start((err) => {
    if (err) {
      throw err;
    }

    console.log('Server running at:', server.info.uri);
  });
});
该航线的代码封装为Hapi.js插件,以节省空间在本教程中,但如果你很好奇,你可以查看文件routes.js 。 的的关键部分server.js的文件,如下所示:
服务器
require('dotenv').config({silent: true});
本品采用dotenv Node.js的包从加载我们的环境变量.env文件。 您可以查看该文档dotenv包在Github上库 ,如果你感兴趣的工作方式。我们将变量保存在此文件中仅用于开发过程;它比在终端中手动写变量容易。在生产中,我们将通过Rancher从Docker获取变量。 接下来我们设置的端口服务器,使用称为一个环境变量PORT ,与回退值3000 ,如果变量没有定义:
server.js
server.connection({ port: process.env.PORT || 3000 });
端口3000是Node.js的应用程序的通用惯例。 如果需要,可以更改此值; 唯一的要求是,它应当是高于1023和下面65535 。 最后,加载路线和启动服务器之前,我们连接到MongoDB的服务器,使用称为环境变量MONGO_HOST
server.js
server.app.db = mongojs(process.env.MONGO_HOST + '/api');
当我们创建MongoDB容器时,这个环境值将通过Rancher与MongoDB服务器的主机名一起定义。价值api是我们要连接到数据库的名称,它会自动设置,如果它不存在。 现在,你有一些应用程序正在寻找什么,以及我们如何配置其端口和数据库连接的背景,让我们把Docker带入图片。

第2步 - 构建Docker镜像

Rancher使用Docker镜像将应用程序部署到服务器,所以让我们为我们的应用程序创建一个Docker镜像。为了建设一个Docker映像我们的应用程序,我们需要一个名为Dockerfile其中包含了一系列构建图像时Docker窗将遵循的步骤。此文件已包含在您克隆的应用程序存储库中。让我们来看看它的内容,以了解它是如何工作的。在文本编辑器中打开它,您会看到以下代码:
Dockerfile
FROM node:6
MAINTAINER James Kolce <contact@jameskolce.com>

RUN mkdir -p /usr/api
COPY . /usr/api
WORKDIR /usr/api
RUN npm install --production

ENV PORT 3000
EXPOSE  $PORT

CMD ["npm", "start"]
让我们详细了解每一步。首先,我们看到这行:
Dockerfile
FROM node:6
该行宣布,我们的形象是建立在之上官方Node.js的图像从Docker窗枢纽,因为我们的应用程序会利用某些功能ES6仅在该版本或更高版本中提供我们所选择的Node.js的第6版。 我们推荐的做法是选择一个特定的版本,而不是这样你避免可能破坏你的应用程序的任何变化只是用最新的生产。 之后,我们设置了我们的工作目录:
Dockerfile
RUN mkdir -p /usr/api
COPY . /usr/api
WORKDIR /usr/api
首先,我们运行mkdir命令来创建一个名为新目录/usr/api ,这也正是我们的应用程序将生活。 该-p标志意味着mkdir将根据需要创建中间目录。然后我们将图像的内容复制到该目录。然后我们将这个新目录设置为我们的工作目录,以便从该目录运行后续命令。 下一行运行npm命令和安装的生产依赖于我们的应用程序。
Dockerfile
RUN npm install --production
接下来,我们看到这两行:
Dockerfile
ENV PORT 3000
EXPOSE  $PORT
第一行定义称为一个环境变量PORT我们的应用程序将用于其监听端口。 万一这个变量没有定义,我们设置3000为默认值。然后我们公开该端口,所以我们可以从容器外部访问它。使用环境变量使得更容易改变,而不必重写我们的应用程序代码。并记住,我们的应用程序设计为使用这些环境变量。 在我们的Dockerfile的最后一步通过发出运行我们的Node.js服务器npm start命令:
Dockerfile
CMD ["npm", "start"]
要创建我们从这个文件的应用程序的Docker形象,确保你是在hapi-example在终端文件夹,并执行以下命令:
docker build -t your_dockerhub_username/hapi-example .
该命令使用我们的Docker,图像Dockerfile 。 注意命令结尾处的点。 此指定的路径Dockerfile ,这是在当前文件夹。 该-t标志设置一个标记为我们的形象,我们将使用your_dockerhub_username / hapi-example为标记,这是我们应用到图像,所以我们可以用它来从图像中创建容器实例的标签。我们使用Docker Hub用户名作为前缀,因为我们准备在测试它时发布这个镜像,Docker镜像的本地标签必须与Docker Hub上的版本库名称相匹配。 :如果您收到消息Cannot connect to the Docker daemon. Is the docker daemon running on this host?Cannot connect to the Docker daemon. Is the docker daemon running on this host?当您运行此命令时,确保Docker应用程序正在运行,并且Docker已启动。然后再次运行该命令。 现在让我们测试我们刚刚构建的图像,这样我们就可以确保一切正常工作。如前所述,我们的应用程序依赖于MongoDB,所以让我们创建一个MongoDB容器,我们的应用程序可以使用它来存储数据。运行以下命令以基于官方MongoDB Docker镜像创建和启动MongoDB容器:
docker run --name testdb -p 27017:27017 -d mongo:3
我们分配一个临时名称与容器--name选项; 当我们完成测试应用程序时,我们将使用该名称停止服务器。 我们还结合主机端口27017由容器露出的端口,所以我们可以测试的MongoDB通过使用我们的本地Web浏览器中运行。 最后,我们指定我们要使用的图像。 这是一个好主意,使用MongoDB的相同版本的应用程序与开发,以确保一切正常,所以在这种情况下,我们指定的版本3 。 执行该命令后,参观http://localhost:27017在您的浏览器,你会看到以下消息: It looks like you are trying to access MongoDB over HTTP on the native driver port ,这意味着MongoDB的运行。 现在运行应用程序容器并通过运行以下命令将其链接到MongoDB容器:
docker run --name hapi-app -p 3000:3000 -d -e MONGO_HOST=testdb --link testdb your_dockerhub_username/hapi-example
此命令是类似于我们用来启动MongoDB的容器中的命令,但这次我们使用我们的应用程序图像( your_dockerhub_username / hapi-example )和映射端口3000我们的主机与容器暴露的端口。 这是当我们创建了我们使用相同的端口Dockerfile 。 此外,我们添加称为环境变量MONGO_HOST指定我们MongoDB的容器,这将我们的应用程序被用于连接到数据库服务器的名称。 该--link testdb参数让我们使用的数据库容器的名称为我们的应用程序的容器内的主机。 运行该命令后,通过访问测试应用程序http://localhost:3000在浏览器中。 它应该显示一个空白页没有任何错误注意 :您可能还会看到一个空数组( [ ]或JSON视图在Firefox当您访问http://localhost:3000 。这两种结果都是好的。 现在我们已经证明Docker映像在本地工作了,让我们停止并删除我们的本地容器。请记住,删除容器与删除图像不同。我们的形象将保持不变,所以我们可以稍后重新创建容器,或者将图像推送到Rancher,这是我们在清理我们的本地环境后要做的。 首先,使用您之前定义的名称停止数据库容器:
docker stop testdb
现在容器已停止,您可以从您的计算机中删除它,因为您不再需要它了:
docker rm testdb
对应用程序容器重复相同的步骤。首先停止它,然后删除它。
docker stop hapi-app && docker rm hapi-app
现在让我们发布工作映像,所以我们可以使用它与Rancher。

第3步 - 将映像上传到Docker Hub

要部署使用Rancher的容器,我们需要访问注册表Docker窗 ,在这里我们可以创建一个存储库来存储我们的Docker的形象。 我们将使用Docker Hub这是Docker的正式注册。 Docker Hub可以免费用于公共存储库。 使用您的用户名和密码登录Docker Hub。登录后,点击屏幕右侧的创建存储库按钮。填写字段如下:
  • 名称(必填):您的存储库的名称,在这种情况下,这是hapi-example
  • 说明 :一个简短的说明在未来的快速识别你的形象。
  • 完整说明 :你可以在这里添加减价文件作为图像的参考,但由于我们的应用程序是非常简单的,你可以离开这个字段为空。
  • 可见性 :您可以将您的图像作为私人在这里只有你将有机会获得它,或者作为公众,每个人都可以使用你的形象。对于本教程,请创建公共存储库。
:如果您设置的存储库作为私人的,你将不得不添加Docker Hub凭证的基础设施-在RancherUI>登记处网页。 在所有的必填字段填写,点击创建按钮。当过程完成后,您将被重定向到您的新存储库网站。 为了上传Docker形象,必须通过登录到Docker Hubdocker命令。回到您的终端,执行以下命令:
docker login
系统将提示您输入用户名和密码。像大多数CLI工具一样,在输入密码时,您将看不到密码。 登录后,使用以下命令将映像上传到Docker Hub,该命令将所有文件上传到存储库:
docker push your_dockerhub_username/hapi-example
根据您当地的互联网连接,推送图片可能需要几分钟。一旦图像成功发布,我们可以使用Rancher设置我们的主机。

第4步 - 在Rancher中创建和标记主机服务器

让我们使用Rancher来创建我们需要部署我们的服务的所有主机。我们需要两个Node.js应用程序,一个用于MongoDB服务器,一个用于负载均衡器。我们将使用DigitalOcean的API在Rancher UI中完成所有这些工作。 通过访问访问您的Rancher界面在浏览器中http:// your_rancher_ip_address ,并按照下列步骤来创建我们需要的四台主机:
  1. 转到基础设施>主机 ,然后单击添加主机按钮,在页面的顶部。
  2. 选择DigitalOcean作为主机提供商。
  3. 粘贴到你的访问令牌场产生的DigitalOcean应用程序令牌,然后单击Next:配置滴
  4. 分配名称。输入host ,它会自动生成名称host1host4
  5. 移动滑块数量 4台主机。
  6. 对于图像 ,使用Ubuntu 16.04.1 64的默认值。
  7. 对于大小 ,使用1GB内存,30GB硬盘,1个vCPU的默认值。
  8. 您可以将SSH用户字段作为
  9. 点击创建按钮,稍等几分钟,而被创建并添加到Rancher的服务器。
当Rancher完成创建所有主机后,我们将为每个主机添加一个标签,以便对其类型进行分类,以便我们可以组织要放置每个组件的位置。标签主机还可以让我们根据服务器的类型来扩展服务器。例如,如果我们对应用程序的需求太多,我们可以增加该类型的服务器数量,Rancher会自动为我们部署适当的Docker容器。我们要创建的标签是: loadbalancerapplicationdatabase 。 让我们创建的第一个标签, loadbalancer
  1. 转到基础设施>主机和选择第一个主机, host1
  2. 点击选项按钮(在页面顶部的三个垂直点的图标),并选择Edit选项。
  3. 点击+添加标签按钮,并在输入输入单词type ,然后输入loadbalancer输入。
  4. 单击保存按钮。
注意 :您主机可能出现host1.localdomain ;这是正常的行为,它可以根据您的环境而改变。 接下来,标记应用程序主机。重复前面的过程中连下两主机,但这次使用application中的输入。 对于最后一台主机,再重复上述过程,但使用database中的输入。 所有四个主机现在都应该有标签,所以让我们设置服务。我们将从数据库开始。

第5步 - 部署MongoDB服务器

我们将使用Docker Hub上的官方MongoDB Docker镜像部署我们的数据库服务器。 MongoDB的容器也将有一个搭档的容器来存储所有的数据。 两个容器将被部署标记为在主机上database 。 为此,请按照Rancher用户界面中的以下步骤操作:
  1. 选择堆叠菜单中,选择用户选项,然后单击定义服务按钮。
  2. 添加服务页面,确保缩放滑块设置为运行1个容器
  3. 对于服务的名称,使用MongoDB
  4. 对于图像,输入mongo:3
  5. 点击顶部的添加Sidekick的容器按钮。
  6. 命名此新容器Data 。此容器将用作存储MongoDB数据的卷。
  7. 由于我们将只使用这个容器的数据,使用busybox形象。
  8. 在下面的命令选项卡,切换自动重启选项从不(一旦开始),因为我们将使用这个容器仅用于存储。
  9. 切换到选项卡,并单击添加音量按钮添加一个新卷。 输入/data/db在出现的文本字段。这是MongoDB存储数据的默认路径。
  10. 切换到计划选项卡,单击添加计划规则按钮,并输入以下参数: The Host must have a host label of type = database 。使用下拉列表帮助您创建此规则。
  11. 点击MongoDB的服务选项卡,然后向下滚动到命令选项卡,并确保自动重启选项设置为始终
  12. 切换到选项卡,并在卷从选项选择数据
  13. 切换到计划选项卡,并添加一个新的调度规则具有下列参数: The Host must have a host label of type = database
  14. 最后,点击创建按钮,在底部,等待几分钟,而该服务被激活。
现在让我们配置应用程序服务。

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

我们将使用类似的方法来部署我们之前准备的Node.js应用程序。我们存储在Docker Hub的图像将被部署在标有主机application ,并会链接到MongoDB的服务来存储和访问数据。所以,请按照Rancher用户界面中的以下步骤:
  1. 选择堆叠菜单中,选择用户选项,然后单击默认添加服务按钮。
  2. 刻度部分,选择该选项始终每台主机上运行这个容器的一个实例
  3. 我们要使用该服务的名称是NodeJS
  4. 对于映像,我们将使用我们部署到Docker Hub的映像。进入your_dockerhub_username / hapi-example
  5. 单击服务链接按钮,选择目的地服务和选择MongoDB的 。 然后选择作为名称,并输入db ,所以我们NodeJS服务可以访问使用该名称的MongoDB的服务。
  6. 在页面底部的命令选项卡,单击添加环境变量按钮,添加一个名为变量MONGO_HOST与价值db ,映射到我们在上一步中使用的目标服务名称。记住,我们的应用程序依赖这个环境变量来定位数据库服务器。
  7. 切换到计划选项卡,单击添加调度规则按钮,并使用下拉菜单来构造一个规则说The Host must have a host label of type = application
  8. 最后,点击创建并等待Rancher设立的服务。
在很短的时间,你会看到新NodeJS服务已经推出了两个容器。 选择基础设施菜单中,单击主机 ,你会看到标有这两台主机application正在运行的这项新服务。由于有多个,我们设置一个负载均衡器,所以我们可以有效地使用这两个主机。

第7步 - 部署负载平衡器

我们的负载平衡器将被链接到提供NodeJS服务于所有跨应用程序主机上的容器之间平衡工作负载。
  1. 要创建负载平衡器,选择菜单,并选择用户选项。 这一次单击箭头旁边添加服务按钮,然后从下拉列表中添加负载平衡器
  2. 对于名称 ,输入LoadBalancer
  3. 端口规则部分中, 请求主机端口 (第一端口字段)置为80 ,以及目标端口 (第二个),以3000这是我们的端口NodeJS容器暴露。
  4. 目标服务选项选择的NodeJS,这是我们最近创建的服务。
  5. 在页面底部的调度选项卡中单击调度添加规则按钮,创建一个规则说The Host must have a host label of type = loadbalancer
  6. 最后,点击创建并等待Rancher激活服务。
每次我们创建一个服务,我们都使用我们创建的标签来确定如何部署服务。这使得管理额外的主机在将来很容易。现在让我们确保一切正常。

第8步 - 测试应用程序

要测试我们的应用程序,我们需要获取负载均衡器主机的地址。选择负载平衡器服务,你会看到在端口选项卡的IP地址。 要测试我们的应用程序是否正常工作,请在终端中执行以下命令:
curl your_load_balancer_ip
此命令向服务器发送GET请求。你会看到一个包含空数组(响应[]因为我们的数据库是空的。 执行以下命令以将消息添加到数据库,并确保应用程序可以保存数据:
curl -i -X POST -H "Content-Type:application/json" your_load_balancer_ip -d '{"message":"This is a test"}'
这个命令发送POST请求与包含一个JSON对象的服务器message值的关键是一种考验 。 发送请求后,您会收到你发来的回应,与沿相同的消息_id从MongoDB的。这意味着与MongoDB服务器的连接正在工作,应用程序保存您的数据。 这个应用程序将只接受一个message键,任何其他名称将被丢弃。 现在,要仔细检查应用程序是否正常运行,请再次执行第一个命令,您应该会收到上一步中添加的消息。
curl your_load_balancer_ip
输出将如下所示:
HTTP/1.1 200 OK
content-type: application/json; charset=utf-8
cache-control: no-cache
content-length: 61
Date: Wed, 05 Jan 2017 20:07:02 GMT
Connection: keep-alive

{"message":"This is a test","_id":"e64d85579aee7d1000b075a2"}
警告 :此示例应用程序是不安全的;知道地址和API的任何人都可以向系统添加消息。完成本教程后,您可能需要通过删除Rancher中的服务来禁用此应用程序。 此时,您现在有两个应用程序服务器,一个数据库和一个配置好并可以使用的负载均衡器。让我们来看看如何扩展我们的服务以处理更多的流量。

第9步 - 缩放Node.js服务器

当应用程序开始获得大量需求并且您的服务器无法处理负载时,您可以增加Node.js服务器的数量,并且负载将在应用程序主机之间的容器之间自动分配。请按照以下步骤扩展应用程序:
  1. 进入基础设施>主机页面,点击添加主机按钮。
  2. 添加您的DigitalOcean 访问令牌同名的领域。
  3. 使用host5作为名称的第一个新的主机,因为我们创造了最后一台主机是host4 。 因为我们要创建两个新的主机,Rancher将自动命名到下一个host6
  4. 选择所需的数量;在这种情况下,我们将增加2个主机。
  5. 对于图像 ,使用Ubuntu 16.04.1 64的默认值。
  6. 对于大小 ,使用1GB内存,30GB硬盘,1个vCPU的默认值。
  7. 点击添加标签按钮,然后在键盘输入输入type ,然后输入application中的输入。
  8. 点击创建按钮,然后等待新的主机被激活并添加到Rancher。
新主机联机后,由于它们标记为应用程序的主机上,的新实例NodeJS应用程序将被配置和自动部署,负载均衡器将在四台主机分配四个容器之间的工作负载。

结论

在本教程中,您学习了如何准备,部署和扩展功能的Node.js应用程序,并支持使用MongoDB进行数据存储。正如你可以看到,与Rancher和它的GUI的过程是非常直观的,它很容易缩放一个完整的应用程序。感谢Rancher的调度功能,当你的应用程序击中了大时间,你将能够轻松处理负载。