前阵子看到 @于江水 分享了其获取到 AWS Certification 认证的成果,联想到可以将这篇我发布在公司内网的教程分享出来。毕竟,纸上得来终觉浅,绝知此事要躬行。本文演示了如何上线一个 Node.js 应用到阿里云,详尽地记录了对阿里云相关产品和开发链路的完整体验过程。
阿里云也有相似的认证证书。
无论未来是什么 less,相信本文介绍的在阿里云平台上部署、管理和操作方面的技术都会对你有益。——岁月静好,只因有人替你负重前行。
背景:一个社区类应用,技术选型上采用了开源软件 NodeBB。
目录:
最容易最省钱的方式就是购买 ECS 主机然后部署应用。此时应用的架构是这样的:
首次部署上线:
往后迭代:
以下是通过 ECS 部署 NodeBB 的指引教程。
首先我们需要一个 ECS 实例。访问 ECS 控制台 点击“创建实例”。
如果没有开通过 ECS 服务,则需要先开通服务。 阿里云文档中已经有关于 ECS 的详细介绍,这里不再解释。
以下是笔者的配置:
创建实例完成后,默认会获得一个固定公网 IP ,可以使用该 IP 通过 SSH(22端口)或浏览器(80端口)访问该 ECS 实例:
其次,NodeBB 支持 Redis 和 MongoDB 作为数据存储,笔者这里选择了 MongoDB,因此需要创建一个 MongoDB 实例。
访问 MongoDB 控制台 点击“创建实例”:
如果没有开通过 MongoDB 服务,则需要先开通服务。 阿里云文档中已经有关于 MongoDB 的详细介绍,这里不再解释。
创建数据库和用户(也可以通过 Mongo Shell 方式,笔者这里以通过 DMS 为例)。
访问 MongoDB 控制台并进入实例:
点击登录数据库:(输入账号密码,数据库名称填入“admin”(MongoDB 默认数据库)
创建数据库,笔者命名为 club;
创建用户(阿里云数据库不允许使用 root 角色进行远程连接,因此在此新建一个用户,赋予其 club 数据库的增删改查权限):
数据安全性 - 白名单设置(参考):
将 ECS 实例 IP 设置为白名单,访问 ECS 控制台找到刚创建的实例的私有 IP:
安装必要的软件环境并启动 NodeBB。
安装 Node.js。
准备代码:
yum install git
;初始化 NodeBB(初始化数据库、构建静态资源和生成 config.json 文件):./nodebb setup
初始化过程:
生成的 config.json(字段含义参考《The NodeBB Config (config.json)》):
使用 Cluster 模式启动应用:对 NodeBB 源码进行阅读,了解其启动过程,很容易就能看出 NodeBB 的启动流程支持 Cluster 模式——配置 config.json 中 port
为数组即可:
启动 NodeBB:
./nodebb start
;ps -ef | grep node
;service nginx restart
;service nginx status
。域名映射:通过内部的 IDNS 将 http://xxx.taobao.com A 记录到公网 IP。
HTTPS 配置:
部署在 ECS 实例后应用仅仅处于「可用」的状态,还面临着如下问题和隐患:
很容易就能想到使用容器化技术和集群模式。
这就可以应用 Docker 和 Kubernetes(以下简称 k8s),阿里云提供了容器服务 Kubernetes 版。此时应用的架构是这样:
参考:
以下是通过 EDAS 部署 NodeBB 的指引教程。
首先我们需要一个 k8s 集群用于部署我们的应用。访问创建 Kubernetes 集群:
参考:
紧接着,我们需要构建出应用的 Docker 镜像。访问容器镜像服务控制台:
创建镜像仓库:
构建镜像:
在代码仓库的根目录下创建配置文件 config.json:
{ "url": "http://xxx.taobao.com", "secret": "xxx", "database": "mongo", "mongo": { "uri": "mongodb://xxxx" }, "port": "4567" }
Dockerfile 中使用配置文件启动 NodeBB:
FROM node:8.15.0
RUN mkdir -p /usr/src/app WORKDIR /usr/src/app
ARG NODE_ENV ENV NODE_ENV $NODE_ENV COPY install/package.json /usr/src/app/package.json RUN npm install && npm cache clean --force COPY . /usr/src/app
ENV NODE_ENV=production daemon=false silent=false
RUN ./nobebb build CMD ./nodebb start
EXPOSE 4567
通过发布标签触发镜像构建:release-v$version
然后我们创建一个 EDAS 应用,并使用刚创建的镜像部署该应用。访问 EDAS 控制台:
最后,我们在负载均衡层强制启用 HTTPS,并将域名解析到负载均衡的公网 IP。
访问负载均衡控制台操作:
使用 EDAS 已经在一定程度上加强了我们应用的迭代能力、健壮性和并发性,但是在多人协作、持续集成、持续交付上依然空缺。云效则可以应付此类场景。不过云效并不会在创建应用时自动为我们分配机器资源,也没有提供 Node.js 的最佳实践的镜像、构建和部署脚本。
云效内需要自己创建集群资源,并授予云效进行管理。例如,笔者搭建了日常、预发、线上集群:
操作步骤如下:
这样便做到了日常与线上环境的隔离,预发和线上环境的隔离:
这里还有一个命题是,如何实现日常和预发环境只允许特定的客户端进行访问?目前通过负载均衡连接 VPC 的方式,只要知道了负载均衡 IP ,任何客户端都可以访问我们日常和预发环境的应用,这是我们不希望的。
为了和日常、线上环境配合,我们可以创建两个 MongoDB 数据库,并将两个数据库设置在日常和线上专有网络。如何创建请参考上文中“ECS - 创建 MongoDB 实例”章节。
应用构建依赖容器镜像服务,在创建应用时就需要指定镜像仓库,因此我们提前创建。
访问 Aliyun Code 新项目来创建镜像的代码仓库(创建镜像仓库时需关联一个代码仓库):
访问容器镜像服务控制台,创建镜像仓库:
在云效创建应用的过程与 Aone 类似,遵循项目 - 应用的结构,此前的过程不再赘述。这里简单罗列创建 Node.js 应用的配置:
应用名.release
文件,该文件将会在构建阶段被读取用于决定构建过程。
在云效内我们需要手动配置流水线及各环节的构建和部署配置。
我配置了三条流水线:
以日常流水线为例,需要配置最基本的两个阶段:构建和部署。
构建配置:
部署配置(云效将根据这些配置将构建好的包进行下发并部署):
将 k8s 集群导入到云效,选择需要部署的集群。
如果是首次配置,则需要新建服务,保存时云效将创建 k8s 的 service 资源,并在首次部署时创建 k8s 的 deployment 资源:
在 Aone 内 begg 和 midway 已经为我们封装好了镜像、构建和部署脚本的细节,在云效的上线流程中其过程相似,但相关的环节则需要自定义。
在仓库根目录创建如下文件,定义构建和启动脚本。
/bin/build.sh
):在 club.release 中指定,在构建环境将被执行。主要是安装依赖和构建 Nodebb 资源(参考:《NodeBB Development》);sh echo "Target environment is ${PACKAGE_LABEL}"
npm config set registry https://registry.npm.taobao.org
npm install --production || exit 1
./nodebb build -c config.${PACKAGE_LABEL}.json || exit 1
echo "All building process done."
/Dockerfile
:主要是安装 Nginx 和 Node.js ,复制启动脚本之类工作。
/bin/start.sh
:启动脚本,启动 NodeBB 和 Nigix。然后在云效新建特效分支,提交到集成,进行一次流水线的部署,云效便会构建并下发创建 k8s 应用:
在应用上线后,为确保应用在持续健康地运行,还需要有相应的监控及日志(在出现问题时进行现场回溯)。在集团内部,Sandbox 提供了全链路的监控能力。
在云上,有云监控、业务实时监控服务、日志服务。以下简单介绍一下如何接入和查看指标。
在 k8s 集群已开通日志服务的前提下,可以针对集群内的应用进行日志配置。点击应用编辑即可进行配置,首次点击保存 k8s 服务将会自动创建日志服务。
例如笔者就针对应用级别、标准输出进行了存储:
保存后访问阿里云日志服务控制台即看到相关的日志服务已创建:
点击查询即可看到相应的日志,例如笔者配置的 NodeBB 应用日志:
更多内容可参考:《使用日志服务进行Kubernetes日志采集》
对于每个应用,可以通过 k8s 容器服务与云监控的集成,提供监控功能查看应用的资源使用情况。还可以通过可用性监控快速发现本地或依赖的远程服务无响应的情况。
使用业务实时监控服务可从页面打开速度(测速)、页面稳定性(JS Error)和外部服务调用成功率(API)这三个方面监测 Web 页面的健康度。接入后在应用控制台审视相关数据:
更多内容可参考:《前端监控接入概述》
除此之外,笔者还踩了一些 NodeBB 的定制的坑,在此分享给有需要的同学。
主要是两个配置:
笔者已封装 nodebb-plugin-sso-taobao 插件,只需要申请并填写 Appkey 信息即可使用。
NodeBB 的前端基于 Bootstrap 实现,皮肤方案则使用了 bootswatch。bootswatch 中的一些皮肤(例如 simplex)使用了 Google 的字体资源。这些资源由于网络原因在国内无法加载,将会造成网页的渲染阻塞。
在 [email protected] 版本中,目前笔者还没有比较好的办法解决这一问题。唯一的方法就是不使用皮肤,如果确实希望复用某个皮肤的样式,可以通过创建 NodeBB 主题(参考:《如何创建主题》)的方式,将这些资源放入主题包中。