Jenkins搭建入门

Jenkins是一款开源、强大的持续集成工具,其前身是Hudson(商用软件)。

本节将介绍Jenkins的搭建。从架构上理解,Jenklins由两类角色组成:

  • Controller:主控节点,负责管理、配置工作,也称作Master节点。

  • Agent:执行具体作业的工作节点,也称作Slave节点,或者Executor节点。

严格来说,Master节点也可以执行具体作业,但是处于安全性考虑,不建议这样做。

Jeknins的启动与初始配置

首先启动Controller节点:

  1. #!/bin/bash
  2. NAME="jenkins"
  3. PUID="1000"
  4. PGID="1000"
  5. VOLUME="$HOME/docker_data/jenkins"
  6. mkdir -p $VOLUME
  7. docker ps -q -a --filter "name=$NAME" | xargs -I {} docker rm -f {}
  8. docker run \
  9. --hostname $NAME \
  10. --name $NAME \
  11. -v $VOLUME:/var/jenkins_home \
  12. -p 8080:8080 \
  13. -p 50000:50000 \
  14. --detach \
  15. --restart always \
  16. jenkins/jenkins:lts-jdk11

如上所示,我们启动了jenkins的主控节点,并对外暴露了8080、5000两个端口。

我们在浏览器中打开如下链接:http://127.0.0.1:8080/

f

第一次启动会进行初始化,要求输入密码,我们使用如下命令查看:

  1. docker logs -f jenkins
  2. ....
  3. *************************************************************
  4. *************************************************************
  5. *************************************************************
  6. Jenkins initial setup is required. An admin user has been created and a password generated.
  7. Please use the following password to proceed to installation:
  8. 9169c97282d64545b36bc96cf7c1aaab
  9. This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
  10. *************************************************************
  11. *************************************************************
  12. *************************************************************
  13. 2021-11-04 03:15:53.502+0000 [id=49] INFO h.m.DownloadService$Downloadable#load: Obtained the updated data file for hudson.tasks.Maven.MavenInstaller
  14. 2021-11-04 03:15:53.502+0000 [id=49] INFO hudson.util.Retrier#start: Performed the action check updates server successfully at the attempt #1
  15. 2021-11-04 03:15:53.517+0000 [id=49] INFO hudson.model.AsyncPeriodicWork#lambda$doRun$0: Finished Download metadata. 36,815 ms码

如上中间部分,即初始密码。

输入初始密码后,会要求安装创建,建议至少安装下述插件:

  • Gradle:用于Java项目的打包和编译

  • Pipeline:用户开发流水线作业

  • Git:用于代码拉取

  • SSH Build Agents

  • Kubernetes:用于在Kubernetes集群上启动Slave节点

  • Kubernetes CLI:用于执行远程Kubernetes的二进制文件

安装完插件后,需要创建初始管理员账号。

Jeknins的Agent节点配置

启动Controller节点后,我们着手配置Slave节点,这里也有多种选项:

  • 启动固定数量的Slave节点

  • 按需启动,用完释放

  • 上述两种方案的混合

考虑到并发性、资源利用率,我们选用方案2:在Kubernetes集群上,按需启动Slave容器,执行完毕后销毁。

首先,我们需要登录到Kubernetes集群的Master节点上,查看已有的证书信息。

  1. cd ~/.kube/config
  2. apiVersion: v1
  3. clusters:
  4. - cluster:
  5. certificate-authority: /Users/coder4/.minikube/ca.crt
  6. extensions:
  7. - extension:
  8. last-update: Thu, 04 Nov 2021 11:23:17 CST
  9. provider: minikube.sigs.k8s.io
  10. version: v1.22.0
  11. name: cluster_info
  12. server: https://127.0.0.1:52058
  13. name: minikube
  14. contexts:
  15. - context:
  16. cluster: minikube
  17. extensions:
  18. - extension:
  19. last-update: Thu, 04 Nov 2021 11:23:17 CST
  20. provider: minikube.sigs.k8s.io
  21. version: v1.22.0
  22. name: context_info
  23. namespace: default
  24. user: minikube
  25. name: minikube
  26. current-context: minikube
  27. kind: Config
  28. preferences: {}
  29. users:
  30. - name: minikube
  31. user:
  32. client-certificate: /Users/coder4/.minikube/profiles/minikube/client.crt
  33. client-key: /Users/coder4/.minikube/profiles/minikube/client.key

如上,共包含了3个证书/密钥:ca.crt、client.crt、client.key。

我们使用他们创建新的凭据,供Jenkins使用:

  1. openssl pkcs12 -export -out ./kube-jenkins.pfx -inkey ./client.key -in ./client.crt -certfile ./ca.crt

上述创建过程会要求输入密码,请记牢后续会用到。

此外,上述文件中的ca.crt后面会再次用到。

在Jenkins上配置Kubernetes集群之前,我们假设以下信息:

由于我当前使用的minikube,不难发现,minikube的api server只在本地开了端口,并没有监听到物理机上,因此网段是不通的,所以我们先使用socat进行端口映射。

  1. socat TCP4-LISTEN:6443,fork TCP4:127.0.0.1:52058

如上,经过映射后,所有打到本机的公网IP(10.1.172.136)、端口6443上的流量,会被自动转发到52058上。

接下来,我们着手在Jenkins上添加Kubernetes的集群配置。

Manage Jenkins -> Manage Nodes and Clouds -> Configure Clouds -> Add a new cloud -> Kubernetes

截图如下:

f

其中核心配置如下:

  • 名称:自选必填,这里选了kubernetes

  • Kuberenetes地址:https://10.1.172.136:6443

  • Kubernetes 服务证书 key:输入上文中ca.crt中的信息,注意换行问题。

  • 凭据:上传上述生成的kube-jenkins.pfx,同时输入密码

  • Jenkins地址:http://10.1.172.136:8080

上述天禧后,点击”连接测试”,如果一切正常,你会发现如下报错:

f

这是因为我们经过转发后,host与证书中的并不匹配。

我们修改下Jenkins的docker启动脚本,添加hosts参数:

  1. --add-host kubernetes:10.1.172.136

重启Jenkins后,将上述位置的”Kuberenetes地址”修改为”https://kubernetes:6443",再次重试连接,一切会成功。

记得保存所有配置。

测试任务

我们配置一个测试任务:

新建任务 -> 流水线

代码如下:

  1. podTemplate {
  2. node(POD_LABEL) {
  3. stage('Run shell') {
  4. sh 'echo hello world'
  5. }
  6. }
  7. }

保存后,点击”立即构建”,运行结果如下:

  1. Started by user admin
  2. [Pipeline] Start of Pipeline
  3. [Pipeline] podTemplate
  4. [Pipeline] {
  5. [Pipeline] node
  6. Created Pod: kubernetes default/test-4-xsc01-4292c-4rkrz
  7. [Normal][default/test-4-xsc01-4292c-4rkrz][Scheduled] Successfully assigned default/test-4-xsc01-4292c-4rkrz to minikube
  8. [Normal][default/test-4-xsc01-4292c-4rkrz][Pulled] Container image "jenkins/inbound-agent:4.3-4-jdk11" already present on machine
  9. [Normal][default/test-4-xsc01-4292c-4rkrz][Created] Created container jnlp
  10. [Normal][default/test-4-xsc01-4292c-4rkrz][Started] Started container jnlp
  11. Agent test-4-xsc01-4292c-4rkrz is provisioned from template test_4-xsc01-4292c
  12. ---
  13. apiVersion: "v1"
  14. kind: "Pod"
  15. metadata:
  16. annotations:
  17. buildUrl: "http://10.1.172.136:8080/job/test/4/"
  18. runUrl: "job/test/4/"
  19. labels:
  20. jenkins: "slave"
  21. jenkins/label-digest: "802a637918cdcb746f1931e3fa50c8f991b59203"
  22. jenkins/label: "test_4-xsc01"
  23. name: "test-4-xsc01-4292c-4rkrz"
  24. spec:
  25. containers:
  26. - env:
  27. - name: "JENKINS_SECRET"
  28. value: "********"
  29. - name: "JENKINS_AGENT_NAME"
  30. value: "test-4-xsc01-4292c-4rkrz"
  31. - name: "JENKINS_NAME"
  32. value: "test-4-xsc01-4292c-4rkrz"
  33. - name: "JENKINS_AGENT_WORKDIR"
  34. value: "/home/jenkins/agent"
  35. - name: "JENKINS_URL"
  36. value: "http://10.1.172.136:8080/"
  37. image: "jenkins/inbound-agent:4.3-4-jdk11"
  38. name: "jnlp"
  39. resources:
  40. limits: {}
  41. requests:
  42. memory: "256Mi"
  43. cpu: "100m"
  44. volumeMounts:
  45. - mountPath: "/home/jenkins/agent"
  46. name: "workspace-volume"
  47. readOnly: false
  48. nodeSelector:
  49. kubernetes.io/os: "linux"
  50. restartPolicy: "Never"
  51. volumes:
  52. - emptyDir:
  53. medium: ""
  54. name: "workspace-volume"
  55. Running on test-4-xsc01-4292c-4rkrz in /home/jenkins/agent/workspace/test
  56. [Pipeline] {
  57. [Pipeline] stage
  58. [Pipeline] { (Run shell)
  59. [Pipeline] sh
  60. + echo hello world
  61. hello world
  62. [Pipeline] }
  63. [Pipeline] // stage
  64. [Pipeline] }
  65. [Pipeline] // node
  66. [Pipeline] }
  67. [Pipeline] // podTemplate
  68. [Pipeline] End of Pipeline
  69. Finished: SUCCESS

至此,我们已经成功配置了基础的Jenkins,并成功在Kubernetes集群上执行了一次构建任务。