Jenkins连接Kubernetes动态创建JNLP

注意
本文最后更新于 2023-11-06,文中内容可能已过时。

持续构建与发布是我们日常工作中必不可少的一个步骤,目前大多公司都采用 Jenkins 集群来搭建符合需求的 CI/CD 流程,然而传统的 Jenkins Slave 一主多从方式会存在一些痛点,比如:

  • 主 Master 发生单点故障时,整个流程都不可用了
  • 每个 Slave 的配置环境不一样,来完成不同语言的编译打包等操作,但是这些差异化的配置导致管理起来非常不方便,维护起来也是比较费劲
  • 资源分配不均衡,有的 Slave 要运行的 job 出现排队等待,而有的 Slave 处于空闲状态
  • 资源有浪费,每台 Slave 可能是物理机或者虚拟机,当 Slave 处于空闲状态时,也不会完全释放掉资源。

正因为上面的这些种种痛点,我们渴望一种更高效更可靠的方式来完成这个 CI/CD 流程,而 Docker 虚拟化容器技术能很好的解决这个痛点,又特别是在 Kubernetes 集群环境下面能够更好来解决上面的问题,下图是基于 Kubernetes 搭建 Jenkins 集群的简单示意图:

img

这篇文章就是为了向大家说明,如何配置 Jenkins 才能使流水线脚本能够在 K8s 集群中启动 Jenkins 节点。首先你要先安装Kubernetes plugin这个插件。

我的 master 节点是跑在vm而不是k8s中,当然这并不重要。

在插件管理页面,搜索Kubernetes,勾选并安装即可。

image-20211202112253590

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins
  namespace: jenkins

---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: jenkins
  namespace: 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: ["secrets"]
  verbs: ["get"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: jenkins
  namespace: jenkins
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: jenkins
subjects:
- kind: ServiceAccount
  name: jenkins
  namespace: jenkins

Kubernetes服务证书key是用来与Kubernetes API server建立连接的,生成方法是,从Kubernetes API server/root/.kube/config文件中,获取/root/.kube/configcertificate-authority-data的内容,并转化成base64编码的文件即可。

安装命令行解析yaml工具yq

1
2
wget -O /usr/local/bin/yq https://github.com/mikefarah/yq/releases/download/v4.15.1/yq_linux_amd64
chmod +x /usr/local/bin/yq

服务端证书:

1
yq e '.clusters[0].cluster.certificate-authority-data' ~/.kube/config | base64 -d > ca.crt

ca.crt的内容就是Kubernetes服务证书key。

客户端证书:

1
yq e '.users[0].user.client-certificate-data' ~/.kube/config | base64 -d > client.crt

key:

1
yq e '.users[0].user.client-key-data' ~/.kube/config | base64 -d > client.key

生成Client P12认证文件:

1
2
3
openssl pkcs12 -export -out cert.pfx -inkey client.key -in client.crt -certfile ca.crt
Enter Export Password:
Verifying - Enter Export Password:

这里必须输入密码,比如123456,不然在后面添加jenkins相关配置后验证会报错

为了保证 Jenkins 能够访问 K8s 集群的资源,首先你需要按照以下步骤创建一些凭据:

  1. 进入 Jenkins 的系统管理,点击Manage Credentials

  2. 点击Stores scoped to Jenkins列表下全局中的添加凭据

    image-20211202112722830

  3. 填写所需信息,上传 cert.pfx 文件

    image-20211202112945468

这样之后 Jenkins 就可以使用这个凭据去访问 K8s 的资源啦

在系统管理的节点管理点击 Add a new cloud,添加k8s集群

image-20211202115317679

image-20211202115606698

配置k8s集群信息

image-20211202115728290

根据自己的需要配置

image-20211202122842685

容器环境变量,挂载卷按需配置

image-20211202122803213

pod template示例

在Jenkinsfile中使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#!groovy

@Library('jenkinslibrary@master') _

// func from shareibrary
def build = new org.devops.build()
def tools = new org.devops.tools()
def checkout = new org.devops.checkout()
// 读取资源文件
def podYaml = libraryResource 'com/yuanfu/pipeline/podyaml/MavenPod.yaml'

// pipeline
pipeline{
    agent{
        kubernetes{
            label "jenkins-slave-${UUID.randomUUID().toString()}"
            defaultContainer 'maven'
            yaml podYaml
            showRawYaml 'flase'
        }
    }

创建一个pipeline工程

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
node('java') {
    stage('Clone') {
      echo "1.Clone Stage"
    }
    stage('Test') {
      echo "2.Test Stage"
    }
    stage('Build') {
      echo "3.Build Docker Image Stage"
    }
    stage('Push') {
      echo "4.Push Docker Image Stage"
    }
    stage('YAML') {
      echo "5. Change YAML File Stage"
    }
    stage('Deploy') {
      echo "6. Deploy Stage"
    }
}

参考链接:

Jenkins 和 Kubernetes -云上的神秘代理

Jenkins连接k8s的多种姿势

Jenkins 连接 Kubernetes

相关内容