使用Node.js、Express 4向Kubernetes集群部署RESTful APIs
在本教程中,我们将介绍如何使用Node.js Express框架构建RESTful API,使用docker-compose在本地进行测试。然后,我们将继续把这个应用程序部署到Kubernetes上。
简介
Express是一个建立在Node.js之上的后端开发框架,它能够实现客户端-服务器架构。凭借其灵活性,它允许定制API端点,从而满足我们的需求。
前提条件
要继续学习本教程,你需要以下条件。
- 在你的本地开发环境中下载并安装Node.js。
- Node.js的Express框架的基本知识。
- RESTful APIs设计。
- Docker方面的基本知识
- kubernetes的基本知识
目标
在本文结束时,你应该能够创建一个完整的动态Express应用程序,并使用Docker将其部署到云中。
Node.js应用程序的设置
让我们从导入所需的模块开始,并创建一个运行的服务器。
//this node application is located in the index.js file
const http = require("http");
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8000);
console.log('Server started at http://127.0.0.1:8000/');
现在通过在命令行上运行命令来执行这个应用程序。
node index.js
执行输出。
The server started at http://127.0.0.1:8000/
Express软件包设置
在你的server.js 脚本中添加以下内容。
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
// import the student schema defined in the student.js file
const Student = require('./models/student');
//register router middleware
const router = express.Router();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
const port = process.env.PORT || 8000;
const config = require('./config');
const mongoose = require('mongoose');
mongoose.connect(config.db[app.settings.env]);
在上面的脚本中,我们导入了Express包。此外,我们还导入了有助于运行我们的Express应用程序和设置与数据库的连接的包。
现在我们已经得到了与MongoDB数据库服务器的连接,让我们来定义我们将用于从学校数据库中获取学生名单的模型。
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const StudentSchema = new Schema({
student_id: String,
name: String,
registration_number: String,
course: String,
year_of_study: Number,
},
{
timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' }
});
module.exports = mongoose.model('Student', StudentSchema);
在上面的模型中,我们设置了我们将通过我们的API获得的学生详细信息。
RESTful APIs的实现
现在我们已经设置了我们的模型和服务器文件,在这一节中,让我们实现我们的RESTful APIs并将我们的应用程序部署到云端。
router.get('/students/:student_id', function(request, response) {
Student.findOne({student_id: request.params.student_id}, function(err, Student) {
if (err)
{
response.status(500);
response.setHeader('Content-Type', 'application/vnd.error+json');
response.json({ message: "An error occurred, unable to get student details"});
}
else if (Student == null)
{
response.status(404);
response.setHeader('Content-Type', 'application/vnd.error+json');
response.json({ message: "ProductQuantity not found for product_id "+request.params.student_id});
}
else
{
response.status(200);
response.setHeader('Content-Type', 'application/hal+json');
let student_resource = halson({
student_id: Student.student_id,
name: Student.name,
course: Student.course,
year: Student.year_of_study,
registration_number: Student.registration_number,
created_at: Student.created_at
}).addLink('self', '/students/'+Student.student_id)
//response
response.send(JSON.stringify(student_resource));
}
});
});
// let's now register our routes
app.use('/', router);
// now start the server on port 8000
app.listen(port);
console.log('Starting server on port ' + port);
Dockerizing the Express application
现在我们已经定义了我们的核心应用API逻辑,让我们进入本教程的主要目的,对你的RESTful Node.js Express应用进行停靠。
本节假设你已经在Ubuntu机器上启动并运行了Docker。
让我们继续并定义Dockerfile 的内容,以指导docker如何为我们的Express应用程序建立一个容器镜像。
# the base image from which the app is built upon
FROM node: latest
# Runs the mkdire command to create /usr/src/app inside docker container
RUN mkdir -p /usr/src/app
# Sets the work directory to /usr/src/app
WORKDIR /usr/src/app
# Copies the contents of the current directory into the working directory inside the # docker container
COPY . /usr/src/app
# Exposes port 8000 outside the docker container
EXPOSE 8000
# Runs the npm install command to install dependencies
RUN npm install
# Provides the command required to run the application
CMD ["npm", "start"]
这个Dockerfile ,在我们的RESTful应用程序中使用npm来安装模块。现在让我们继续,并设置docker-compose配置文件,我们将使用该文件来启动Node.js Express应用程序(包括MongoDB实例)。
-------------------------
# Service name
student:
# build in the current directory
build: .
# command to run the app
command: npm start
# Maps port 8000 inside docker container to port 8000 outside docker container
ports:
- "8000:8000"
# linking the student to mongodb container
links:
- mongodb
# env variables
environment:
- NODE_ENV=production
- MONGODB_ADDRESS=mongodb
# mongodb service
mongodb:
# pulling mongodb image
image: mongo
设置YAML服务以部署Docker化的Node.js Express应用程序
现在我们已经在本地对应用程序进行了docker化,下一步就是将应用程序部署到云端。
让我们继续,设置服务来部署应用程序,如下所示
//service.yaml file
-----------------------------
services:
inventory:
git_url: git@github.com:myexample.git
git_branch: main
command: npm start
build_root: .
ports:
- container: 8000
http: 80
https: 443
env_vars:
NODE_ENV: production
databases:
- mongodb
注意,确保你在上述服务中改变你的git URL。
现在你可以登录到你喜欢的云计算供应商,部署你的docker化应用程序。
现在我们有一个Docker容器镜像,我们需要创建一个部署文件。在根目录下,创建一个名为deployment.yaml 的新文件。这个文件将把应用程序部署到Kubernetes引擎上。
在该文件中添加以下片段。
apiVersion: v1
kind: Service
metadata:
name: rest-test-service
spec:
selector:
app: rest-test-app
ports:
- protocol: "TCP"
port: 3000
targetPort: 8000
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: rest-test-app
spec:
selector:
matchLabels:
app: rest-test-app
replicas: 5
template:
metadata:
labels:
app: rest-test-app
spec:
containers:
- name: rest-test-app
image: rest-test-app
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8000
该文件有两部分。
-
Service- 该服务充当负载平衡器。负载平衡器用于将请求分配到各种可用的服务器上。 -
Deployment将充当预定的应用程序。用户请求击中了负载均衡器,然后负载均衡器通过创建 文件中定义的副本数量来分配请求。例如,在我们的案例中,我们有5个副本,以实现可扩展性,这意味着我们将有5个实例在同一时间运行。deployment.yaml
多个副本的好处是,如果一个实例崩溃了,其他应用实例会继续运行。
deployment.yaml 文件与之前创建的Docker镜像相连接,因此为了将应用程序部署到Kubernetes集群,我们使用Docker镜像。当我们部署应用程序时,该镜像将自动为应用程序创建容器。
部署到Kubernetes服务
我们已经将我们的RESTful应用程序docker化,现在我们需要将其部署到Kubernetes引擎。
在你的终端执行下面的命令。
kubectl apply -f deployment.yaml
这个命令将把我们的服务和应用实例部署到Kubernetes引擎上。执行这个命令后,我们应该可以看到rest-test-service 和rest-test-app 已经成功创建。
部署仪表板
Minikube和Kubernetes提供了一个仪表盘来可视化部署。要在该仪表板中看到我们的部署,在你的终端中执行下面的命令。
minikube dashboard
我们可以看到我们的rest应用程序已经部署,我们可以看到运行的实例数量。如果有请求,负载平衡器会将请求的命中率分配到各实例上。
访问应用程序
我们可以使用下面的命令来访问该应用程序。
minikube start service: rest-test-service
总结
在本教程中,我们已经涵盖了Node.js Express应用程序RESTful APIs的关键概念。我们讨论了如何使用Docker在本地对该应用程序进行docker化,并将其部署到Kubernetes上。