理解和应用持续集成(GitHub Action和Jenkins)
通过实际例子演示如果配置Github Action和在k8s集群上安装配置Jenkins
实现持续集成和部署的工具很多,此篇博客主要介绍如何利用GitAction来完成构建和在k8s集群下安装和使用jenkins来完成job运行。利用GitHub的action来完成构建有如下优势:
低成本:GitHub目前为项目提供免费的构建流水线,可满足日常构建需求。
免运维:无需自己构建流水线,GitHub提供小量构建请求。
易构建:GitHub action非常容易构建,另外提供了一系列内建的action,社区还有大量可复用的action。
易集成:无需配置GitHub webHook即可完成与PR联动。
接下来就看看如何在github上创建action来完成持续构建,如下图所示,在创建workflow时,可以选择已有的模版,也可以完全自定义,这里选择go模版,因为源代码是用go语言编写,右边是具体的workflows中的yml文件定义,可以看到文件中定义了在push代码和提交pr时会触发该job,job中定义了三个step,
step1:checkout代码
step2:setup构建环境(即安装go build的环境)
step3:执行go build命令完成构建。
完成配置后,在github上提交commit或者pr,可以看到触发了action,如下图所示
点击进入action,还可以看到每个步骤的执行日志信息,如下图所示
上面只是演示了简单的构建过程,更多关于github action的语法定义可以参考官网资料。接下来看看如何在k8s集群中使用jenkins完成构建。下图是在k8s集群下通过jenkins完成job执行的过程图
下面通过实际例子演示来看看如何在k8s上安装和配置jenkins,完成job执行。
k8s上安装jenkins,如果要安装jenkins只需如下yaml文件,创建StatefulSet和Service即可,Service类型是NodePort,这样可以在外网访问创建在集群上的jenkins。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: jenkins
spec:
selector:
matchLabels:
name: jenkins
serviceName: jenkins
replicas: 1
template:
metadata:
name: jenkins
labels:
name: jenkins
spec:
terminationGracePeriodSeconds: 10
serviceAccountName: jenkins
containers:
- name: jenkins
image: jenkins/jenkins:lts-alpine
ports:
- containerPort: 8080
- containerPort: 50000
---
apiVersion: v1
kind: Service
metadata:
name: jenkins
spec:
selector:
name: jenkins
ports:
- name: http
port: 80
targetPort: 8080
protocol: TCP
- name: agent
port: 50000
protocol: TCP
type: NodePort
除了安装jenkins的直接yaml文件外,还需要定义个SA,以及给SA设置role和roleBinding,创建SA在后续配置jenkins时会用到,具体的yaml文件内容如下所示
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: jenkins
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get","list","watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["watch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: jenkins
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jenkins
subjects:
- kind: ServiceAccount
name: jenkins
通过kubectl create -f xx.yaml文件完成安装后,即可通过节点IP+servicePort在外网访问jenkins。首次访问需要输入登录密码,登陆的密码可以通过查询jenkin的pod日志获取 (kubectl logs jenkinspod)。
登陆成功后,首先需要安装jenkins的插件,这里选择安装插件后不重启服务,因为重启后,安装的插件会消失,又需要重新安装。
插件安装完成后,配置Cloud Provider
菜单Manage Jenkins->Manage Node and Cloud->Configure Cloud
- Add a new cloud:Kubernetes
- Kubernetes URL:https://kubernetes.default
- Kubernetes Namespace:填写安装jenkins时的namespace
- Credentials:Add->Jenkins->Kind:Kubernetes Service Account,之前为jenkins创建了service account和分配了权限,所以这里选择Kubernetes Service Account
配置完成后,点击Test Connnection,如果连接成功,说明安装、插件安装、配置都正确。可以看到下图连接成功
接着配置PodTemplate配置,添加PodTemplate
- name:jnlp-slave
- Label:jnlp-slave
- Add Container
Name:jnlp
Image:jenkins/inbound-agent
Argumentes to pass the command:${computer.jnlpmac}${computer.name}。
完成配置后,创建一个freestyle的project,这里输入的Label是jnlp-slave,主要不要有空格,输入后下面应该会显示macth到了一个cloud node的信息才行。另外,job的build步骤配置简单的echo test命令即可。
完成job配置后,运行job,可以看到启动了jenkins-slave,实际此时在k8s集群上新启动了一个pod,pod中拉取的image就是podTemplate中配置的image,这个pod启动起来就是为了执行job中的构建命令。
实际实验室,jenkins-slave在启动后总是被kill掉,查看了下pod日志,显示JNLP4-connect refused。这里使用的集群是aws上的eks集群,具体什么原因导致JNLP4-connect连接失败,没有继续调查,但这不影响对jenkins的理解。
可以看到真正执行job的是jenkins-slave,上面的配置中构建命令只是简单的echo test。在实际项目中构建命令肯定是真正的对应用进行打包,例如go的应用,应该执行go build命令。那么在配置podTemplate时,需要提前制备jenkins-slave的image,即包含go build环境的镜像,否则启动的slave pod无法执行go build命令。如果是java或者其他技术栈应用,道理相同,即需要制备构建所需的环境镜像。
另外,如果在构建过程中需要执行docker命令,即在启动的pod中需要从源代码中生成镜像文件,就需要实现docker in docker。关于docker in docker有两种解决方案:
方案一:在启动的容器中是没有docker.socket的,而如果想执行docker命令,需要用到docker.socket.所以可以吧host的docker.socket mount到容器内。
方案二:引入Kaniko,Kaniko是google提供了解决docker in docker问题的一个工具,Kaniko运行用户在container或者Kubernetes cluster上通过Dockerfile构建image,并将生成的镜像推送到镜像仓库。Kaniko底层不依赖Docker daemon,Kaniko自己编写了executer,这个executer负责将Dockerfile构建成镜像。关于Kaniko的详细信息可查看官网资料。
另外,实际项目中除了安装jenkins外,还需要创建PVC,保证jenkins master pod出错时,新的kubernetes pod可以mount同样的工作目录,保证配置不丢失。
更多推荐
所有评论(0)