「Jenkins」- 使用 Kubernetes Cluster 作为构建节点

  CREATED BY JENKINSBOT

解决方案

通过 Kubernetes 插件,我们能够在 Kubernetes Pod 中运行构建任务;

配置步骤

我们不再展开细节,大致分为两步:

1)添加 Kubernetes 节点:Manage Jenkins ⇒ Manage Nodes and Clouds ⇒ Configure Clouds
Jenkins URL:填写 Jenkins Server 地址;
Container Cleanup Timeout:控制 Container 清理。默认在任务结束时将自动清理;

2)通过 Pipeline 使用:通过 PodTemplate 调用即可

podTemplate(
  cloud: "cluster name",
  containers: [
    containerTemplate(name: 'maven', image: 'maven:3.8.1-jdk-8', command: 'sleep', args: '99d'),
    containerTemplate(name: 'golang', image: 'golang:1.16.5', command: 'sleep', args: '99d')
  ]) {

    node(POD_LABEL) {
        stage('Get a Maven project') {
            git 'https://github.com/jenkinsci/kubernetes-plugin.git'
            container('maven') {
                stage('Build a Maven project') {
                    sh 'mvn -B -ntp clean install'
                }
            }
        }

        stage('Get a Golang project') {
            git url: 'https://github.com/hashicorp/terraform.git', branch: 'main'
            container('golang') {
                stage('Build a Go project') {
                    sh '''
                    mkdir -p /go/src/github.com/hashicorp
                    ln -s `pwd` /go/src/github.com/hashicorp/terraform
                    cd /go/src/github.com/hashicorp/terraform && make
                    '''
                }
            }
        }

    }
}

常见问题

… kubernetes.default.svc: Name or service not known …

在 Jenkins 中,添加集群,然后 Test Connection 验证,会产生如下错误:

...
jenkins run as docker kubernetes plugin Error testing connection XXX java.net.UnknownHostException: kubernetes.default.svc: Name or service not known
...

原因分析:
查看 Jenkins 日志,也会看到提示无法解析 kubeconfig 文件;

解决方案:
连接 Kubernetes Cluster 的 kubeconfig 的 current-context 要配置正确;

… not ready after 5000 MILLISECONDS …

在执行 Pipeline 过程中,出现 not ready after 5000 MILLISECONDS 错误:

...
java.net.SocketTimeoutException: connect timed out
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
...
io.fabric8.kubernetes.client.KubernetesClientException: not ready after 5000 MILLISECONDS
	at io.fabric8.kubernetes.client.utils.Utils.waitUntilReadyOrFail(Utils.java:180)
	at io.fabric8.kubernetes.client.dsl.internal.core.v1.PodOperationsImpl.exec(PodOperationsImpl.java:332)
	at io.fabric8.kubernetes.client.dsl.internal.core.v1.PodOperationsImpl.exec(PodOperationsImpl.java:85)
	at org.csanchez.jenkins.plugins.kubernetes.pipeline.ContainerExecDecorator$1.doLaunch(ContainerExecDecorator.java:428)
...

原因分析:
https://support.cloudbees.com/hc/en-us/articles/360038066231
https://support.cloudbees.com/hc/en-us/articles/360054642231
我们遇到该问题,是因为网络原因导致连接超时(我们的 IPSec VPN 总是会定时重新握手,而握手期间网络不通)

解决方案:
当添加集群时,配置 Max connections to Kubernetes API 参数,默认为 32 个连接;
对于我们的场景,我们需要修复 IPSec VPN 的问题(其他方案并不能解决该问题)

[WIP] 大量 Jenkins Agent 实例

问题描述:在 Kubernetes Cluster 中,我们发现 Jenkins 创建非常多的 Jenkins Agent 实例;

原因分析:

1)该问题并不常见,仅出现过两次,我们猜测是 Jenkins 无法正常连接 Kubernetes Cluster 有关;

2)我们需要观察 Pod 创建周期,似乎也没有什么固定规律:

# kubectl get pods -l jenkins=slave -n default -o jsonpath='{range .items[*]}{.metadata.name} {.status.startTime}{"\n"}{end}' --sort-by=".status.startTime"
integration-test-for-zenoh-raft-186-d11wx-2x1bl-f6d1r 2023-01-03T21:00:19Z
integration-test-for-zenoh-raft-186-d11wx-2x1bl-dw9px 2023-01-03T21:06:38Z
integration-test-for-zenoh-raft-186-d11wx-2x1bl-wxq7s 2023-01-03T21:11:14Z
integration-test-for-zenoh-raft-186-d11wx-2x1bl-14gnw 2023-01-03T21:14:03Z
integration-test-for-zenoh-raft-186-d11wx-2x1bl-cvt1k 2023-01-03T21:14:03Z
integration-test-for-zenoh-raft-186-d11wx-2x1bl-nqnwt 2023-01-03T21:14:11Z
integration-test-for-zenoh-raft-186-d11wx-2x1bl-cm7ps 2023-01-03T21:17:51Z
integration-test-for-zenoh-raft-186-d11wx-2x1bl-s0jpk 2023-01-03T21:18:05Z
integration-test-for-zenoh-raft-186-d11wx-2x1bl-lp2jq 2023-01-03T21:24:05Z

解决方案:[WIP]

参考文献

Kubernetes CLI | Jenkins plugin
kubernetes – Jenkins pipeline: kubectl: not found – Stack Overflow