joeの小窝

Loading...

jenkins对接kubernetes

jenkins对接kubernetes

jenkins对接k8s或者对接node节点

  • 对接k8s的话,就是会创建一个临时的pod(在k8s的任意一个工作节点上运行),来执行任务,动态的slave

  • 对接node的话,就是增加节点,就是会在node节点上创建一个工作目录,用节点的操作系统上跑进程,静态的slave

  • 本文讲的是对接k8s,需要先安装kubernetes插件

1、kubernetes插件简介

kubernetes插件的目的就是能够使用k8s配合,实现动态配置jenkins代理,在执行jenkins job 构建时,jenkins master会在k8s中创建一个slave pod 代理来执行这次任务

这个slave pod可以包含很多的镜像,需要maven编译可以使用maven镜像执行任务,需要npm编译就使用npm镜像,镜像也是可以自定义的

所有job中所需要的环境及其依赖都交由镜像提供,而而不需要手动搭配这些环境,在slave pod中执行job任务后,这个slave pod 会被自动的删除,所以k8s插件简单的用法就是,在k8s中启动jenkins slave代理,执行任务,执行完成后删除slave 释放资源

2、k8s插件使用

1、k8s插件组成部分

k8s插件配置主要有3部分组成

  • 连接k8s的参数,主要就是配置怎么连接k8s的

    • 如果jenkins在k8s内部的话,可以直接使用svc进行连接

    • 如果jenkins单独部署在一台机器上的话,就需要使用k8s的rbac认证授权配置这些(后面抽时间实现以下)

      • k8s api server地址,证书/token,rbac权限(删除pod,创建pod的权限)
  • slave pod 连接master的参数,就是slave pod 创建出来后,通过配置与master进行通信,master发送任务给slave pod,slave pod 执行任务

  • pod模版,可以定义pod在哪一个空间下创建,使用哪一个镜像

2、k8s连接参数

进入 系统管理->节点管理->Configure Clouds 中,点击 Add a new cloud 选项,选择kubernetes,即可进行kubernetes插件的配置。Kubernetes 插件的基本配置,可以配置 Jenkins 连接 Kubernetes API 地址、凭据、超时时间、容器数量限制等参数,详细配置项说明如下:

  • 名称: 用于云配置的标识,可以配置多个云对应多个k8s环境

  • k8s地址: k8s的api地址,一般在集群的内部 https://kubernetes.default.svc.cluster.local ,集群外部的k8s地址为https://{k8s ip}:6443
    ,jenkins部署在内部的话,使用内部地址,否则使用外部地址

  • 禁用https证书检查:连接k8s api的时候不检查https证书,一般默认不勾选

  • k8s命名空间:指定在哪一个k8s空间下执行任务,也就是slave pod 会创建在这个空间下

  • jenkins地址:指定jenkins master的url地址,用于slave连接jenkins用,如果jenkins配置了前缀也要带上,如 http://jenkins.example.com:8080 ,也可以使用k8s内部地址,也就是svc的dns http://jenkins-svc.devops.svc.cluster.local:8080

  • jenkins通道: jenkins会提供一个独立的端口用于jenkins slave连接,默认端口为50000,如 jenkins-svc.devops.svc.cluster.local:50000

# 8080 slave连接master
# 50000 mamster连接slave
# 这样实现了双方的通信,master发送任务给slave

[root@master01 ~]# kubectl get svc -n devops
NAME          TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)                          AGE
jenkins-svc   NodePort   10.111.33.72   <none>        8080:32000/TCP,50000:32686/TCP   17h


创建一个k8s云

img

img

点击连接k8s

img

连接成功

3、测试

1、创建流水线

新建一个流水线,执行任务,看能不能启动一个slave pod, 能不能正确启动连接

img

pipeline {
    agent {
        kubernetes {
            cloud 'k8s'   // 这里填创建的云
            showRawYaml true   //展示yaml详细信息
            yaml """         
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: jenkins-agent
  name: jenkins-agent
spec:
  serviceAccountName: jenkins-admin
  containers:
  - name: jnlp
    image: jenkins/inbound-agent 
    args: ['\$(JENKINS_SECRET)', '\$(JENKINS_NAME)']
  - name: busybox
    image: busybox
    command:
    - cat
    tty: true
    imagePullPolicy: IfNotPresent
  dnsPolicy: ClusterFirst
  restartPolicy: Never
"""
        }
    }
 
    stages {
        stage('Hello') {
            steps {
                echo 'Hello World'
            }
        }
    }
}
 

2、输出成功

输出成功

img

3、背后详细信息解读

会启动一个临时pod,里面有2个容器

  • 一个是默认的容器的"jenkins/inbound-agent",这个容器必须存在

    • 这个容器是必须的,唯一的作用就是与master进行通信,接收任务,里面有之前配置的连接jenkins的地址,主动连接master
  • 另外一个容器是我们自定义的,可选的,负责干活的

  • 这个pod就是slave pod

  • 任务执行完成后,就会自动销毁

test-k8s-2-xdpq6-0ckcl-pdqgq      0/2     Pending   0             0s    <none>          <none>   <none>           <none>
test-k8s-2-xdpq6-0ckcl-pdqgq      0/2     Pending   0             0s    <none>          node1    <none>           <none>
test-k8s-2-xdpq6-0ckcl-pdqgq      0/2     ContainerCreating   0             0s    <none>          node1    <none>           <none>
test-k8s-2-xdpq6-0ckcl-pdqgq      0/2     ContainerCreating   0             1s    <none>          node1    <none>           <none>
test-k8s-2-xdpq6-0ckcl-pdqgq      2/2     Running             0             17s   10.245.149.15   node1    <none>           <none>
test-k8s-2-xdpq6-0ckcl-pdqgq      2/2     Terminating         0             21s   10.245.149.15   node1    <none>           <none>
test-k8s-2-xdpq6-0ckcl-pdqgq      2/2     Terminating         0             52s   10.245.149.15   node1    <none>           <none>
test-k8s-2-xdpq6-0ckcl-pdqgq      0/2     Terminating         0             52s   10.245.149.15   node1    <none>           <none>

输出详细信息解读

Started by user admin
[Pipeline] Start of Pipeline
[Pipeline] podTemplate
[Pipeline] {
[Pipeline] node
Created Pod: k8s devops/test-k8s-2-xdpq6-0ckcl-pdqgq
[PodInfo] devops/test-k8s-2-xdpq6-0ckcl-pdqgq
	Container [busybox] waiting [ContainerCreating] No message
	Container [jnlp] waiting [ContainerCreating] No message
	Pod [Pending][ContainersNotReady] containers with unready status: [jnlp busybox]
[PodInfo] devops/test-k8s-2-xdpq6-0ckcl-pdqgq
	Container [busybox] waiting [ContainerCreating] No message
	Container [jnlp] waiting [ContainerCreating] No message
	Pod [Pending][ContainersNotReady] containers with unready status: [jnlp busybox]
Still waiting to schedule task
‘test-k8s-2-xdpq6-0ckcl-pdqgq’ is offline
Agent test-k8s-2-xdpq6-0ckcl-pdqgq is provisioned from template test_k8s_2-xdpq6-0ckcl
---
apiVersion: "v1"
kind: "Pod"
metadata:
  annotations:
    kubernetes.jenkins.io/last-refresh: "1776234725670"
    buildUrl: "http://jenkins-svc.devops.svc.cluster.local:8080/job/test_k8s/2/"
    runUrl: "job/test_k8s/2/"
  labels:
    run: "jenkins-agent"
    jenkins: "slave"
    jenkins/label-digest: "b3e6eaaddee4004d98e05d38b6c9e8860613db6c"
    jenkins/label: "test_k8s_2-xdpq6"
    kubernetes.jenkins.io/controller: "http___jenkins-svc_devops_svc_cluster_local_8080x"
  name: "test-k8s-2-xdpq6-0ckcl-pdqgq"
  namespace: "devops"
spec:
  containers:
  - args:
    - "$(JENKINS_SECRET)"
    - "$(JENKINS_NAME)"
    env:
    - name: "JENKINS_SECRET"
      value: "********"
    - name: "JENKINS_TUNNEL"  # jenkins通道
      value: "jenkins-svc.devops.svc.cluster.local:50000"
    - name: "JENKINS_AGENT_NAME"
      value: "test-k8s-2-xdpq6-0ckcl-pdqgq"
    - name: "REMOTING_OPTS"
      value: "-noReconnectAfter 1d"
    - name: "JENKINS_NAME"
      value: "test-k8s-2-xdpq6-0ckcl-pdqgq"
    - name: "JENKINS_AGENT_WORKDIR"
      value: "/home/jenkins/agent"
    - name: "JENKINS_URL"   # jenkins连接地址
      value: "http://jenkins-svc.devops.svc.cluster.local:8080/"
    image: "jenkins/inbound-agent"  # 默认容器 jnlp
    name: "jnlp"
    resources:
      requests:
        memory: "256Mi"
        cpu: "100m"
    volumeMounts:
    - mountPath: "/home/jenkins/agent"
      name: "workspace-volume"
      readOnly: false
  - command:   # busybox执行的命令,让这个容器一直活着
    - "cat"
    image: "busybox"
    imagePullPolicy: "IfNotPresent"
    name: "busybox"
    tty: true  # 分配一个终端,输出信息,否则报错
    volumeMounts:
    - mountPath: "/home/jenkins/agent"
      name: "workspace-volume"
      readOnly: false
  dnsPolicy: "ClusterFirst"
  nodeSelector:
    kubernetes.io/os: "linux"
  restartPolicy: "Never"
  serviceAccountName: "jenkins-admin"  # 这个pod使用的jenkins-admin用户启动的
  volumes:
  - emptyDir:
      medium: ""
    name: "workspace-volume"

Running on test-k8s-2-xdpq6-0ckcl-pdqgq in /home/jenkins/agent/workspace/test_k8s  # pod启动了
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Hello)
[Pipeline] echo
Hello World
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] }
[Pipeline] // podTemplate
[Pipeline] End of Pipeline
Finished: SUCCESS

这个输出信息是跑在默认容器上的,因为你没有指定容器执行哪些命令,所以是默认容器中执行这个命令

stage('Hello') {
  steps {
    container('busybox') {  // # 这个地方就指定了容器,执行命令
      echo "Hello World"
    }
  }
}

总结一下

jenkins连接k8s(动态slave pod)

目的就是执行任务的时候,会创建一个slave pod 运行在k8s的工作节点上

master和slave pod 进行通信,master发送任务给slave pod 执行,执行结束后,自动销毁

slave pod 环境

  • 2个容器,一个jenkins默认容器,一个自定义容器

  • 容器的镜像可以拉取,自己构建等等

之后的实验

gitlab+jenkins+k8s+harbor

dockerfile文件从gitlab上拉取,构建一个镜像,推送到镜像仓库

拉取这个镜像,执行任务

posted @ 2026-04-15 15:09  乔的港口  阅读(89)  评论(0)    收藏  举报