当前位置:首页 >  科技 >  IT业界 >  正文

干货分享|如何利用KubeSphere,打通DevOps流水线

 2022-11-08 17:43  来源: 互联网   我来投稿 撤稿纠错

  【推荐】海外独服/站群服务器/高防

作者:赵海亮,浙江大学计算机专业四年级在读博士生,研究方向为云计算、边缘计算、分布式系统等。

虽然青云科技(qingcloud.com,股票代码:688316)推出的 KubeSphere 容器平台能够将我们从 yaml 文件的编写中解放出来,但是项目上云仍然十分繁琐。此外,一旦项目源代码发生更替(如发布新功能或去除 bug 等),所有组件都需要重新经历“源码打包 --> 制作镜像 --> 启动容器” 这个流程。这意味着,项目运维人员不得不从事大量重复性劳动。为了提高项目发布的效率,工业界引入了 DevOps 的概念。

本文首先将介绍 DevOps 是什么,随后尝试利用 KubeSphere 集成的功能来实现 DevOps。

什么是 DevOps

目前绝大多数互联网公司将开发和系统管理划分成不同的部门。开发部门的驱动力通常是 “频繁交付新特性”,而运维部门则更关注 IT 服务的可靠性和 IT 成本投入的效率。两者目标的不匹配,因而存在鸿沟,从而减慢了 IT 交付业务价值的速度。为了解决这个问题,DevOps(Development 和 Operations 的组合词)被提出。DevOps 的目的是在企业内部搭建一个自动化 “软件交付” 和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。

实现 DevOps 通常需要多个软件和工具的密切配合。如图 1 所示,DevOps 将软件的交付流程依次划分为 Plan、Code、Build、Test、Release、Deploy、Operate 以及 Monitor 这些阶段。 当需求变更时,将会从 Monitor 重新平滑过渡至 Plan 阶段。每个阶段都有一系列的软件和工具可供选择。对于任意项目,我们只需要基于这些软件和工具搭建一条自动化流水线,再设置类似于 “一旦代码变更就自动执行” 这样的钩子函数,整个项目即可自动实现“持续集成 / 持续交付(CI/CD)”,这将大大减少重复劳动。

图 1 DevOps 技术栈

KubeSphere DevOps 基于 Kubernetes Jenkins Agent 实现。和传统的 Jenkins Controller-Agent 架构不同的是,在 KubeSphere 中,Jenkins Agent 可以动态扩缩容,从而降低 CI/CD 对集群资源的盲目占用。 KubeSphere 的 DevOps 用户指南参见 https://kubesphere.io/zh/docs/devops-user-guide/。 本文将依照该指南将一个开源项目上云。

基于 DevOps 的项目部署

项目介绍

本次实验要部署的项目叫做尚医通,这是一个基于 Spring-Boot 实现的预约挂号统一平台。 该项目一共包含三个子部分,分别为 yygh-parent、yygh-site 和 yygh-admin。 在架构上,该项目依赖的数据层中间件有 mysql、redis、mongodb 以及 rabbitmq,依赖的流量治理中间件有 sentinel 和 nacos。

接下来,我们约定项目根目录为 his,然后分别从开源地址 https://gitee.com/leifengyang/yygh-parent、https://gitee.com/leifengyang/yygh-site 和 https://gitee.com/leifengyang/yygh-admin 拉取源代码:

依次查看三个项目的文件布局:

对于本项目,我们需要部署如下内容:

以上 12 个待部署的子项目将以独立 Pod 的形式在集群中部署。 每一个子项目根目录需要具有一个 Dockerfile 文件以及一个名为 deploy 的文件夹。 前者是本子项目的镜像制作文件,后者是本子项目的资源清单文件 *.yaml(用于在集群中部署)。 以 service-cmn为例,其文件布局如下:

遵循上一篇文章使用 KubeSphere 部署 Ruoyi-Cloud · KS 实践 02[1] 中所述的部署流程,我们首先需要将中间件上云。然后,我们将三个项目以流水线的方式上云。

部署中间件

本项目所使用的中间件除了 Sentinel 和 MongoDB,其他均已在前文中部署。 接下里依次部署这两个中间件。

对于 Sentinel,我们直接使用雷丰阳已经制作好的镜像 leifengyang/sentinel:1.8.2,然后暴露一个 NodePort 类型的 Service,端口号为 32636。 访问 http://192.168.23.160:32636,以默认用户 sentinel 和默认密码 sentinel 登录,可以进入 Sentinel 控制台。 如果一切顺利,应该可以看到类似的页面:

图 2 访问 sentinel 暴露的 NodePort 类型的 Service

对于 MongoDB,我们直接通过应用模版部署它(不勾选登录认证):

图 3 Bitnami 官方镜像仓库提供的 MongoDB

为 MongoDB 应用暴露一个 NodePort 类型的 Service,端口号为 31801,然后在本机通过 MongoDB Compass 连接它(192.168.23.160:31801):

图 4 使用 MongoDB Compass 连接 MongoDB 实例

如果可以连上,则一切正常。

导入初始数据

使用 DataGrip 将位于 his/yygh-parent/data/sql 目录下的全部演示数据(一共有 5 个 sql 文件需要执行,会创建 5 个 yygh 打头的数据库)导入集群中的 MySQL 实例:

图 5 导入数据至集群 MySQL 实例中

MongoDB 的演示数据将在项目启动后导入。

在 Nacos 中创建微服务的启动配置

观察每一个子项目的 Dockerfile,以 service-cmn 为例:

这意味着该子项目在启动时,会激活 prod 环境,并从 Nacos 中读取 service-cmn-prod.yml 文件作为启动配置。 因此,我们首先需要在 Nacos 中创建其生产环境配置文件 service-cmn-prod.yml,然后将 子项目路径 / src/main/resources/application-dev.yml 的内容复制进去,在其基础上修改。 需要修改的内容主要是中间件的访问地址。 以 service-cmn 为例,它的配置文件被命名为 service-cmn-prod.yml,其最终内容如下:

如图 6 所示,除了 hospitla-manage,其余所有 9 个 Spring-Boot 子项目均需要按照上述规则编写对应的配置文件。 hospitla-manage 的启动不依赖 Nacos,因此不需要。

图 6 所有微服务的配置均已在 Nacos 中添加

创建微服务部署流水线

流水线表示应用从代码编译、测试、打包和部署的过程,KubeSphere 的流水线管理使用了业界常用的 Jenkinsfile 来表述一组 CI/CD 流程。 Jenkinsfile 是一个文本文件,使用了 Jenkins 提供的 DSL(Domain-Specific Language)语法。 KubeSphere 提供了可视化编辑器,用户只需在页面上输入少量配置信息,接口自动组装完成 Jenkinsfile。 当然,也可直接编辑 Jenkinsfile。

流水线涉及如下几个概念:

Stage:阶段,一个 Pipeline 可以划分为若干个 Stage,每个 Stage 代表一组操作。Stage 是一个逻辑分组的概念,可以跨多个 Node。

Node:节点,一个 Node 就是一个 Jenkins 节点,或者是 Master,或者是 Agent,是执行 Step 的具体运行时环境。

Step:步骤,Step 是最基本的操作单元,小到创建一个目录,大到构建一个 Docker 镜像,由各类 Jenkins Plugin 提供。

KubeSphere 默认提供的 Agent 有 base、go、maven 和 nodejs。它们分别适用于不同编程语言开发的项目的打包构建。 因为我们即将部署的 10 个子项目均是 Spring-Boot 应用,因此我们选择 maven 作为启动流水线的 agent。

我们可以直接编写流水线的 Jenkinsfile,也可以通过 KubeSphere 提供的可视化页面编辑流水线。 通常,流水线的第一步是下载项目源代码 4[2],我们在 UI 上直接添加相关命令:

图 7 基于 UI 编辑流水线第一步:源码拉取

KubeSphere 会自动生成这次编辑的 Jenkinsfile 代码片段:

流水线的第二个阶段通常是项目的打包与编译。 默认情况下,Maven 从官方仓库下载项目依赖,如果想要修改默认镜像仓库,需要修改集群中名为 ks-devops-agent 的 ConfigMap,它拥有一个叫做 MavenSetting 的键:

我们需要修改 MavenSetting 文件,在其中添加国内镜像仓库地址:

图 8 为 Maven 添加国内镜像仓库地址

我们通过命令 mvn clean package -Dmaven.test.skip=true 进行项目打包编译。由此,流水线的第二阶段需要执行的命令如下:

图 9 流水线的第二步:项目打包与编译

相应地,在 Jenkinsfile 中也会自动生成第二步的代码:

流水线的第三个阶段是制作镜像。我们在章节 2.1 说过,每个子项目的根目录有一个 Dockerfile,并且在章节 2.4 展示过 Dockerfile 的内容。 因此,对于单体应用 hospitla-manage,它的镜像构建命令为 docker build -t hospital-manage -f hospital-manage/Dockerfile hospital-manage/;对于网 关子项目 server-gateway,它的镜像构建命令为 docker build -t server-gateway/Dockerfile server-gateway/;其余 8 个微服务的构建命令则是 docker build -t service/service-xxx service/service-xxx/。这里的 xxx 被替换为具体的微服务名称。 在上述构建命令中,尤其需要注意的是 Dockerfile 相对于项目根目录 yygh-parent 所在的位置以及镜像构建上下文的相对位置。

因为上述 10 个镜像的构建相互之间独立,因此可以并行化执行。我们可以很轻易地在 KubeSphere 中做到这一点:

图 10 流水线的第三步:并行化镜像制作

相应地,Jenkinsfile 中增加了如下内容:

流水线的第四个阶段是镜像推送。在企业内部,构建好的镜像通常会被推送到企业的私有仓库中。笔者采用阿里云给个人开发者免费提供的镜像仓库作为推送目标。因为目标仓库是一个私有仓库,因此需要提供账户和密码作为凭证(credential)。如何在 KubeSphere 中为镜像推送命令提供凭证呢? 我们可以在 DevOps 的项目设置中创建:

图 11 在 DevOps 的项目设置中创建凭证

上图中,笔者创建一个名为 aliyun-docker-hub 的凭证,用户名是我的阿里云账户名,密码则是申请容器镜像服务所创建的密码。 读者需要替换成自己的账户密码:

图 12 为流水线创建凭证 aliyun-docker-hub

基于该凭证,我们在 Jenkinsfile 中编写镜像推送的代码如下:

同样地,上述过程也以并行的方式执行。最终,Jenkinsfile 中被添加了如下代码:

测试一下到目前为止的流水线,一切运行顺利:

图 13 测试流水线

流水线的最后阶段是部署到开发环境和生产环境。因为这一阶段需要和 Kubernetes API Server 打交道,所以需要指定 Kubernetes 上下文 5[3]。 KubeSphere 自动为我们创建了名为 demo-kubeconfig 的凭证,该凭证提供了形如 .kube/config 的文件,使得我们可以根据凭证发起 kubectl apply 命令。 与此同时,我们还需要指定待部署的资源清单文件的位置。 以子项目 hospital-manage 为例,它的资源清单文件在 yygh-parent/hospital-manage/deploy/ 目录下。 观察该目录下的 deploy.yaml 文件,可以发现它要求集群从阿里云私有镜像仓库拉取镜像,需要我们提供 imagePullSecrets 字段:

图 14 从阿里云私有镜像仓库拉取镜像

这意味着我们需要在 his 项目中创建名为 aliyun-docker-hub 的 Secret。 注意,这里是在为 his 项目创建 Secret,而先前是在 DevOps 的项目设置中创建 Credential。二者的服务对象是不同的。 对于部署这个操作,我们可以直接在 UI 上选择 “添加 kubernetesDeploy”:

图 15 在流水线中添加 kubernetesDeploy 这一步骤

由此生成的 Jenkinsfile 代码为

我们尝试运行一下现在的流水线,诡异的事情却发生了。在项目部署阶段产生了如下错误:

观察报错内容,似乎是负责执行流水线的 Jenkins Agent 版本太老所导致的。 经过查阅,笔者发现 KubeSphere 的官方维护人员已经提交了相关 issue(https://github.com/kubesphere/website/issues/2096)来说明此事。根据说明,报错的根源在于 Jenkins 的官方插件 kubernetes-cd-plugin[4] “年久失修”,我所安装的 Kubernetes 的 API 版本是 v1.22,而 Jenkins 的 kubernetes-cd-plugin 却已经停摆两年。 对于这个问题,KubeSphere 官方提供的解决方案是以 shell 命令 kubectl apply -f your-crd-file.yaml 的方式进行部署,而非在 UI 上添加 kubernetesDeploy。

幸运的是,在笔者撰写此文的 40 分钟前,KubeSphere 官方发起了一个针对此问题的临时解决方案:https://github.com/kubesphere/website/pull/2098。 在该 Pull request 中,贡献者提供了一种提供 kubeconfig 验证的写法:

实验证明,该方法有效。同样地,10 个子项目可以并行化部署到 dev 环境。相应的 Jenkins 代码就不再展示了。 部署到 prod 环境的操作类似。此外,还可以添加部署条件,例如,只有获得相关管理员授权之后部署操作才会启动。

创建前端项目部署流水线

接下来,还剩两个前端项目 yygh-site 和 yygh-admin 需要部署。 前端项目的部署服从相似的步骤:首先下载源码,然后需要通过 Node.js 之类的工具为项目安装依赖并构建(产生 dist 目录),最后是镜像构建、推送和部署。 以 yygh-site 为例,它最终的 Jenkinsfile 如下所示:

此处不再展示更多细节。

总结

KubeSphere 为我们提供了 Jenkins 流水线的编辑页面,在一定程度上可以简化操作。

申请创业报道,分享创业好点子。点击此处,共同探讨创业新机遇!

相关标签
云服务

相关文章

  • 对象储存有哪些用处?

    对象存储是一个非常灵活的解决方案,适用于多种数据存储场景。对象存储用处如下:云存储:对象存储在云环境中广泛应用。它能够提供可靠,可扩展和经济高效的数据存储解决方案。大数据存储:对象存储适用于管理结构化和非结构化数据的大型数据集。它可以存储大量数据,并提供快速访问和分析选项。影像存储:对象存储是处理图

    标签:
    云服务
  • 强强联合!百望云入驻微软实验室,揭开数智发展新篇章!

    OpenAI是什么,随着ChatGPT的爆火,相信大家都并不陌生了。而微软也第一时间推出了AzureOpenAI加速计划,希望凭借OpenAI的卓越能力,为企业赋能,帮助越来越多的企业将AI大模型的基础能力,与企业场景相结合,开拓新的商业范式,引领行业变革。近日,以“智领新变共创未来”为主题的“微软

    标签:
    云服务
  • 新成果、新服务、新生态,HPE混合云领导者地位再提升!

    HPE扩大混合云和私有云产品的覆盖范围、灵活选项和创新功能,领导者地位再提升!HPEDiscover科技盛会上,HPE宣布了HPEGreenLake边缘到云平台、混合云服务、私有云产品组合的创新成果,以及合作伙伴生态系统的最新进展:·HPE完成对OpsRamp公司的收购;相关解决方案现已作为HPEG

    标签:
    云服务
  • 权威发布!白山云连续入选IDC边缘云报告

    近日,国际权威研究机构IDC发布《中国边缘云市场跟踪研究,2022H2》报告。作为创新的全球边缘云服务提供商,白山云得到IDC的持续关注与认可,凭借在边缘云领域的技术突破、产品迭代以及场景实践,再度入选报告,与行业伙伴一同撑起边缘云市场的巨大价值空间。IDC指出,在服务商与客户需求的共同推动下,边缘

    标签:
    云服务
  • 带来高校混合云建设方案,青云科技满足教育、教学、教管等场景需求

    随着教育信息化2.0进程加快,教育部等六部门提出“推进教育新型基础设施建设,构建高质量教育支撑体系”,建设智慧校园成为各大高校重点布局方向。但因为传统竖井式建设模式,导致高校信息系统庞大,现有信息化程度较低,IT资源碎片化,资源统一管控难度大等一系列问题,使得智慧校园建设步履维艰,各大高校亟需找到突

    标签:
    云服务

热门排行

信息推荐