nginx向云原生演進,All in?OpenNJet!
1. 應用門戶簡介
NJet 應用引擎是基于 Nginx 的面向互聯網和云原生應用提供的運行時組態服務程序,作為底層引擎,NJet 實現了NGINX 云原生功能增強、安全加固和代碼重構,利用動態加載機制可以實現不同的產品形態,如Web服務器、流媒體服務器、負載均衡、代理(Proxy)、應用中間件、API網關、消息隊列等產品形態等等。NJet使用現有的API Gateway及各動態配置模塊提供的能力,實現了一個Portal管理模塊。通過該模塊,對外提供應用門戶的功能,以此來簡化應用的開發及部署過程。應用可以只專注于業務邏輯的實現,將通用的安裝配置及權限認證功能統一交給NJet應用門戶管理模塊。邏輯架構如下圖所示:
2. 應用部署流程
用戶使用管理員賬號登錄Portal門戶,上傳應用,添加用戶/組/角色,最后進行應用的授權。完成上述操作后,使用普通用戶賬號登錄門戶,即可使用應用。
a. 管理員登錄
在部署包含Portal 管理模塊的環境上,使用api gateway的管理員賬號登錄后,將顯示Portal 的管理界面,在該界面中可以進行應用的部署,及相關的授權。
b. 上傳應用
應用管理中點擊“新增”,選擇Portal 應用的相應npk 文件(應用的結構在后續章節進行說明)。點擊確認后,Portal管理模塊將自動創建應用需要的Location/Upstream, 由于使用了NJet的動態配置功能,所有的改動將實時生效,不需要重啟或重加載NJet。
應用如果需要連接第三方組件,門戶管理模塊也提供了通用組件的配置能力。
c. 創建訪問應用需要的用戶/組/角色
應用門戶使用Api Gateway提供的授權能力,其模型是“用戶->組->角色”的授權模型,一個用戶可以歸屬于不同的用戶組,一個用戶組可以分配多個角色,API 授權將授權到角色上。
應用門戶的 UI上可以對用戶/組/角色及相互間的關系進行維護。
d. 對應用進行授權
在應用管理中,選擇應用授權,對應用不同的訪問路徑可以授予不同的角色。
e. 普通用戶登錄
使用普通用戶賬號登錄后,將顯示應用一覽頁面,在改列表頁面中點擊對應的圖標,將跳轉至具體的應用中。
3. Portal 應用結構
使用Portal 管理模塊部署的應用,需要使用Portal模塊可以識別的格式進行目錄規劃及應用打包,文件類型是npk (NJet Package)。 典型的目錄結構如下圖所示:
-
META-INF 目錄
manifest.json: 應用的基本信息,包括入口地址,配置地址,及location / upstream 信息。
圖標文件: jpg 或 jpg 格式的文件
app_openapi.json: openapi 3.0 格式的文件,其中path 支持 通配符*, 例如 /setting/*
app_schema.json: 應用需要的組件配置項 (可選,非必須) -
scripts 目錄
應用使用的腳本 -
static 目錄
靜態頁面,資源文件,javascript 腳本, css
manifest.json 示例
該文件中定了入口地址(entry_point), 應用配置地址(cfg_url), 及應用需要的 location, upstream servers, \proxy_pass。Location 中可以直接配置屬性("__access_control": “true” ) 來標識該訪問地址需要使用門戶提供的用戶授權功能。
{"manifest_version": "1.0.0","app": {"name": "ollamaApp","version": "1.0.0","arch": "x86_64","description": "Ollma Chat application","icon_file": "ollama.jpg","api_file": "app_openapi.json" },"deployment": {"type": "location","server_name": "","entry_point": "/ollama-app/open/chat","cfg_url": "/ollama-app/open/config","locations": [{"path": "/ollama-app/conversation","properties": {" content_by_lua_file": "${APP_PREFIX}/scripts/chat_api.lua"}},{"path": "/ollama-app/setting","properties": {"__access_control": "true", " content_by_lua_file": "${APP_PREFIX}/scripts/chat_api.lua"}},{"path": "/ollama-app/chat","properties": {"access_by_lua_file": "${APP_PREFIX}/scripts/access.lua", ?"proxy_set_header": ["Host 192.168.0.206","Origin http://192.168.0.206"],"proxy_pass": {"schema": "http","servers": [{"server":"192.168.40.206:11434"}],"url": "/api/chat"}}},{"path": "/ollama-app","properties": {"__access_control": "true", "alias": "${APP_PREFIX}/static/","try_files": "$uri $uri/ /ollama-app/index.html"}}]}
}
app_schema.json 示例
應用需要連接第三方組件時,組件的配置通過json文件描述配置項,門戶管理模塊將根據json內容動態生成配置頁面。該配置使用 formily (阿里巴巴表單框架?https://formilyjs.org/)定義的格式。 以下示例文件為連接redis 組件時需提供的json文件。
{"redis_host": {"type": "string","x-component": "Input","x-component-props": {"placeholder": "請輸入ip地址"},"x-decorator": "Form.Item","x-decorator-props": {"label": "Redis IP","tooltip": "請輸入ip地址"}},"redis_port": {"type": "number","x-component": "InputNumber","x-component-props": {"placeholder": "請輸入端口號","min": 0,"max": 65535},"x-decorator": "Form.Item","x-decorator-props": {"label": "Redis Port","tooltip": "請輸入端口號"}},"redis_password": {"type": "string","x-component": "Input.Password","x-component-props": {"placeholder": "請輸入 密碼"},"x-decorator": "Form.Item","x-decorator-props": {"label": "Redis密碼","tooltip": "請輸入密碼"}}
}
4. Demo 應用完整實例
a. 通過ftp 獲取到 demo 應用包
地址:?ftp.tmlake.com
目錄: /OpenNjet/Software/v3.2.2-portal
文件: demo_app_1.0.2.npk
b. 使用默認管理員賬號 agw_admin /****** 登錄 /portal
c. 添加demo應用
在應用管理中,選擇新增,添加獲取的 demo_app_1.0.2.npk, 并點擊確認
成功后,應用管理頁面將出現 demo 應用的條目
d. 為用戶添加用戶/組/角色
添加一個demo用戶角色
添加一個demo用戶組
為這個組分配角色
添加一個 user1 用戶,并指定 domain 為 “demo”
為這個用戶分配組
e. 編輯應用的授權
在應用管理列表中點擊 demo 的授權該應用只有一個訪問地址,選擇后點擊授權,在彈出的窗口下拉框中選擇"demoUserRole"
f. 使用剛創建的普通用戶賬號登錄 /portal
應用列表中顯示出我們剛剛部署的demo 應用?
點擊應用圖標后,跳轉到應用的頁面
該demo應用只是簡單的一些頁面Tab, 展示的也只是一些測試數據
5. 后續改進
目前部署的應用有新版本需要升級時,需要在應用管理中刪除應用后,重新上傳。后續將繼續優化門戶管理模塊,提供應用的版本管理及回滾功能。
6. 參考
a. 使用到的API
API Gateway: 用戶/組/權限的增刪改查,api group 創建,oas3.0 格式文檔導入,應用部署接口
doc/swagger/helper_api_gateway.yaml · OpenNJet/OpenNJet - Gitee.com
動態Location API: 動態添加及刪除Location
doc/swagger/helper_dy_loc.yaml · OpenNJet/OpenNJet - Gitee.com
動態Upstream API: 動態添加及刪除 Upsteam
doc/swagger/helper_dyn_http_ups.yaml · OpenNJet/OpenNJet - Gitee.com\
b. Demo 應用包的下載
地址:?ftp.tmlake.com?\
目錄: /OpenNjet/Software/v3.2.2-portal
文件: demo_app_1.0.2.npk
c. NJet版本及Portal 獲取及安裝
NJet 版本需要 > 3.2.2
Portal 門戶管理模塊獲取:
地址:?ftp.tmlake.com
目錄: /OpenNjet/Software/v3.2.2-portal/
文件: portal_1.0.2.npk , ssh_remote_mod.so
Portal 門戶管理模塊安裝:
修改配置 /usr/local/njet/conf/njet.conf
worker_processes auto;cluster_name njet;
node_name node1;error_log logs/error.log error;helper ctrl modules/njt_helper_ctrl_module.so conf/njet_ctrl.conf;
helper broker modules/njt_helper_broker_module.so;load_module modules/njt_agent_dynlog_module.so;
load_module modules/njt_dyn_ssl_module.so;
load_module modules/njt_http_vtsc_module.so;
load_module modules/njt_http_location_module.so;
load_module modules/njt_http_lua_module.so;
load_module modules/njt_http_dyn_upstream_module.so;
load_module modules/njt_http_dyn_server_module.so;
load_module modules/njt_http_token_sync_module.so;
load_module modules/njt_http_upstream_member_module.so;
load_module modules/njt_http_dyn_lua_module.so;events {worker_connections 1024;
}shared_slab_pool_size 100m;
http {token_sync zone=token:4M sync_time=5s clean_time=10s;dyn_kv_conf conf/iot-work.conf;include mime.types;access_log off;vhost_traffic_status_zone;lua_package_path "$prefix/lualib/lib/?.lua;$prefix/modules/?.lua;$prefix/apps/?.lua;;";lua_package_cpath "$prefix/lualib/clib/?.so;;";init_by_lua_block {local _=require("lor.index")local _=require("lsqlite3complete")}server {listen 8080;error_page 401 =302 /portal;client_max_body_size 1000m; location / {root html;}location /icons/ {alias /usr/local/njet/apps/__icons/;try_files $uri =404;}}
}
load_module modules/njt_http_sendmsg_module.so;
load_module modules/njt_ctrl_config_api_module.so;
load_module modules/njt_helper_health_check_module.so;
load_module modules/njt_http_upstream_api_module.so;
load_module modules/njt_http_location_api_module.so;
load_module modules/njt_doc_module.so;
load_module modules/njt_http_vtsd_module.so;
load_module modules/njt_http_lua_module.so;
load_module modules/njt_http_dyn_upstream_module.so;
load_module modules/njt_http_dyn_upstream_api_module.so;
load_module modules/njt_http_dyn_server_api_module.so;
load_module modules/njt_http_upload_module.so;error_log logs/error_ctrl.log error;events {worker_connections 1024;
}http {dyn_kv_conf conf/ctrl_kv.conf;lua_package_path "$prefix/lualib/lib/?.lua;$prefix/modules/?.lua;;";lua_package_cpath "$prefix/lualib/clib/?.so;;";init_by_lua_block {local _=require("lor.index")local _=require("lsqlite3complete")}include mime.types;access_log off;server {client_max_body_size 1000m; listen 8081;location / {return 200 "njet control panel\n";}location /api {dyn_module_api; }location /doc {doc_api;}location /metrics {vhost_traffic_status_display;vhost_traffic_status_display_format html;}location /api_gateway {access_by_lua_block {local ac=require("api_gateway.access.control")local access=ac.new("/api_gateway")access:check()}content_by_lua_block {local api_gateway=require("api_gateway")api_gateway.main()}}}
}
拷貝 ssh_remote_mod.so
sudo cp ssh_remote_mod.so /usr/local/njet/lualib/clib/
重啟 njet
sudo systemctl stop njet
sudo systemctl start njet
將下載后的 portal_1.0.2.npk 文件上傳到 njet 主機上,并且主機上安裝 curl 及 jq 命令行工具
NJET_SITE="http://localhost:8081"PORTAL_FILE=$(curl -k -s -F "file=@portal_1.0.2.npk" "$NJET_SITE/api/v1/upload" |jq -r '.file')TOKEN=$(curl -k -X POST -d '{"login_data":{"username": "agw_admin", "password": "********"}}' -s "$NJET_SITE/api_gateway/auth/login" | jq -r '.token')curl -X 'POST' \"$NJET_SITE/api_gateway/deploy/app" \-H "Authorization: Bearer $TOKEN" \-H "Content-Type: application/json" \-d "{\"uploaded_file\": \"$PORTAL_FILE\"}"
NJet 應用引擎通過內核重構實現了獨特的運行時動態配置加載能力,是 新一代高性能 Web 應用引擎 。NJet 擁有高性能數據面處理能力,將集群、高可用、主動健康檢查、聲明式 API 等多種輔助功能,通過 NJet 獨特的副駕駛 CoPilot 服務框架調度,從而方便功能擴展,隔離管理 / 控制功能對數據面的影響,NJet 應用引擎性能超過 CNCF 推薦 Envoy 應用引擎的三倍。?
官網:https://njet.org.cn/?
郵件組:https://njet.org.cn/mailman/listinfo