Rainbond 结合 Jpom 实现云原生 & 本地一体化项目管理

Posted Rainbond开源

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Rainbond 结合 Jpom 实现云原生 & 本地一体化项目管理相关的知识,希望对你有一定的参考价值。

Jpom 是一个简而轻的低侵入式在线构建、自动部署、日常运维、项目运维监控软件。提供了:

  • 节点管理:集群节点,统一管理多节点的项目,实现快速一键分发项目文件
  • 项目管理:创建、启动、停止、实时查看项目控制台日志,管理项目文件
  • SSH 终端:在浏览器中执行 SSH 终端,方便进行日常运维,记录执行命令记录
  • 在线构建:在线拉取 GIT、SVN 仓库快速构建项目包,不用运维人员手动上传项目包
  • 在线脚本:在线管理脚本、定时执行脚本、webhook 钩子执行、执行日志等
  • Docker管理:在线管理镜像、容器、SWARM 集群。界面化管理 DOCKER
  • 用户管理:多用户管理,实现不同用户不同权限,用户操作、管理日志完善记录
  • 项目监控:实时监控项目当前状态、如果异常自动触发邮件、钉钉报警通知
  • NGINX 配置、SSL 证书:在线快速方便的修改 NGINX 配置文件,SSL 证书统一管理

Rainbond 与 Jpom 结合

Rainbond 与 Jpom 结合可以实现云原生项目和本地项目的统一管理,例如:

  • 使用 Rainbond 部署和管理 Jpom
  • 可通过 Jpom 构建可容器化的云原生项目并部署在 Rainbond 上管理和运维
  • 通过 Jpom 管理一些无法容器化的传统项目以及部署
  • 通过 Jpom 管理 Rainbond 集群的服务器,可作为堡垒机使用
  • 使用 Jpom 管理脚本、执行脚本和定时脚本等。

部署 Jpom

前提

安装 Rainbond,可通过一条命令快速安装 Rainbond。

curl -o install.sh https://get.rainbond.com && bash ./install.sh

对接开源应用商店并部署 Jpom

Jpom 已发布到 Rainbond 开源应用商店,可通过 Rainbond 开源应用商店一键部署 Jpom。

进入 Rainbond 控制台的 平台管理 -> 应用市场 -> 开源应用商店 中搜索 Jpom 并安装。

安装完成后,可通过 Rainbond 提供的默认域名访问 Jpom并登陆进行用户注册。

Jpom 快速入门

本地构建 + SSH 发布 Java Jar 项目

简述使用 Jpom 构建 Java 项目然后通过 SSH 发布到服务器上并运行。

1.添加 SSH 节点

进到 系统管理 -> 资产管理 -> SSH管理 添加 SSH 节点,如下图。

添加 SSH 节点后,点击 关联,配置文件目录,发布的项目将在这个目录下操作。

2.添加 Git 仓库信息

进入 功能管理 -> 在线构建 -> 仓库信息 新增仓库,Git 仓库地址:https://gitee.com/rainbond/java-maven-demo

3.添加构建任务

进入 功能管理 -> 在线构建 -> 构建列表 添加构建:

  • 名称:自定义

  • 源仓库:选择上一步创建的仓库信息

  • 分支:master

  • 方式:本地构建

  • 构建命令:

    mvn clean package
    
  • 产物目录:target/java-maven-demo-0.0.1.jar

  • 发布操作:选择 SSH

  • 发布的SSH:选择第一步配置的 SSH 节点

  • 发布目录:选择配置的目录 /home/zqjava 目录是项目运行目录

  • 发布前命令:一般用于停止就的进程。

Tag="java-maven-demo"

pid=$(ps -ef | grep -v \'grep\' | egrep $Tag| awk \'printf $2 " "\')
if [ "$pid" != "" ]; then      
  echo -n "boot ( pid $pid) is running" 
  echo 
  echo -n $"Shutting down boot: "
  pid=$(ps -ef | grep -v \'grep\' | egrep $Tag| awk \'printf $2 " "\')
  if [ "$pid" != "" ]; then
    echo "kill boot process"
    # kill  "$pid"
    kill -9 "$pid"
  fi
else 
    echo "boot is stopped" 
fi
  • 发布后命令:一般用于启动项目。
nohup java -Dappliction=java-maven-demo -jar /home/zq/java/java-maven-demo-0.0.1.jar > /dev/null 2>&1 &

其他都默认即可,保存并构建。

等待构建完成后,就可以在服务器上看到进程,并且也能访问。

最后

Jpom 还有很多优秀的功能和场景,比如:节点管理、脚本管理、文件管理、监控管理 以及一些实践场景等等,有兴趣的小伙伴可以自行探索。

基于Rainbond开发Python云原生应用

组件开发

这里使用 基于源码中的 Dockerfile 创建组件,因为这种方式能兼容所有类型的项目。

识别为 Dockerfile 类型的源码将使用类似于 docker build -t xxx/xxx . 的命令进行镜像构建,因此此方式是灵活性最高的源码编译方式

基本结构

Python 云原生应用的基本目录结构如下,由 app.py(主程序)、Dockerfile(容器配置)和 requirements.txt(依赖关系)三个文件组成。

.
├── app.py
├── Dockerfile
├── requirements.txt

app.py

最简单、且符合 RESTfulPython Flask 主程序如下:

import json
from flask import Flask, request
from rainbond_python.parameter import Parameter
from rainbond_python.error_handler import error_handler

app = Flask(__name__)
error_handler(app)

@app.route('/demo/1.0/api', methods=['GET', 'POST', 'PUT', 'DELETE'])
def api():
    parameter = Parameter(request)

    if parameter.method == 'GET':
        return json.dumps(parameter.param_url, ensure_ascii=False), 200, []

    elif parameter.method == 'POST':
        return json.dumps(parameter.param_json, ensure_ascii=False), 200, []

    elif parameter.method == 'PUT':
        return json.dumps(parameter.param_json, ensure_ascii=False), 200, []

    elif parameter.method == 'DELETE':
        return json.dumps(parameter.param_json, ensure_ascii=False), 200, []

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

requirements.txt

这个通用的 Python 项目的依赖文件,根据上面的示例代码,我们的依赖如下:

Flask
gunicorn
rainbond-python

Dockerfile

这个通用的 Dockerfile 是用来构建镜像的文本文件,内容包含了一条条构建 Docker 镜像所需的指令,基于上面的示例代码,我们的容器配置如下:

FROM python:3.8.7
WORKDIR /app
ADD . /app
RUN pip install -i https://mirrors.aliyun.com/pypi/simple/ --no-cache-dir -r requirements.txt
CMD ["gunicorn", "app:app", "-b", "0.0.0.0:8000", "--log-file", "-", "--access-logfile", "-", "--error-logfile", "-"]
EXPOSE 8000

组件调试

在不同的阶段(开发、测试、发布)中,我们可以使用不同的方式对组件进行调试,这些调试可以确保组件在 Rainbond 云原生平台上被正确部署。

# 开发调试
$ python3 app.py
# 测试调试
$ pip3 install -r requirements.txt
$ gunicorn app:app
# 发布调试
$ docker build -t devdocker .
$ docker run devdocker

部署组件

首先创建好 团队应用,并进入到应用视图中,选择 “+ 添加组件”,如下图:

点击 “自定义仓库”,填入 Git 仓库地址,如果组件是统一管理在同一个仓库中,我们可以通过 “填写子目录路径” 来指定组件所在目录,如下图:

最后点击 “新建组件” 就可以快速开始部署组件。

组件访问策略

在组件需要 被外部访问 时,如果是企业内网部署,我们还需要配置组件的访问策略,进入应用视图中,选择 “网关 > 访问策略管理” ,如下图:

找到我们刚才创建的组件,点击 “编辑”,并按照什么示例代码的内容进行配置,如下图:

特别要注意,“域名” 要填写一个配置好内网解析的域名地址,这样,便可以通过 xxxxxx.xxxx.com/demo/1.0/api 访问到组件的服务。

数据存储

在 Python 云原生开发实践中,推荐使用 MongoDB 数据库,因此我们可以从 Docker Hub 获取 MongoDB Docker 镜像。

添加存储组件

首先进入到应用视图中,选择 “+ 添加组件”,并选择 “从源镜像开始 > 指定镜像”,然后在 “镜像地址” 栏输入 mongo,如下图:

点击创建,接下来 Rainbond 就会开始自动部署 MongoDB 存储组件。(PS:如果在内网环境下,请耐心等待……)

配置存储组件

首先,我们要明确我们是在开发 云原生 项目,数据库是可选项,所以,就算没有这个可选项,我们的组件也不能因为这个异常,而导致程序崩溃。

在云原生的体系中,数据库是一个独立的组件,是原生运行在容器云平台里的一个分布式数据库,真正做到了存储和计算的完全分离

在 MongoDB 组件的 依赖 > 端口列表 中找到 27017 端口,开放 “对内服务”,修改 “使用别名” 为 MONGODB,如下图:

通过上一步,就可以在 依赖 > 组件连接信息 中看到 MONGODB_HOSTMONGODB_PORT 两个变量,分别是 MongoDB 组件的连接地址和端口号信息。

依赖存储组件

计算组件存储组件 分离的情况下,计算组件 需要通过 存储组件依赖 > 组件连接信息 中的数据库连接信息来访问 存储组件

计算组件 视图的的 依赖 > 依赖组件信息 下,选择 “+ 添加依赖”,并添加我们安装在应用内的 存储组件,如图所示:

接下来,我们就可以在 计算组件 中,通过环境变量,获取 存储组件 的组件连接信息。

操作数据库

计算组件app.py(主程序)文件中,可以简单实现一个对 MongoDB 数据库的读取、写入的示例:

import json
from flask import Flask, request
from rainbond_python.parameter import Parameter
from rainbond_python.db_connect import DBConnect

app = Flask(__name__)
db = DBConnect(db='demo', collection='test')

@app.route('/demo/1.0/api', methods=['GET', 'POST'])
def api():
    parameter = Parameter(request)

    if parameter.method == 'GET':
        cursor = db.mongo_collection.find()
        if not db.mongo_collection.estimated_document_count():
            return '资源为空', 204, []
        data = list(cursor)
        return str(data), 200, []

    elif parameter.method == 'POST':
        if parameter.verification(checking=parameter.param_json, verify='name': str, 'age': int):
            param = parameter.param_json
            insert_dict = 'name': param['name'], 'age': param['age']
            if db.write_one_docu(docu=insert_dict):
                return '新资源被创建', 201, []
            else:
                return '资源无法被创建', 500, []
        else:
            return '请求参数错误', 400, []

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

上面代码中,并没有出现获取 存储组件 连接信息的代码,因为这部分内容已经被 rainbond-python 所封装,其中 DBConnect 的初始化代码片段如下:

import os
……
class DBConnect():
    def __init__(self, db: str, collection: str, home_kye='MONGODB_HOST', port_kye='MONGODB_PORT'):
        self.mongo_home = os.environ.get(home_kye, None)
        self.mongo_port = os.environ.get(port_kye, 27017)
……

可以看到,home_kyeport_kye 的默认值对应的正是 MONGODB_HOSTMONGODB_PORT,当我们没有赋值时,它自动会读取这两个环境变量。

开发细节

在环境中存储配置

按照 12-factors 的第 III 条:在环境中存储配置。我们需要把组件的配置信息存储在环境中,在 Dockerfile(容器配置)文件中,我们添加两个配置信息:

……
ENV SPEECH_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ENV SERVICE_REGION=eastus
……

这样配置后,当组件部署到 Rainbond 云原生平台后,这两个环境配置会出现到组件视图的 “环境配置” 标签页,如下图所示:

然后我们只需要在组件的代码文件中,通过下列代码,即可读取到这些配置信息:

import os
……
speech_key = os.environ.get('SPEECH_KEY', None)
service_region = os.environ.get('SERVICE_REGION', None)
……

容器中安装依赖

有时候,默认的 Docker 容器里会缺少组件运行必须的依赖,这时我们就需要配置安装命令,例如,我们在 Dockerfile(容器配置)文件里编写系统库 libasound2 的安装命令:

……
RUN apt-get update
RUN apt-get install -y libasound2
……

这样,我们就可以缺啥补啥。

在开发机上配置环境变量

在本地开发时,我们就需要在开发机配置组件需要的环境变量,以 Ubuntu 开发机为例,通过 vim /etc/profile 打开系统环境变量文件,并在最后加入新的环境变量,例如:

export KEY=VALUE

然后保存文件,并通过 source /etc/profile 使编辑的配置生效,还可以通过 export 查看当前系统的环境变量,再确认一遍环境变量添加成功。

前端组件的打包脚本

如果是 React 前端项目,那么 Dockerfile(容器配置)文件可以参考下面代码:

FROM node:lts
WORKDIR /app
ADD . /app
RUN npm install
RUN npm run build
RUN npm install -g http-server
CMD ["http-server", "./build", "-p", "6001", "-a"]
EXPOSE 6001

大致过程是:安装Node稳定镜像 > 初始化项目 > 构建项目 > 安装http-server库 > 运行项目,很简单的。

查看组件容器日志

如果要查看 Rainbond 部署的组件日志,我们要知道 K8s 与 Rainbond 的关系:NAMESPACE=团队/集群、POD=应用、Docker=组件。所以,我们要查看日志的时候,基本就是查看K8s日志的路数:

# 登录集群主节点服务器
ssh -p22 xxxx@xxx.xxx.x.xxx
# 查看POD
kubectl get pod -A -o wide
# 查看某一个POD中容器的日志(一)
kubectl -n [NAMESPACE] logs --tail=100 [POD] [Docker]
# 查看某一个POD中容器的日志(二)
kubectl -n [NAMESPACE] logs -f [POD] [Docker]

其中,NAMESPACE 和 POD 的位置在下图位置中:

而 Docker 则在 Rainbond 上查看,如下图:

这样就可以直接查看最原始的日志信息。

处理前端组件跨域问题

我们可以把 API 服务组件、前端 UI 组件通过同一个域名进行解析,如下图:

这样,哪里还会出现什么跨域问题。

提前构建好基础镜像

如果构建过程太慢,比如构建一次要好几分钟,那么我们可以提前把一些环境构建过程制作成基础镜像,只要构建过程会加快很多。

# 本地构建镜像
$ docker build -t demo .
# 给镜像打tag
$ docker tag [IMAGE ID] [私有hub域名]/[项目名称]/demo:latest
# 推送到私有hub仓库
$ docker push [私有hub域名]/[项目名称]/demo:latest

然后将 Dockerfile(容器配置)文件的第一行改为:

FROM [私有hub域名]/[项目名称]/demo:latest

这样,原本可能要几分钟的构建过程,现在只需要几十秒就可以完成,非常棒!

模拟服务器环境调试

在云原生平台部署组件之前,最好模拟服务器环境在本地测试一下:

# 本地构建镜像
$ docker build -t demo .
# 查看打包的镜像
$ docker images
# 运行镜像
$ docker run -p 6008:6008 demo
# 运行镜像(指定环境变量)
$ docker run -e "KEY=xxx" -p 6008:6008 demo
# 运行镜像(后台运行)
$ docker run -d -p 6008:6008 demo
# 查看运行中的容器
$ docker ps
# 暂停运行中的容器
$ docker stop <CONTAINER ID>
# 关闭运行中的容器
$ docker rm <CONTAINER ID>
# 删除镜像
$ docker rmi <IMAGE ID>

这样可以避免在云原生平台不方便调试的问题。

查看网关容器Nginx配置

在 Rainbond 平台配置网关后,可以进入网关容器,查看配置的域名规则生成的 Nginx 配置是否正确:

# 找到网关容器的NAME
$ kubectl get pod -A -o wide
# 进入网关容器
$ kubectl -n rbd-system exec -it <网关容器NAME> bash
# 输出default_servers.conf内容
$ cat /run/nginx/conf/http/default/default_servers.conf
# 退出网关容器
$ exit

这样就可以确认 Rainbond 平台配置的网关规则是否正确。

以上是关于Rainbond 结合 Jpom 实现云原生 & 本地一体化项目管理的主要内容,如果未能解决你的问题,请参考以下文章

一文了解 Rainbond 云原生应用管理平台

云原生之kubernetes实战在kubernetes集群下部署Rainbond平台

基于Rainbond开发Python云原生应用

详解 Rainbond Ingress 泛解析域名机制

详解 Rainbond Ingress 泛解析域名机制

10分钟在 Rainbond 上部署 mall 电商项目