Jenkins定制Agent

上一节,我们实现了最简单的打包任务,在这一节,我们将定制所需的打包环境,为CD流水线做准备。

手动连接Agent

在上一节,我们使用了Kubernetes集群启动新的Slave节点,你可以沿着这条路,继续集成所需的环境,不再展开。

在本节,我们将切换另一种思路,使用手动启动&连接的方式。

首先,在Jenkins中添加一个Agent,路径是:Manage Jenkins -> Manage Nodes and Clouds -> New Node。

关键参数如下:

name:自选,这里e1

Number of executors:在这台机器上的并发执行任务数,这里选默认的2

Remote root directory:默认执行目录,这里选/home/jenkins/ateng

Labels:自选,这里executor,可以用它对Executor分组(如测试、线上等)

Launch method:Launch agent by connecting it to the master,即我们手动连接

保存后,点击进去后,能看到如下提示:

  1. Run from agent command line:
  2. java -jar agent.jar -jnlpUrl http://127.0.0.1:8080/computer/e1/jenkins-agent.jnlp -secret b057970bf978f53a8f945d470ac644e44c945e4b7259b216f703dedb95d0cac9 -workDir "/home/jenkins/agent"
  3. Run from agent command line, with the secret stored in a file:
  4. echo b057970bf978f53a8f945d470ac644e44c945e4b7259b216f703dedb95d0cac9 > secret-file
  5. java -jar agent.jar -jnlpUrl http://127.0.0.1:8080/computer/e1/jenkins-agent.jnlp -secret @secret-file -workDir "/home/jenkins/agent"

如上所示,我们需要用上述的Secret来连接Controller(主控)节点。

我们通过Docker启动Executor节点,如下:

  1. #!/bin/bash
  2. NAME="jenkins_e1"
  3. PUID="1000"
  4. PGID="1000"
  5. docker ps -q -a --filter "name=$NAME" | xargs -I {} docker rm -f {}
  6. docker run \
  7. --name $NAME \
  8. --env PUID=$PUID \
  9. --env PGID=$PGID \
  10. --detach \
  11. --init jenkins/inbound-agent \
  12. -workDir=/home/jenkins/agent \
  13. -url http://10.1.172.136:8080 \
  14. b057970bf978f53a8f945d470ac644e44c945e4b7259b216f703dedb95d0cac9 \
  15. e1

温馨提示:上述的workDir需要与Jenkins中的配置保持一致。

当启动成功后,能看到节点上线了,如下图所示:

f

为了不调度到Controller节点,我们可以将其上的执行数量设置为0。

随后,我们尝试修改任务,如下所示:

  1. pipeline {
  2. agent any
  3. stages {
  4. stage('Test') {
  5. steps {
  6. sh 'echo hello world'
  7. }
  8. }
  9. }
  10. }

如果一起顺利,其会成功地在e1完成执行!

定制Executor的环境

从上述例子中,不难理解:真正的打包任务,是在Executor中执行的。

如果我们的打包流程需要用到git、Java、Gradle、Kubernetes的话,我们也需要将这些集成到Executor中。

我们基于Jenkins的官方基础镜像进行定制,Dockerfile如下:

  1. FROM jenkins/inbound-agent:latest-jdk8
  2. ENV GRADLE_VERSION=7.2
  3. ENV K8S_VERSION=v1.22.3
  4. # tool
  5. USER root
  6. RUN apt-get update && \
  7. apt-get install -y curl unzip docker-ce docker-ce-cli && \
  8. apt-get clean
  9. # gradle
  10. RUN curl -skL -o /tmp/gradle-bin.zip https://services.gradle.org/distributions/gradle-$GRADLE_VERSION-bin.zip && \
  11. mkdir -p /opt/gradle && \
  12. unzip -q /tmp/gradle-bin.zip -d /opt/gradle && \
  13. ln -sf /opt/gradle/gradle-$GRADLE_VERSION/bin/gradle /usr/local/bin/gradle
  14. RUN chown -R 1001:0 /opt/gradle && \
  15. chmod -R g+rw /opt/gradle
  16. # kubectl
  17. RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/$K8S_VERSION/bin/linux/amd64/kubectl
  18. RUN chmod +x ./kubectl
  19. RUN mv ./kubectl /usr/local/bin
  20. USER jenkins

如上所示:

  • 我们基于inbound-agent进行定制,这是官方的默认的Agent基础镜像
  • 随后,我们使用apt安装curl、unzip等基础工具
  • 接着,我们安装gradle、kubectl等二进制文件
  • 最后恢复默认的运行环境

制作镜像

  1. docker build -t "coder4/jenkins-my-agent" .

制作时间会比较长

再次打包

  1. pipeline {
  2. agent {label 'executor'}
  3. stages {
  4. stage('git') {
  5. steps {
  6. sh "echo todo"
  7. }
  8. }
  9. stage('gradle') {
  10. steps {
  11. sh "gradle -v"
  12. }
  13. }
  14. stage('k8s') {
  15. steps {
  16. withKubeConfig([credentialsId: "60a8e9d2-0212-4ff4-aa98-f46fced97121",serverUrl: "https://kubernetes:6443"]) {
  17. sh "kubectl get nodes"
  18. }
  19. }
  20. }
  21. }
  22. }

需要指出的是:上述’k8s’阶段,使用的凭据,是我们在 Jenkins搭建入门一节中生成的证书+凭据。

运行结果

  1. Started by user admin
  2. [Pipeline] Start of Pipeline
  3. [Pipeline] node
  4. Running on e1 in /home/jenkins/agent/workspace/test
  5. [Pipeline] {
  6. [Pipeline] stage
  7. [Pipeline] { (git)
  8. [Pipeline] sh
  9. + git version
  10. git version 2.30.2
  11. [Pipeline] }
  12. [Pipeline] // stage
  13. [Pipeline] stage
  14. [Pipeline] { (gradle)
  15. [Pipeline] sh
  16. + gradle -v
  17. Welcome to Gradle 7.2!
  18. Here are the highlights of this release:
  19. - Toolchain support for Scala
  20. - More cache hits when Java source files have platform-specific line endings
  21. - More resilient remote HTTP build cache behavior
  22. For more details see https://docs.gradle.org/7.2/release-notes.html
  23. ------------------------------------------------------------
  24. Gradle 7.2
  25. ------------------------------------------------------------
  26. Build time: 2021-08-17 09:59:03 UTC
  27. Revision: a773786b58bb28710e3dc96c4d1a7063628952ad
  28. Kotlin: 1.5.21
  29. Groovy: 3.0.8
  30. Ant: Apache Ant(TM) version 1.10.9 compiled on September 27 2020
  31. JVM: 1.8.0_302 (Temurin 25.302-b08)
  32. OS: Linux 5.10.47-linuxkit amd64
  33. [Pipeline] }
  34. [Pipeline] // stage
  35. [Pipeline] stage
  36. [Pipeline] { (k8s)
  37. [Pipeline] withKubeConfig
  38. [Pipeline] {
  39. [Pipeline] sh
  40. + kubectl get nodes
  41. NAME STATUS ROLES AGE VERSION
  42. minikube Ready control-plane,master 6h58m v1.21.2
  43. [Pipeline] }
  44. [kubernetes-cli] kubectl configuration cleaned up
  45. [Pipeline] // withKubeConfig
  46. [Pipeline] }
  47. [Pipeline] // stage
  48. [Pipeline] }
  49. [Pipeline] // node
  50. [Pipeline] End of Pipeline
  51. Finished: SUCCESS