Jenkins连接Kubernetes动态创建agent

持续构建与发布是我们日常工作中必不可少的一个步骤,目前大多公司都采用 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

为了使 Jenkins 访问 Kubernetes 集群,需要创建一个 ServiceAccount

在 Kubernetes 集群主机上,创建文件jenkins-rbac.yml

  • 创建一个名为 jenkinsServiceAccount,位于 jenkins 命名空间。
  • 定义一个名为 jenkins-roleRole,位于 jenkins 命名空间。
  • 授予了对以下资源的权限:
    • pods:创建、删除、获取、列表、更新、监视。
    • pods/exec:创建、删除、获取、列表、更新、监视。
    • pods/log:获取、列表、监视。
    • secrets:获取。
  • jenkins-role 绑定到 jenkins ServiceAccount

yaml

kind: ServiceAccount
apiVersion: v1
metadata:
  name: jenkins
  namespace: jenkins
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: jenkins-role
  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-role-binding
  namespace: jenkins
subjects:
- kind: ServiceAccount
  name: jenkins
  namespace: jenkins
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: jenkins-role

创建 ServiceAccount

bash

kubectl apply -f jenkins-rbac.yml

bash

kubectl get secret $(kubectl get serviceaccount jenkins -n jenkins -o jsonpath='{.secrets[0].name}') -n jenkins -o jsonpath='{.data.token}' | base64 --decode; echo

在系统管理的 Clouds 点击添加 New cloud,创建 Type Kubernetes

image-20250325101716646

添加 Secret text 类型的凭据,内容填写上面获取的 token 值

image-20250325100818681

配置 k8s 集群信息

Cloud kubernetes 配置

凭证选择k8s-secret后,点击连接测试,提示 Connection to Kubernetes xx 则表示配置成功。

pod template示例

在Jenkinsfile中使用

groovy

#!groovy

@Library('jenkinslibrary@master') _

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

// pipeline
pipeline{
    agent{
        kubernetes{
            inheritFrom 'jenkins-slave'
            defaultContainer 'maven'
            yaml podYaml
            showRawYaml false
        }
    }
...
}

创建一个pipeline工程

pipeline

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

相关内容