# Jenkins CI/CD ## 前言 本文档介绍如何快速通过K8s集群实现Jenkins 动态Slave CI/CD流程。 ## 开始之前 在开始之前需要准备以下环境: - k8s dns组件 参考文档:[kubedns](kubedns.md) - helm 为了简化部署,通过helm来安装Jenkins,可参考文档:[helm](helm.md) - 持久化存储 这里使用**NFS**演示,参考文档:[cluster-storage](../setup/08-cluster-storage.md)。 如果k8s集群是部署在公有云,也可使用厂商的NAS等存储方案,项目中已集成支持阿里云NAS,其他的方案参考相关厂商文档 - Ingress Controller(nginx-ingress/traefik) 默认是通过Ingress访问Jenkins,因此需要安装一种`Ingress Controller`。参考文档:[ingress](ingress.md) - Gitlab 代码管理仓库 用于提交代码后自动触发CI, 目前项目中还没有相关内容,可[参考官网](https://about.gitlab.com/installation/)进行安装。 ## 安装Jenkins 执行以下命令快速安装: ``` helm install manifests/jenkins/ --name jenkins ``` 如果通过/etc/ansible/roles/helm/helm.yml安装的helm,安装过程会出现如下错误 ``` bash E0703 08:40:22.376225 19888 portforward.go:331] an error occurred forwarding 41655 -> 44134: error forwarding port 44134 to pod 5098414beaaa07140a4ba3240690b1ce989ece01e5db33db65eec83bd64bdedf, uid : exit status 1: 2018/07/03 08:40:22 socat[19991] E write(5, 0x1aec120, 3424): Connection reset by peer Error: transport is closing ``` 请执行以下命令快速安装进行修复: ``` helm install --tls manifests/jenkins/ --name jenkins ``` 由于初始化过程中,默认安装指定的插件,所以启动较慢,大概5-10分钟左右就可以启动完成了。 部分默认配置说明: **注**:以下配置都定义在`manifests/jenkins/values.yaml`文件中。
字段 说明 默认值
InstallPlugins 初始化安装的插件
  • kubernetes:1.6.3
  • workflow-aggregator:2.5
  • workflow-job:2.21
  • credentials-binding:1.16
  • git:3.9.0
  • gitlab:1.5.6
HostName Ingress访问入口 jenkins.local.com
AdminPassword admin登录密码 admin
UpdateCenter 插件下载镜像地址 https://mirrors.tuna.tsinghua.edu.cn/jenkins
StorageClass 持久化存储SC nfs-dynamic-class
## 配置Kubernetes plugin 登录Jenkins,点击左边导航`系统管理`——>`系统设置`,拖动到最下面可以看到`云——>Kubernetes`配置,默认配置有以下字段: - Name:配置名称,后面运行测试的时候会用到,用于区别多个Kubernetes配置,默认为:kubernetes - Kubernetes URL:集群访问url,可通过`kubectl cluster-info`查看,如果集群有部署**DNS**插件, 也可以直接填服务名称(自动解析),默认使用服务名称:https://kubernetes - Jenkins URL:Jenkins访问地址,默认使用服务名称+端口号 在Jenkins初始化时,默认都已经配置好了,可以直接新建项目测试了。 ## 简单测试 点击左边:新建任务——>流水线(Pipeline) 任务名称可以随便起,这里为:k8s-test 配置——>流水线,选择`Pipeline script` 以下为测试脚本内容: ``` podTemplate(label: 'jenkins-slave', cloud: 'kubernetes') { node ('jenkins-slave') { stage('test') { echo "hello, world" sleep 60 } } } ``` - cloud:插件配置中的Name - label:插件配置中的Images——>Kubernetes Pod Tempalte——>Labels - node:与label一致即可 保存配置,点击立即构建,查看控制台输出,出现以下内容就表示运行成功了: ``` Agent default-lsths is provisioned from template Kubernetes Pod Template Agent specification [Kubernetes Pod Template] (jenkins-slave): * [jnlp] jenkins/jnlp-slave:alpine(resourceRequestCpu: 200m, resourceRequestMemory: 256Mi, resourceLimitCpu: 200m, resourceLimitMemory: 256Mi) Running on default-lsths in /home/jenkins/workspace/k8s-test [Pipeline] { [Pipeline] stage [Pipeline] { (test) [Pipeline] echo hello, world [Pipeline] sleep Sleeping for 1 min 0 sec [Pipeline] } [Pipeline] // stage [Pipeline] } [Pipeline] // node [Pipeline] } [Pipeline] // podTemplate [Pipeline] End of Pipeline Finished: SUCCESS ``` ## 配置自动触发CI - 配置Gitlab项目 在`Gitlab`中创建一个测试项目,将上面测试的脚本内容写入到一个`Jenkinsfile`文件中,然后上传到该测试项目根路径下。 - 配置Jenkins项目 点击项目`配置`——>`构建触发器`——>勾选`Build when a change is pushed to GitLab. GitLab webhook URL:http://jenkins.local.com/project/k8s-test`——>保存配置 - 配置Webhook 进入Gitlab测试项目的`Settings——>Integrations`,一般只需要填写`URL`即可,其他的可根据需求环境配置 默认Jenkins配置不允许匿名用户触发构建,因此还需要添加用户和token。 URL的格式为: `http://[UserID]:[API Token]@jenkins.local.com/project/[ProjectName]` Jenkins 用户ID Token查看: 点击右上角的`用户名——>设置——>API Token(点击Show API Token...)` 最终Webhook中的URL类似: http://admin:a910b1492e39e9dd1ea48ea7f7638aaf@jenkins.local.com/project/k8s-test 后面只需要我们一提交代码到Git仓库,就会自动触发Jenkins进行构建了。 ## 项目应用 这里我们以一个简单的Java项目为例,实战演示如何进行CI/CD。 基本环境配置上面已经说过了,这里就不多介绍。 示例项目:https://github.com/lusyoe/springboot-k8s-example 结构说明: - 镜像构建文件:`Dockerfile` - k8s应用配置:`k8s-example.yaml` - 项目源码:`src` - Jenkins构建文件:`jenkins/Jenkinsfile` 构建流程说明: - 通过Jenkins kubernetes插件,定义构建过程中所需的3个docker容器:maven、docker、kubectl (这3个容器都在一个pod中) - 挂载docker.sock和kubeconfig文件 - 首先使用`maven`容器,检出代码,执行项目构建 - 使用`docker`容器,构建镜像,推送到镜像参考 - 使用`kubectl`容器,部署`k8s-example`应用(这里后面也可以使用helm) 访问: 项目通过Ingress访问`k8s-example.com`,出现`hello, world`,就表示服务部署成功了。