1. 概述
ks-console主要是作为用户和kubereshpere交互的入口,主要为用户提供页面的交互方式,以及少量API接口。
如图所示,ks-console第一层级主要包含会话管理,其他API,页面。
- 会话管理主要是登录授权后维持用户token等的权限cache
- 其他API主要是直接提供了部分和dockerhub或者下载的部分API
- 页面主要提供用户的交互入口
从页面功能来看,又分为管理页面和终端页面,终端页面是提供在页面上使用命令行直接与kubernetes的交互界面,管理页面则是集成化的对整个kubesphere的管理
管理业面又主要分为集群管理,权限管理和系统设置
- 集群管理 管理集群的整体资源
- 权限管理 管理用户或用户组的权限
- 系统设置 对系统邮箱,webhook等全局配置进行管理
2. 结构分析
如图所示
- 路由层是整个前段系统的入口,主要使用koa提供了最外层的服务框架,其中嵌入了配置管理config和部分交互数据压缩等的中间件工具utils。
- 会话层主要是提供了用户的登录,以及登录后的session数据维持管理; 主要提供页面的访问入口。此外还有dockerhub等API接口。
- 路由分发层则从业面上做了功能分发,提供管理页面(kubesphere pages)以及终端页面(terminal)两个访问入口。
- 页面逻辑层中才是管理页面的真正实现,使用react框架,完成了页面的支持。
- 管理页面或者终端页面都将最终在后台API层通过ks-apiserver 与后台交互。
- 路由层
如下所示,可以看到在路有层中,根据访问路径对业务进行分发,包括基本工具API,登录管理API,终端页面,和最后的用户管理页面。
router
.use(proxy('/devops_webhook/(.*)', devopsWebhookProxy))
.use(proxy('/b2i_download/(.*)', b2iFileProxy))
.get('/dockerhub/(.*)', parseBody, handleDockerhubProxy)
.get('/blank_md', renderMarkdown)
.all('/(k)?api(s)?/(.*)', checkToken, checkIfExist)
.use(proxy('/(k)?api(s)?/(.*)', k8sResourceProxy))
.get('/sample/:app', parseBody, handleSampleData)
// session
.post('/login', parseBody, handleLogin)
.get('/login', renderLogin)
.post('/login/confirm', parseBody, handleLoginConfirm)
.get('/login/confirm', renderLoginConfirm)
.post('/logout', handleLogout)
// oauth
.get('/oauth/redirect/:name', handleOAuthLogin)
// terminal
.get('/terminal*', renderTerminal)
// page entry
.all('*', renderView)
- 路由分发层
注意前面最后路由分发的 renderTerminal 和 renderView其实现如下,该层是根据路由的路径不同,去查询对应打包文件中的页面入口,从而真正让用户进入终端页面和管理业面。
const renderIndex = async (ctx, params) => {
const manifest = getManifest('main')
const localeManifest = getLocaleManifest()
await ctx.render('index', {
manifest,
isDev: global.MODE_DEV,
title: clientConfig.title,
hostname: ctx.hostname,
globals: JSON.stringify({
config: clientConfig,
localeManifest,
...params,
}),
})
}
const renderTerminal = async ctx => {
try {
const manifest = getManifest('terminalEntry')
const [user, ksConfig] = await Promise.all([
getCurrentUser(ctx),
getKSConfig(),
])
const localeManifest = getLocaleManifest()
await ctx.render('terminal', {
manifest,
isDev: global.MODE_DEV,
title: clientConfig.title,
hostname: ctx.hostname,
globals: JSON.stringify({
localeManifest,
user,
ksConfig,
}),
})
} catch (err) {
renderViewErr(ctx, err)
}
}
- 页面逻辑层
因为终端页面直接使用的第三方库,因此基本没有开发逻辑,而管理页面则是使用react实现后打包完成.
其目录入下具体实现都按照react的规范设计, 在后面章节单独分析。
3. 页面结构
- actions 调用底层最终的交互动作封装
- assets 各种常量
- configs 配置管理
- pages 页面的封装
- core 二次封装,整体入口
- compents 套件封装
- sccss 样式
- storages 页面数据管理
- utils 工具封装
下面对管理页面整体结构分析
- 首先index是整个页面的入口。
- index中包含的route则是陆游的入口。
- 路由注册了两种页面,一种是导航页面view1, 一种是逻辑页面view2。
逻辑页面会交互完成集群查询管理,节点管理等具体逻辑功能。而导航页面则只负责展示导航列并提供点击做页面跳转。 - 导航页面支持动态呈现,其通过global组件从config里面获取页面元素和布局,动态展现支持的资源提供跳转链接。
- 逻辑页面则是导航页面跳转的。
- 逻辑页面通过controller调用action中的模块和后台交互,管理获取后台的实际资源。
- 而store则是在前端存取的后台资源的cache。
- view展示数据时对应的后台资源则从store获取。