关于云计算:KubeSphere-助力提升研发效能的应用实践分享

42次阅读

共计 5921 个字符,预计需要花费 15 分钟才能阅读完成。

作者:卢运强,次要从事 Java、Python 和 Golang 相干的开发工作。酷爱学习和应用新技术;有着非常强烈的代码洁癖;喜爱重构代码,长于剖析和解决问题。原文链接。

我司从 2022 年 6 月开始应用 KubeSphere,到目前为止快一年工夫,简要记录下此过程中的教训积攒,供大家参考。

背景

公司以后有靠近 3000 人的规模,次要业务为汽车配套相干的软硬件开发,其中专门从事软件开发约有 800 人,这其中 Java 开发的约占 70%,余下的为 C/C++ 嵌入式和 C# 桌面程序的开发。

在 Java 开发局部,约 80% 的都是 Java EE 开发,因为公司的业务次要是给内部客户提供软硬件产品和咨询服务,在晚期公司和部门更关注的是如何将产品销售给更多的客户、取得更多的订单和尽快回款,对软件开发流程这块没有过多的器重,故晚期在软件开发局部不是特地规范化。软件开发基于我的项目次要采纳麻利开发或瀑布模型,而对于软件部署和运维仍旧采纳的纯手工形式。

随着公司规模的扩充与软件产品线的增多,上述形式逐步暴露出一些问题:

  • 存在大量重复性工作,在软件疾速迭代时,须要频繁的手工编译部署,消耗工夫,且此过程不足日志记录,后续无奈追踪审计;
  • 不足审核性能,对于测试环境和生产环境的操作须要审批流程,之前通过邮件和企业微信无奈串联;
  • 不足准入性能,随着团队规模扩充,人员素质参差不齐,须要对软件开发流程、代码格调都须要强制固化;
  • 不足监控性能,后续不同团队、我的项目采纳的监控计划不对立,不利于常识的积攒;
  • 不同客户的定制化性能太多(logo,字体,IP 地址,业务逻辑等),采纳手工打包的形式效率低,容易脱漏出错。

在竞争日益强烈的市场环境下,公司须要把无限的人力资源优先用于业务迭代开发,解决上述问题变得愈发迫切。

选型阐明

基于前述起因,部门筹备选用网络上开源的零碎来尽可能的解决上述痛点,在技术选型时有如下考量点:

  • 采纳尽量少的零碎,最好一套零碎能解决前述所有问题,防止多个系统维护和整合的老本;
  • 采纳开源版本,防止公司外部手工开发,节约人力;
  • 装置过程简洁,不须要简单的操作,能反对离线装置;
  • 文档丰盛、社区沉闷、应用人员较多,遇到问题能较容易的找到答案;
  • 反对容器化部署,公司和部门的业务中主动驾驶和云仿真相干的越来越多,此局部对算力和资源提出了更高的要求。

咱们最开始采纳的是 Jenkins,通过 Jenkins 基本上能解决咱们 90% 的问题,但仍旧有如下问题影应用体验:

  • 对于云原生反对不太好,不利于部门后续云仿真相干的业务应用;
  • UI 界面简陋,交互方式不敌对(我的项目构建日志输入等);
  • 对于我的项目,资源的权限调配与隔离过于简陋,不满足多我的项目多部门应用时细粒度的辨别要求。

在网络上查找后发现相似的工具有很多,通过初步比照筛选后偏向于 KubeSphere、Zadig 这 2 款产品,它们的基本功能都相似,进一步比照如下:

KubeSphere Zadig
云原生反对 个别
UI 好看度 个别
GitHub Star 12.4k 2k
社区活跃度 个别

通过比照,KubeSphere 较为合乎咱们的需要,尤其是 KubeSphere 的 UI 界面非常好看,故最终选定 KubeSphere 作为部门外部的继续集成与容器化管理系统!

至此,部门外部经验了 手工操作 ->Jenkins->KubeSphere 这 3 个阶段,各阶段的次要应用点如下:

实际过程

KubeSphere 在公司外部的整体部署架构如下图所示,其作为最顶层的应用程序间接与应用人员交互,提供被动 / 定时触发构建、利用监控等性能,应用人员不用关怀底层的 Jenkins、Kubernetes 等依赖组件,只须要与 Gitlab 和 KubeSphere 交互即可。

继续集成

初始实现

在最后的尝试阶段只布局了 4 套环境:dev(开发环境)、sit(调试环境)、test(测试环境)、prod(生产环境)。

出于简化应用与保护的思考,打算对每个工程模块只保护一条流水线,通过构建时抉择不同的环境参数来实现定制化打包与部署。

KubeSphere 和 Kubernetes 目前在部门是以单机版模式装置的,故对于不同环境的辨别次要是通过调配不同端口来实现,具体实现时须要能在 Jenkins 和 Kubernetes 的 yaml 文件中都能动静的获取对应的端口参数和项目名称,参考实现代码如下:

  • 在基于 Groovyscript中依据抉择环境动态分配相干端口

    switch(PRODUCT_PHASE) {
        case "sit":
            env.NODE_PORT = 13003
            env.DUBBO_PORT = 13903
            break
        case "test":
            env.NODE_PORT = 14003
            env.DUBBO_PORT = 14903
            break
        case "prod":
            env.NODE_PORT = 15003
            env.DUBBO_PORT = 15903
            break
    }
  • script中读取参数

    print env.DUBBO_IP
  • shell中读取参数

    docker build -f kubesphere/Dockerfile \
    -t idp-data:$BUILD_TAG  \
    --build-arg  PROJECT_VERSION=$PROJECT_VERSION \
    --build-arg  NODE_PORT=$NODE_PORT \
    --build-arg  DUBBO_PORT=$DUBBO_PORT \
    --build-arg PRODUCT_PHASE=$PRODUCT_PHASE .
  • yaml文件中读取参数

    spec:
      ports:
        - name: http
          port: $NODE_PORT
          protocol: TCP
          targetPort: $NODE_PORT
          nodePort: $NODE_PORT
        - name: dubbo
          port: $DUBBO_PORT
          protocol: TCP
          targetPort: $DUBBO_PORT
          nodePort: $DUBBO_PORT
      selector:
        app: lucumt-data-$PRODUCT_PHASE
      sessionAffinity: None
      type: NodePort

运行成果相似下图:

具体内容请参见 KubeSphere 应用心得。

环境扩容

基于前述形式搭建的 4 套环境一开始应用较为顺利,但随着我的项目的推动以及开发人员的增多,同时有多个功能模块须要并行开发与测试,导致原有的 4 套环境不够用。通过一番摸索后,实现了联合 Nacos 在 KubeSphere 中动静配置多套环境性能,通过批改 Nacos 中的 JSON 配置文件可很容易的从 4 套扩大为 16 套甚至更多。

联合我的项目理论状况以及防止后续再次批改 KubeSphere 流水线,为了实现 灵便的配置多套环境,制订了如下 2 个规定:

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

因为我的项目中采纳 Nacos 作为配置核心与服务治理平台,故决定采纳 Nacos 作为端口的配置核心,实现流程如下:

基于上述流程,在具体实现时面临如下问题:

  • 利用 Groovy 代码获取 Nacos 中特定的端口 JSON 配置文件,并能动静解析;
  • 利用 Groovy 代码依据输出输出参数动静的获取 Nacos 中对应的 namespace
  • 因为环境的增多,不可能每套环境都筹备一个 YAML 文件,此时须要动静的读取并更新 YAML 文件。

因为 Jenkins 默认不反对 JSONYAML 的解析,须要在 Jenkins 中事后装置 Pipeline Utility Steps 插件,该插件提供了对 JSONYAMLCSVPROPERTIES 等常见文件格式的读取与批改操作。

  • 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
                    }
                ]
            }
        ]
    }
  • Nacos Open Api 中可知查问 namespace 的申请为 /nacos/v1/console/namespaces,查问配置文件的申请为 /nacos/v1/cs/configs,基于 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}
    }
    
    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 文件

    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

具体内容请参见利用 Nacos 与 KubeSphere 创立多套开发与测试环境。

扩大性能

  • 在我的项目构建时增加审核性能,对于 testprod 环境必须通过相干人的审核能力进行后续构建流程,防止毁坏相干版本的稳定性。

  • 在 KubeSphere 的容器组页面能够查看 pod 节点的 CPU 和内存耗费,可初步满足对代码潜在性能问题的排查。

  • 在我的项目构建实现时发送邮件告诉给相干人。

内部部署

部门外部的软件最终都会销售并交付给相干客户,因为客户网络与公司网络不通以及代码窃密等要求,无奈在客户现场应用原有的 Jenkins 流水线进行部署交付。基于此部门采取折中计划:在公司外部通过 KubeSphere 进行编译打包,导出 Docker 镜像,拷贝到客户处而后基于 Docker 镜像部署运行, 具体请参见如下链接:

  • 在 Jenkins 中依据配置从不同的仓库中 Checkout 代码
  • 利用 shell 脚本实现将微服务程序以 docker 容器形式主动部署

应用帮助

在应用过程中的确遇到了不少问题,次要通过如下三条路径解决:

  • 浏览官网文档,依据文档阐明操作;
  • 若官网文档没有,则去用户论坛查看是否有人遇到相似问题或间接发帖;
  • 通过微信群寻求帮助。

依据部门应用教训,90% 的问题可通过官网文档或用户论坛取得答案。

应用成果

局部共事习惯于原始的手工操作或基于 Docker 部署,导致在推广过程中受到了肯定的阻力,部门外部基于充沛沟通和逐渐替换的形式疏导相干共事来缓缓适应。通过约一年的工夫磨合,大家都认可了拥抱云原生和 KubeSphere 给咱们带来的便当,应用过的共事都说很香!

对我司而言,有如下几个方面的晋升:

  • 研发人员简直不必消耗工夫在软件的部署和监控上,节俭约 20% 工夫,产品迭代速度更快;
  • 定制化的性能通过脚本实现,彻底杜绝了给客户交付软件时因为人工疏漏导致的偶发问题,在进步软件交付品质的同时也晋升了客户我司的认可度;
  • 软件开发、测试流程更标准,通过在 Jenkins 流水线强制增加各种标准检查和审核流程,实现了软件研发的标准对立,代码品质更高,更利于扩大保护,同时也在肯定程序上缩小了因为人员散失 / 变更对我的项目造成的影响;
  • 基于 KubeSphere 的云原生部署联合 Nacos 能够更疾速的调配多套环境,无效的实现了 开发 测试 生产 环境的隔离,在云仿真相干的业务场景中可基于业务场景更不便的对 pod 进行监控与调整,前瞻性的业务研发发展更顺利。

将来布局

联合公司与部门的理论状况,短期的布局仍然是欠缺基于 Jenkins 的 CI/CD 应用来欠缺打包与部署流程,部门外部在进行全面 web 化,基于此中长期拥抱云原生。

  • 接入企业微信,将构建与运行后果随时告诉相干人,构建后果与我的项目监控更实时;
  • 将部门外部基于 Eclipse RCP 的桌面应用程序通过 Jenkins 实现标准化与自动化的构建;
  • 将底层的 Kubernetes 从单机降级为集群,反对更多 pod 的部署,反对公司外部须要大量 pod 并发运行的云仿真我的项目;
  • 部门外部的 web 我的项目全副通过 KubeSphere 构建部署,欠缺其应用文档,开掘 KubeSphere 在部门业务中新的利用场景(如对设计文档、开发文档、bug 修复的定时与强制查看告诉等)。

本文由博客一文多发平台 OpenWrite 公布!

正文完
 0