基于KubeSphere使用心得给部门搭建了devsittestprod这4套环境之后,一开始使用较为顺利,但随着项目的推进以及开发人员的增多,同时有多个功能模块需要并行开发与测试,导致原有的4套环境不够用。经过一番摸索后,实现了结合NacosKubeSphere中动态配置多套环境功能,通过修改Nacos中的JSON配置文件可很容易的从4套扩展为16套甚至更多。

原实现方式

最开始自己只准备了devsittestprod这4套环境,由于环境数量不多,对于不同环境的端口配置自己是在代码中直接实现的1

 switch(PRODUCT_PHASE) {
     case "dev":
     env.NODE_PORT = 12002
     break
     case "sit":
     env.NODE_PORT = 13002
     break
     case "test":
     env.NODE_PORT = 14002
     break
     case "prod":
     env.NODE_PORT = 15002
     break
 }

此种方式将相关环境相关的配置全都集中到Jenkins流水线中,在最初的使用阶段可减少配置文件数量,能够快速编写流水线,快速交付使用。但随着项目规模与人员的扩大,当需要灵活配置多套环境时,此种方式采用硬编码的方式会显得捉襟见肘。

kubesphere原始部署方式

修改后的方式

结合项目实际情况以及避免后续再次修改KubeSphere流水线,为了实现灵活的配置多套环境,自己制定了如下2个规则:

  1. 端口信息存放到配置文件中,KubeSphere在构建时去流水线读取相关配置
  2. 当需要扩展环境或修改端口时,不需要修改KubeSphere中的流水线,只需要修改对应的端口配置文件即可2

由于项目中采用Nacos作为配置中心与服务管理平台,故决定采用Nacos作为端口的配置中心,实现流程如下:

kubesphere结合nacos部署

基于上述流程,在个人项目中面临如下问题:

  • 利用Groovy代码获取Nacos中特定的端口JSON配置文件,并能动态解析
  • 利用Groovy代码根据输入输入参数动态的获取Nacos中对应的namespace
  • 由于环境的增多,不可能每套环境都准备一个YAML文件,此时需要动态的读取并更新YAML文件

安装Pipeline Utility Steps插件

Jenkins默认不支持JSONYAML的解析,需要在Jenkins中预先安装Pipeline Utility Steps插件,该插件提供了对JSONYAMLCSVPROPERTIES等常见文件格式的读取与修改操作。

JSON文件设计

JSON文件设计如下,通过env、server、dubbo等属性记录环境和端口信息,通过project来记录具体的项目名称,由于配置文件中的key都是固定的,后续Groovy解析时会较为方便,在需要扩展环境时只需要更新此JSON文件即可。

{
    "portConfig":[
        {
            "project":"lucumt-system",
            "ports":[
                {
                    "env":"dev-1",
                    "server":12001,
                    "dubbo":12002
                },
                {
                    "env":"dev-2",
                    "server":12201,
                    "dubbo":12202
                }
            ]
        },
        {
            "project":"lucumt-idp",
            "ports":[
                {
                    "env":"dev-1",
                    "server":13001,
                    "dubbo":13002
                },
                {
                    "env":"dev-2",
                    "server":13201,
                    "dubbo":13202
                }
            ]
        }
    ]
}

读取namespace

Nacos Open Api中可知查询namespace的请求为/nacos/v1/console/namespaces,基于Groovy的读取代码如下:

response = sh(script: "curl -X GET 'http://xxx.xxx.xxx.xxx:8848/nacos/v1/console/namespaces'", returnStdout: true)
jsonData = readJSON text: response
namespaces = jsonData.data
for(nm in namespaces){
    if(BUILD_TYPE==nm.namespaceShowName){
        NACOS_NAMESPACE = nm.namespace
    }
}

读取Nacos配置文件

Nacos Open Api中可知查询配置文件的请求为/nacos/v1/cs/configs,基于Groovy的读取代码如下:

response = sh(script: "curl -X GET 'http://xxx.xxx.xxx.xxx:8848/nacos/v1/cs/configs?dataId=idp-custom-config.json&group=idp-custom-config&tenant=0f894ca6-4231-43dd-b9f3-960c02ad20fa'", returnStdout: true)
jsonData = readJSON text: response
configs = jsonData.portConfig
for(config in configs){
    project = config.project
    if(project!=PROJECT_NAME){
       continue
    }
    ports = config.ports
    for(port in ports){
        if(port.env!=BUILD_TYPE){
            continue
        }
        env.NODE_PORT = port.server
	}
}

根据YAML文件

由于自己将项目中变化的部分已经单独抽取为了一个YAML文件,故只需要修改此单独配置文件即可,在修改过程中,处于简化考虑,自己先将原有的YAML文件删除,之后重新写入,相关代码如下

yamlFile = 'src/main/resources/bootstrap-dev.yml'
yamlData = readYaml file: yamlFile
yamlData.spring.cloud.nacos.discovery.group = BUILD_TYPE
yamlData.spring.cloud.nacos.discovery.namespace = NACOS_NAMESPACE
yamlData.spring.cloud.nacos.config.namespace = NACOS_NAMESPACE
sh "rm $yamlFile"

writeYaml file: yamlFile, data: yamlData

运行效果

上述的配置均需要在项目编译之前进行,配置完毕的流水线运行效果如下,程序可正常运行,改造目的实现。

kubesphere多环境运行

参考代码


  1. 参见lucumt-system.groovy ↩︎

  2. 在个人项目中Jenkins流水线不需要修改,但需要修改Kubesphere中的默认输入配置,将新增的环境加到下拉列表中,便于使用 ↩︎