Jenkins 配合 Kubernetes 实现服务持续集成的实践和建议

2020-04-22 17:03:16 浏览数 (1)

Kubernetes 本身是一个以服务扩容见长的容器编排系统,如果不能跟其它 CI/CD 工具结合起来,从根本上说还是不能提升开发部署效率,达到持续集成,持续交付的目的,本文以 Jenkins 配合 Kubernetes 完成 Java 服务持续集成和部署过程碰到一些问题,进行说明和总结。


是否需要把 Jenkins 集成 Kubernetes 集群中进行统一管理?

当你在网上搜索 Jenkins 持续集成 dockers/kubernetes 时,80% 答案是在Kubernetes集群中容器化 Jenkins,在我看来,对于业务服务数量有限的互联网公司,前期的话,不是特别建议把Jenkins直接安装到kubernetes集群当中,特别是在没有使用 Kubernetes 容器云平台之前已经有了自动化构建工具,有以下原因:

首先早阶段开发、测试、生产环境已经部署了Jenkins,已经习惯了这种使用方式,Jenkins本身呢,只是执行一些命令,本身不会耗费太多资源,不需要多个副本和横向扩展的能力,把需要持续交付的服务实现容器化再说吧。

再者如果你把 Jenkins 放到 Kubernetes 集群中执行,你需要把 Jenkins 打成镜像,放到 Pod 中执行,而一般情况下根据镜像的最小化原则,镜像里面不会包含 docker 组件,所以如果你在宿主机上打包可以正常执行,而放到Pod 中可能会出现无法 docker build ,当然这也是可以解决的,因为 docker 本身是 B/S 架构,你可以通过在镜像内部挂载 docker 命令,调用宿主机 docker socket 端口;更简单方法,直接远程到一台包含 docker 基础服务的服务器上执行,但无论如何,你可能都要折腾一下,改变现有使用方式。


Jenkins如何搭配 Kubernetes 实现持续集成?

整体流程如下图所示:

简单分为五个过程

1、需求原型开发完成,开发人员介入开发;

2、开发人员将代码提交到代码仓库 git/SVN;

3、钩子触发 jenkins master 启动一次构建,或者开发人员自行点击构建,根据情况自行选择,jenkins 拉取代码、maven 编译;

这里假设你已经完成 Jenkins 安装、远程工具、java 编译环境配置等。如果没有配置,网上找找,资料特别多。这部分其实相对来说和之前使用Jenkins 的方式区别不大,如果你使用 git,这里还是 git 拉取代码,之前是 maven/ant 进行打包,那么这里还是 maven/ant 进行打包。

4、docker 镜像构建、镜像提交到仓库;

docker 镜像在构建需要区别与以前的形式,如果你已经在 Jenkins 上安装了 docker 插件,直接在当前机器构建即可,如果没,也没问题,远程 SSH 到一台能够构建 docker 镜像的服务器进行镜像打包。

代码语言:javascript复制
docker build -t docker.hub.com/dev/tomcat-webapps:$version .
docker push docker.hub.om/dev/tomcat-webapps:$version

打包过程需要注意两点

  • 第一点,docker 构建镜像需要 tag ,这个 tag 可以通过 Jenkins 参数化构建,在构建之前输入版本号,如果没有输入,填写默认值即可。
  • 第二点、历史镜像如何处理?比较建议每次镜像构建完成之后,通过  Jenkins 配置命令删除没有运行的镜像。 具体根据使用场景处理这些中间产物。
代码语言:javascript复制
docker rm $(docker ps -a -q)

5、Kubernetes yaml 运行过程到仓库拉取 docker 镜像构建产物,从而启动整个服务,测试人员开始全方位功能、性能测试。

代码语言:javascript复制
kubectl apply -f config.yaml
sed -i 's/image-replace-webapps/tomcat-webapps:${version}/'  tomcat_deployment.yaml;
kubectl apply  -f  tomcat_deployment.yaml

「麻雀虽小五脏俱全」一个项目功能不多,但是少不了 configmap、deployment、甚至 service,Jenkins 在打包过程肯定要涉及到对这些文件的修改,问题来了,这些文件如何存放呢?

如果你有强大的 helm 包管理工具,当然可以解决这些问题;如果你的项目没有大到使用 helm 进行文件管理,可以考虑把 yaml 配置直接放到源代码某个目录下面,利用 SVN/GIT 进行管理,也可以直接放到服务器某个路径下面,Jenkins 每次构建时 SSH 到这台服务器进行备份、修改运行 yaml 文件。

3、在构建过程中需要注意问题

docker 每次镜像构建 tag 不一样,如何传递到 k8s yaml中?

docker 镜像构建过程中通过参数化构建已经可以修改版本号,同样的,首先在 k8s 编排文件镜像部分添加能够已知占位符;

然后把这个版本号动态传递并替换到 k8s yaml 中;

代码语言:javascript复制
sed -i 's/image-replace-webapps/tomcat-webapps:${version}/'  tomcat_deployment.yaml;

在现实使用场景中,可能会存在多个Kubernetes环境,如何处理?

这时可以根据情况进行处理,比如线上环境和开发测试环境镜像仓库、集群环境、Jenkins都是严格隔离的,那就可以等到开发测试完成之后把上述流程重新走一遍。如果使用同一个 Jenkins 通过不同的用户权限构建到不同环境也是类似道理。其实看你怎么用,因为镜像已经集中存储到仓库,正式线上环境直接拿着 yaml 就可以跑起来,比以前上传 war 更清爽。

4、总结

本文主要以 Jenkins 为中心介绍了持续集成Kubernetes 过程,Jenkins本身是持续集成,持续交付工具链过程非常重要的一个部分,它是开源的并且提供了大量可用的插件,入门使用非常简单,但是真正掌握好 Jenkins 使用并不是一件轻松的事情,如何使用 Jenkins 创建出高效稳定、灵活的流水线是所有从事 DevOps 开发人员所亟待解决的问题。

0 人点赞