[TOC]
0x00 前言简述 描述: 有了上一章的基础"4.Jenkins进阶之分布式架构环境配置"
介绍,本章主要介绍Kubernetes 的插件使用实例, 以及自定义 Slave 的 Jenkins-Jnlp 容器镜像模板(重点),在进行K8s动态节点生成时拉取使用,极大的节约了系统资源。
0x01 Kubernetes-plugin 使用 描述: 前面已经对Jenkins集成Kubernetes进行部署和配置,本章将进行介绍与实践如何使用该插件以及帮助文档的记录;
说明: Kubernetes-plugin 它是在Kubernetes集群中运行动态代理的Jenkins插件, 该插件为每个启动的代理创建一个Kubernetes Pod,由Docker映像定义运行,并在每次构建后停止。
备注: 代理是使用JNLP启动的,因此预期图像会自动连接到Jenkins主机,以下是重要的环境变量(我们说过不建议使用自己jnlp覆盖默认的jnlp容器)。
[TOC]
0x00 前言简述 描述: 有了上一章的基础"4.Jenkins进阶之分布式架构环境配置"
介绍,本章主要介绍Kubernetes 的插件使用实例, 以及自定义 Slave 的 Jenkins-Jnlp 容器镜像模板(重点),在进行K8s动态节点生成时拉取使用,极大的节约了系统资源。
0x01 Kubernetes-plugin 使用 描述: 前面已经对Jenkins集成Kubernetes进行部署和配置,本章将进行介绍与实践如何使用该插件以及帮助文档的记录;
说明: Kubernetes-plugin 它是在Kubernetes集群中运行动态代理的Jenkins插件, 该插件为每个启动的代理创建一个Kubernetes Pod,由Docker映像定义运行,并在每次构建后停止。
备注: 代理是使用JNLP启动的,因此预期图像会自动连接到Jenkins主机,以下是重要的环境变量(我们说过不建议使用自己jnlp覆盖默认的jnlp容器)。1 2 3 4 5 JENKINS_URL: Jenkins web interface url JENKINS_SECRET: the secret key for authentication JENKINS_AGENT_NAME: the name of the Jenkins agent JENKINS_NAME: the name of the Jenkins agent (Deprecated. Only here for backwards compatibility)
该镜像是Jenkins自定义jnlp容器模板,主要用于Jenkins工作节点容器化使用,主要包含Gitlab_release发布、 docker 容器管理、kubectl 集群管理功能。我们可以直接在docker 的环境中 docker pull weiyigeek/alpine-jenkins-jnlp
下来
环境依赖
1.先决条件
正在运行的Kubernetes集群1.14或更高版本。对于OpenShift用户,这意味着OpenShift容器平台4.x。
安装了一个Jenkins实例
已安装Jenkins Kubernetes插件
2.填写Kubernetes插件配置
您将打开Jenkins UI并导航至Manage Jenkins-> Configure System-> Cloud-> Kubernetes并输入相应的Kubernetes URL和Jenkins URL,除非Jenkins在Kubernetes中运行否则默认工作(参考上一章)。
3.支持的凭证
Username/password - 用户名密码
Secret File (kubeconfig file) - 秘密文件(kubeconfig文件)
Secret text (Token-based authentication) (OpenShift) - 秘密文本(基于令牌的身份验证)(OpenShift)
Google Service Account from private key (GKE authentication) - 来自私钥的Google服务帐户(GKE身份验证)
X.509 Client Certificate - X.509客户端证书
插件参数 podTemplate - Pod和容器模板 描述: podTemplate 是用于创建代理的pod的模板可以通过用户界面或管道进行配置
, 无论哪种方式它都可以访问以下字段:
container - 容器模板的定义 描述: containerTemplate 是一个将被添加到pod中的容器模板它属于container中数组对象。同样它可以通过用户界面或管道进行配置,并允许你设置以下字段:
containerTemplate - 容器模板
name : 容器的名称。
image : 容器的图像。
envVars : 应用于容器的环境变量(补充和覆盖在pod级别设置的env var
)。
envVar 环境变量,其值是内联定义的。
secretEnvVar 一个环境变量,其值是从Kubernetes机密派生的。
workingDir : 工作空间目录
command : 容器将执行的命令。
args : 传递给命令的参数。
ttyEnabled : 标记以指示应启用tty。
livenessProbe : 要添加到容器中的exec liveness探针的参数(不支持httpGet liveness探针)
ports : 暴露容器上的端口。
alwaysPullImage : 容器在启动时将拉出图像。
runAsUser : 用于运行容器的用户ID。
runAsGroup : 运行容器的组ID。
Liveness Probe Usage 1 2 3 4 5 6 7 8 9 10 11 12 13 14 containerTemplate( name: 'busybox' , image: 'busybox' , ttyEnabled: true , command : 'cat' , livenessProbe: containerLivenessProbe( execArgs: 'some --command' , initialDelaySeconds: 30, timeoutSeconds: 1, failureThreshold: 3, periodSeconds: 10, successThreshold: 1 ) )
Tips : 默认情况下代理连接超时设置为100秒
。在某些情况下您想要设置一个不同的值,如果可以可以将system属性设置org.csanchez.jenkins.plugins.kubernetes.PodTemplate.connectionTimeout
为一个不同的值
Pipeline Support 实践示例 Scripted Pipeline 描述: Scripted Pipeline 示例参考:
(1) containerTemplate 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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 podTemplate( cloud: 'kubernetes' , name: 'jenkins-slave' , namespace: 'devops' , label: 'k8s-slave' , containers: [ containerTemplate( name: 'maven' , image: 'maven:3.6-jdk-8-alpine' , ttyEnabled: true , command: 'cat' , privileged: false , alwaysPullImage: false , workingDir: '/home/jenkins/agent' , resourceRequestCpu: '100m' , resourceLimitCpu: '500m' , resourceRequestMemory: '100Mi' , resourceLimitMemory: '500Mi' , envVars: [ envVar(key: 'MYSQL_ALLOW_EMPTY_PASSWORD' , value: 'true' ) ] ) ] ,volumes: [ hostPathVolume(hostPath: '/nfsdisk-31/appstorage/mavenRepo' , mountPath: '/home/jenkins' ), hostPathVolume(hostPath: '/var/run/docker.sock' , mountPath: '/var/run/docker.sock' ), ], annotations: [ podAnnotation(key: "maven-pod" , value: "Kubernetes-jenkins-Test" ) ], showRawYaml: 'flase' ) { node ('k8s-slave' ) { container('maven' ) { stage('maven' ) { container('maven' ) { sh "hostname && ip addr" sh ("mvn -version" ) sh "env" } } } } }
运行结果: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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 Created Pod: kubernetes devops/jenkins-slave-rtjxx-q3nhn [Normal][devops/jenkins-slave-rtjxx-q3nhn][Scheduled] Successfully assigned devops/jenkins-slave-rtjxx-q3nhn to work-223 [Normal][devops/jenkins-slave-rtjxx-q3nhn][Pulled] Container image "maven:3.6-jdk-8-alpine" already present on machine [Normal][devops/jenkins-slave-rtjxx-q3nhn][Created] Created container maven | Started container maven [Normal][devops/jenkins-slave-rtjxx-q3nhn][Pulled] Container image "jenkins/inbound-agent:4.3-4" already present on machine [Normal][devops/jenkins-slave-rtjxx-q3nhn][Created] Created container jnlp | Started container jnlp Agent jenkins-slave-rtjxx-q3nhn is provisioned from template jenkins-slave-rtjxx apiVersion: "v1" kind: "Pod" metadata: annotations: maven-pod: "Kubernetes-jenkins-Test" buildUrl: "http://jenkins.devops.svc.cluster.local:8080/job/Kubernetes-jenkins-slave/23/" runUrl: "job/Kubernetes-jenkins-slave/23/" labels: jenkins: "slave" jenkins/label-digest: "823e2bb3db243573786b7a360a483f1acc7a0f96" jenkins/label: "k8s-slave" name: "jenkins-slave-rtjxx-q3nhn" spec: containers: - command : - "cat" env: - name: "MYSQL_ALLOW_EMPTY_PASSWORD" value: "true" image: "maven:3.6-jdk-8-alpine" imagePullPolicy: "IfNotPresent" name: "maven" resources: limits: memory: "500Mi" cpu: "500m" requests: memory: "100Mi" cpu: "100m" tty: true volumeMounts: - mountPath: "/home/jenkins" name: "volume-0" readOnly: false - mountPath: "/var/run/docker.sock" name: "volume-1" readOnly: false - mountPath: "/home/jenkins/agent" name: "workspace-volume" readOnly: false workingDir: "/home/jenkins/agent" - env: - name: "JENKINS_SECRET" value: "********" - name: "JENKINS_AGENT_NAME" value: "jenkins-slave-rtjxx-q3nhn" - name: "JENKINS_NAME" value: "jenkins-slave-rtjxx-q3nhn" - name: "JENKINS_AGENT_WORKDIR" value: "/home/jenkins/agent" - name: "JENKINS_URL" value: "http://jenkins.devops.svc.cluster.local:8080/" image: "jenkins/inbound-agent:4.3-4" name: "jnlp" resources: limits: {} requests: memory: "256Mi" cpu: "100m" volumeMounts: - mountPath: "/home/jenkins" name: "volume-0" readOnly: false - mountPath: "/var/run/docker.sock" name: "volume-1" readOnly: false - mountPath: "/home/jenkins/agent" name: "workspace-volume" readOnly: false nodeSelector: kubernetes.io/os: "linux" restartPolicy: "Never" volumes: - hostPath: path: "/nfsdisk-31/appstorage/mavenRepo" name: "volume-0" - hostPath: path: "/var/run/docker.sock" name: "volume-1" - emptyDir: medium: "" name: "workspace-volume" + hostname + ip addr + mvn -version + env
Tips : 在PodTemplate模板中设置 showRawYaml: 'flase'
则将不会显示资源清单在日志中;
weiyigeek.top-脚本式流水线k8s插件使用
Tips : 要使用 secretEnvVar 我们必须在 Dashboard -> 凭据 -> 系统 -> 全局凭据 (unrestricted)
进行添加一个Secret-text凭据(未能成功复现);1 Secret text 4fc93636-d8f1-4051-8011-d852873fc740 mysql-secret Secret text mysql-secret
Declarative Pipeline 描述: 声明式管道支持需要Jenkins 2.66+, 在Declarative Pipeline使用的 kubernetes 选项说明;1 options are [activeDeadlineSeconds, cloud, containerTemplate, containerTemplates, customWorkspace, defaultContainer, idleMinutes, inheritFrom, instanceCap, label, namespace, nodeSelector, podRetention, serviceAccount, slaveConnectTimeout, supplementalGroups, workingDir, workspaceVolume, yaml, yamlFile, yamlMergeStrategy]
示例帮助: https://github.com/jenkinsci/kubernetes-plugin/tree/master/src/main/resources/org/csanchez/jenkins/plugins/kubernetes/pipeline/samples
示例1.通过yaml文件资源清单创建 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 pipeline { agent { kubernetes { cloud 'kubernetes' namespace 'devops' workingDir '/home/jenkins/agent' inheritFrom 'jenkins-slave' defaultContainer 'maven' yaml """\ apiVersion: kind: Pod metadata: labels: jenkins: "slave" jenkins/label: 'k8s-slave' spec: containers: - name: 'maven' image: 'maven:3.6-jdk-8-alpine' imagePullPolicy: 'IfNotPresent' # 镜像拉取策略 command: - cat tty: true """ .stripIndent() } } stages { stage ('declarative Pipeline - kubernetes' ) { steps { echo "declarative Pipeline - kubernetes" container ('maven' ) { sh "echo ${POD_CONTAINER}" sh "mvn -version" } } } } }
执行结果: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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 [Pipeline] Start of Pipeline [Pipeline] podTemplate [Pipeline] { [Pipeline] node --- kind: "Pod" metadata: annotations: buildUrl: "http://jenkins.devops.svc.cluster.local:8080/job/Kubernetes-jenkins-slave/49/" runUrl: "job/Kubernetes-jenkins-slave/49/" labels: jenkins: "slave" jenkins/label: "Kubernetes-jenkins-slave_49-fcd1s" jenkins/label-digest: "95508e0ca05226ba84989959dc886ad4011cf125" name: "kubernetes-jenkins-slave-49-fcd1s-m3n3q-t33d8" spec: containers: - command : - "cat" image: "maven:3.6-jdk-8-alpine" imagePullPolicy: "IfNotPresent" name: "maven" tty: true volumeMounts: - mountPath: "/home/jenkins/agent" name: "workspace-volume" readOnly: false - env: - name: "JENKINS_SECRET" value: "********" - name: "JENKINS_AGENT_NAME" value: "kubernetes-jenkins-slave-49-fcd1s-m3n3q-t33d8" - name: "JENKINS_NAME" value: "kubernetes-jenkins-slave-49-fcd1s-m3n3q-t33d8" - name: "JENKINS_AGENT_WORKDIR" value: "/home/jenkins/agent" - name: "JENKINS_URL" value: "http://jenkins.devops.svc.cluster.local:8080/" image: "jenkins/inbound-agent:4.3-4" name: "jnlp" resources: limits: {} requests: memory: "256Mi" cpu: "100m" volumeMounts: - mountPath: "/home/jenkins/.m2" name: "volume-0" readOnly: false - mountPath: "/home/jenkins/agent" name: "workspace-volume" readOnly: false hostNetwork: false nodeSelector: kubernetes.io/os: "linux" restartPolicy: "Never" volumes: - hostPath: path: "/nfsdisk-31/appstorage/mavenRepo" name: "volume-0" - emptyDir: medium: "" name: "workspace-volume" Running on kubernetes-jenkins-slave-49-fcd1s-m3n3q-t33d8 in /home/jenkins/agent/workspace/Kubernetes-jenkins-slave [Pipeline] echo declarative Pipeline - kubernetes + echo maven maven + mvn -version Apache Maven 3.6.1 (d66c9c0b3152b2e69ee9bac180bb8fcc8e6af555; 2019-04-04T19:00:29Z) Maven home: /usr/share/maven Java version: 1.8.0_212, vendor: IcedTea, runtime: /usr/lib/jvm/java-1.8-openjdk/jre Default locale: en_US, platform encoding: UTF-8 OS name: "linux" , version: "5.4.0-42-generic" , arch: "amd64" , family: "unix" Finished: SUCCESS
Tips :默认情况下在容器中运行步骤, 步骤将嵌套在隐式container(name){…}块中,而不是在jnlp容器中执行。1 defaultContainer 'maven'
Tips : 您也可以使用yamlFile将pod模板保存在单独的KubernetesPod.yaml文件中1 2 3 4 5 6 7 8 9 10 pipeline { agent { kubernetes { yamlFile 'KubernetesPod.yaml' } } stages { ... } }
0x02 自定义Jenkins工作节点之jnlp-slave镜像模板构建 Dockerfile 构建依赖 描述: 下述相关脚本以及文件下载地址请在WeiyiGeek
微信公众号回复jenkins-jnlp-dockerfile
关键字获取;
自定义的jnlp容器模板主要实现功能:
用户权限控制(sudo)
ssh 远程连接
git 代码版本控制
docker 容器管理
kubectl 集群管理
Java 运行环境
Maven 运行环境
SonarQube 扫描环境
Gitlab_release 上传环境
中文环境支持
时区更改配置
Tips: 在K8s集群中测试alpine镜像执行相应的安装(需要在Alpine调试新安装软件时使用):1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: alpine-app spec: containers: - name: alpine-app image: alpine:latest args: - sleep - "100000" EOF pod/alpine-app created $ kubectl get pods -o wide
Dockerfile
自定义jnlp容器模板镜像地址: https://hub.docker.com/r/weiyigeek/alpine-jenkins-jnlp
该镜像是Jenkins自定义jnlp容器模板,主要用于Jenkins工作节点容器化使用,主要包含Gitlab_release发布、 docker 容器管理、kubectl 集群管理功能。我们可以直接在docker 的环境中 docker pull weiyigeek/alpine-jenkins-jnlp
下来
说明: 镜像构建文件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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 FROM alpine:3.13 .1 MAINTAINER Jenkins Custom Work Node Jnlp Container - <master@weiyigeek.top> - WeiyiGeekARG USERNAME=jenkins \ AGENT_WORKDIR=/home/jenkins \ BASE_DIR=/usr/local \ BASE_BIN=/usr/local/bin \ BASE_URL=http://192.168 .12.107 :8080 \ LOCALE=locale.md \ JDK_NAME=jdk-8 u281-linux-x64 \ JDK_DIR=/usr/local/jdk1.8.0 _281 \ GLIBC_NAME=glibc-2.32 -r0.apk \ GLIBC_BIN_NAME=glibc-bin-2.32 -r0.apk \ GLIBC_I18N_NAME=glibc-i18n-2.32 -r0.apk \ MAVEN_NAME=apache-maven-3.6 .3 -bin \ MAVEN_DIR=/usr/local/apache-maven-3.6 .3 \ SONAR_SCANNER_NAME=sonar-scanner-cli-4.5 .0.2216 -linux \ SONAR_SCANNER_DIR=/usr/local/sonar-scanner-4.5 .0.2216 -linux \ GITLAB_CLI=release-cli-0.6 .0 -linux-amd64 ENV LANG=en_US.UTF-8 \ LC_ALL=en_US.UTF-8 \ JAVA_HOME=/usr/local/jdk8 \ JRE_HOME=/usr/local/jdk8/jre \ MAVEN_HOME=/usr/local/maven \ MAVEN_RPEO=/home/jenkins/.m2 \ SONAR_SCANNER_HOME=/usr/local/sonar-scanner \ NODEJS_MODULES=/usr/lib/node_modules USER rootRUN sed -i 's/dl-cdn.alpinelinux.org/mirror.tuna.tsinghua.edu.cn/g' /etc/apk/repositories \ && apk update \ && apk add --no-cache openssh tzdata curl tar sudo git ca-certificates wget unzip docker zlib nodejs npm jq \ && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ && chmod 4755 /bin/busybox \ && addgroup -g 1000 -S ${USERNAME} \ && adduser ${USERNAME} -D -g ${USERNAME} -G root -u 1000 -s /bin/sh \ && echo "jenkins ALL=(root) NOPASSWD:ALL" >> /etc/sudoers \ && mkdir -p ${AGENT_WORKDIR} /agent ${AGENT_WORKDIR} /.ssh ${AGENT_WORKDIR} /.m2 \ && wget -q -O /tmp/${GLIBC_NAME} ${BASE_URL} /${GLIBC_NAME} \ && wget -q -O /tmp/${GLIBC_BIN_NAME} ${BASE_URL} /${GLIBC_BIN_NAME} \ && wget -q -O /tmp/${GLIBC_I18N_NAME} ${BASE_URL} /${GLIBC_I18N_NAME} \ && wget -q -O /etc/apk/keys/sgerrand.rsa.pub ${BASE_URL} /sgerrand.rsa.pub \ && wget -q -O /tmp/${LOCALE} ${BASE_URL} /${LOCALE} \ && wget -q -O /tmp/${JDK_NAME} .tar.gz ${BASE_URL} /${JDK_NAME} .tar.gz \ && wget -q -O ${BASE_BIN} /agent.jar ${BASE_URL} /agent.jar \ && curl -fsSL -o ${BASE_BIN} /jenkins-agent.sh ${BASE_URL} /jenkins-agent.sh \ && curl -fsSL -o /tmp/${MAVEN_NAME} .tar.gz ${BASE_URL} /${MAVEN_NAME} .tar.gz \ && curl -fsSL -o /tmp/${SONAR_SCANNER_NAME} .zip ${BASE_URL} /${SONAR_SCANNER_NAME} .zip \ && curl -fsSL -o /usr/local /bin/release-cli ${BASE_URL} /${GITLAB_CLI} \ && curl -fsSL -o /usr/local /bin/kubectl ${BASE_URL} /kubectl \ && sed -i "s/#PermitRootLogin.*/PermitRootLogin yes/g" /etc/ssh/sshd_config \ && sed -i "s/^#\s*StrictHostKeyChecking ask/StrictHostKeyChecking no/g" /etc/ssh/ssh_config \ && ssh-keygen -t dsa -P "" -f /etc/ssh/ssh_host_dsa_key \ && ssh-keygen -t rsa -P "" -f /etc/ssh/ssh_host_rsa_key \ && ssh-keygen -t ecdsa -P "" -f /etc/ssh/ssh_host_ecdsa_key \ && ssh-keygen -t ed25519 -P "" -f /etc/ssh/ssh_host_ed25519_key \ && ssh-keygen -t ed25519 -P "" -C "master@weiyigeek.top" -f /home/jenkins/.ssh/id_ed25519 \ && apk add /tmp/${GLIBC_NAME} /tmp/${GLIBC_BIN_NAME} /tmp/${GLIBC_I18N_NAME} \ && tar -zxf /tmp/${JDK_NAME} .tar.gz -C ${BASE_DIR} \ && mv ${JDK_DIR} ${JAVA_HOME} \ && tar -zxf /tmp/${MAVEN_NAME} .tar.gz -C ${BASE_DIR} \ && mv ${MAVEN_DIR} ${MAVEN_HOME} \ && unzip /tmp/${SONAR_SCANNER_NAME}.zip -d ${BASE_DIR} \ && mv ${SONAR_SCANNER_DIR} ${SONAR_SCANNER_HOME} \ && npm config set registry https://registry.npmmirror.com \ && chmod a+x ${BASE_BIN}/* \ && chown -R jenkins:jenkins ${BASE_DIR}/ ${AGENT_WORKDIR}/ ${NODEJS_MODULES}/ \ && echo "root:WeiyiGeek" | chpasswd \ && echo "jenkins:WeiyiGeek" | chpasswd \ && cat /tmp/${LOCALE} | xargs -i /usr/glibc-compat/bin/localedef -i {} -f UTF-8 {}.UTF-8 \ && sed -i "s#use_embedded_jre=true#use_embedded_jre=false#g" ${SONAR_SCANNER_HOME}/bin/sonar-scanner \ && rm -rf /var/cache/apk/* /tmp/* ${SONAR_SCANNER_HOME}/jre/* \ && cd ${JAVA_HOME} \ && rm -rf COPYRIGHT LICENSE README release THIRDPARTYLICENSEREADME-JAVAFX.txt THIRDPARTYLICENSEREADME.txt Welcome.html javafx-src.zip src.zip \ lib/plugin.jar \ lib/ext/jfxrt.jar \ bin/javaws \ lib/javaws.jar \ lib/desktop \ plugin \ lib/deploy* \ lib/*javafx* \ lib/*jfx* \ lib/amd64/libdecora_sse.so \ lib/amd64/libprism_*.so \ lib/amd64/libfxplugins.so \ lib/amd64/libglass.so \ lib/amd64/libgstreamer-lite.so \ lib/amd64/libjavafx*.so \ lib/amd64/libjfx*.so && echo "export LANG=zh_CN.UTF-8" > /etc/profile.d/locale.sh USER jenkins WORKDIR ${AGENT_WORKDIR} ENV CLASSPATH=.:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar \ PATH=${JAVA_HOME}/bin:${MAVEN_HOME}/bin:${SONAR_SCANNER_HOME}/bin:$PATH ENTRYPOINT ["/usr/local/bin/jenkins-agent.sh" ]
local.md 描述:让alpine操作系统中文字符支持;1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 tee local.md <<'END' en_AG en_AU en_BW en_CA en_DK en_GB en_HK en_IE en_IN en_NG en_NZ en_PH en_SG en_US en_ZA en_ZM en_ZW zh_CN zh_HK zh_SG zh_TW zu_ZA END
jenkins-agent.sh 描述: 容器启动时与jenkins
利用Java jnlp 进行连接的脚本;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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 #!/bin/sh if [ $# -eq 1 ]; then exec "$@ " else case "$@ " in *"-tunnel " *) ;; *) if [ ! -z "$JENKINS_TUNNEL " ]; then TUNNEL="-tunnel $JENKINS_TUNNEL " fi ;; esac if [ ! -z "$JENKINS_AGENT_WORKDIR " ]; then case "$@ " in *"-workDir" *) echo "Warning: Work directory is defined twice in command-line arguments and the environment variable" ;; *) WORKDIR="-workDir $JENKINS_AGENT_WORKDIR " ;; esac fi if [ -n "$JENKINS_URL " ]; then URL="-url $JENKINS_URL " fi if [ -n "$JENKINS_NAME " ]; then JENKINS_AGENT_NAME="$JENKINS_NAME " fi if [ "$JENKINS_WEB_SOCKET " = true ]; then WEB_SOCKET=-webSocket fi if [ -n "$JENKINS_PROTOCOLS " ]; then PROTOCOLS="-protocols $JENKINS_PROTOCOLS " fi if [ -n "$JENKINS_DIRECT_CONNECTION " ]; then DIRECT="-direct $JENKINS_DIRECT_CONNECTION " fi if [ -n "$JENKINS_INSTANCE_IDENTITY " ]; then INSTANCE_IDENTITY="-instanceIdentity $JENKINS_INSTANCE_IDENTITY " fi JAVA_BIN="java" if [ "$JAVA_HOME " ]; then JAVA_BIN="$JAVA_HOME /bin/java" fi OPT_JENKINS_SECRET="" if [ -n "$JENKINS_SECRET " ]; then case "$@ " in *"${JENKINS_SECRET} " *) echo "Warning: SECRET is defined twice in command-line arguments and the environment variable" ;; *) OPT_JENKINS_SECRET="${JENKINS_SECRET} " ;; esac fi OPT_JENKINS_AGENT_NAME="" if [ -n "$JENKINS_AGENT_NAME " ]; then case "$@ " in *"${JENKINS_AGENT_NAME} " *) echo "Warning: AGENT_NAME is defined twice in command-line arguments and the environment variable" ;; *) OPT_JENKINS_AGENT_NAME="${JENKINS_AGENT_NAME} " ;; esac fi exec $JAVA_BIN $JAVA_OPTS -cp /usr/local /bin/agent.jar hudson.remoting.jnlp.Main -headless $TUNNEL $URL $WORKDIR $WEB_SOCKET $DIRECT $PROTOCOLS $INSTANCE_IDENTITY $OPT_JENKINS_SECRET $OPT_JENKINS_AGENT_NAME "$@ " fi
镜像构建所需软件 备注: 在Jenkins 2.277版本中添加一个新的节点中获取匹配当前版本的 agent.jar, 或者是在 jenkins 官网 https://repo.jenkins-ci.org/public/org/jenkins-ci/main/remoting 进行下载;1 2 3 ~/k8s/jenkins/jnlp-slave$ ls agent.jar build jdk-8u281-linux-x64.tar.gz Jenkins.zip release-cli-0.6.0-linux-amd64 sonar-scanner-cli-4.5.0.2216-linux.zip apache-maven-3.6.3-bin.tar.gz glibc-2.32-r0.apk jenkins-agent.sh kubectl sgerrand.rsa.pub
Dockerfile 构建操作 操作流程 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 ~/k8s/jenkins/jnlp-slave$ python3 -m http.server 8080 Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ... docker build -t weiyigeek/alpine-jenkins-jnlp --platform linux/amd64 . docker images weiyigeek/alpine-jenkins-jnlp --all docker push weiyigeek/alpine-jenkins-jnlp ansible node -m shell -a "docker pull weiyigeek/alpine-jenkins-jnlp"
weiyigeek.top-DockerFile构建自定义Jnlp容器
自定义 jenkins-jnlp-slave 镜像的使用 描述: 此处还是利用Jenkins的kubernetes插件,让jenkins在进job时动态的生成工作节点(Pod),并在结束后销毁容器。
weiyigeek.top-custom-jenkins-jnlp
Dockerfile 迭代更新
截止于【2021年5月17日 16:41:37】最新更新的Dockerfile1 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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 FROM alpine:3.13 .1 MAINTAINER Jenkins Custom Work Node Jnlp Container - <master@weiyigeek.top> - WeiyiGeekARG USERNAME=jenkins \ AGENT_WORKDIR=/home/jenkins \ BASE_DIR=/usr/local \ BASE_BIN=/usr/local/bin \ BASE_URL=http://192.168 .12.107 :8080 \ LOCALE=locale.md \ JDK_NAME=jdk-8 u281-linux-x64 \ JDK_DIR=/usr/local/jdk1.8.0 _281 \ GLIBC_NAME=glibc-2.32 -r0.apk \ GLIBC_BIN_NAME=glibc-bin-2.32 -r0.apk \ GLIBC_I18N_NAME=glibc-i18n-2.32 -r0.apk \ MAVEN_NAME=apache-maven-3.8 .4 -bin \ MAVEN_DIR=/usr/local/apache-maven-3.8 .4 \ SONAR_SCANNER_NAME=sonar-scanner-cli-4.5 .0.2216 -linux \ SONAR_SCANNER_DIR=/usr/local/sonar-scanner-4.5 .0.2216 -linux \ GITLAB_CLI=release-cli-0.10 .0 -linux-amd64 ENV LANG=en_US.UTF-8 \ LC_ALL=en_US.UTF-8 \ JAVA_HOME=/usr/local/jdk8 \ JRE_HOME=/usr/local/jdk8/jre \ MAVEN_HOME=/usr/local/maven \ MAVEN_RPEO=/home/jenkins/.m2 \ SONAR_SCANNER_HOME=/usr/local/sonar-scanner \ NODEJS_MODULES=/usr/lib/node_modules USER rootRUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \ && apk update \ && apk add --no-cache openssh tzdata curl tar sudo git ca-certificates wget unzip docker zlib nodejs npm bash jq \ && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ && chmod 4755 /bin/busybox \ && addgroup -g 1000 -S ${USERNAME} \ && adduser ${USERNAME} -D -g ${USERNAME} -G root -u 1000 -s /bin/sh \ && echo "jenkins ALL=(root) NOPASSWD:ALL" >> /etc/sudoers \ && mkdir -p ${AGENT_WORKDIR} /agent ${AGENT_WORKDIR} /.ssh ${AGENT_WORKDIR} /.m2 \ && wget -q -O /tmp/${GLIBC_NAME} ${BASE_URL} /${GLIBC_NAME} \ && wget -q -O /tmp/${GLIBC_BIN_NAME} ${BASE_URL} /${GLIBC_BIN_NAME} \ && wget -q -O /tmp/${GLIBC_I18N_NAME} ${BASE_URL} /${GLIBC_I18N_NAME} \ && wget -q -O /etc/apk/keys/sgerrand.rsa.pub ${BASE_URL} /sgerrand.rsa.pub \ && wget -q -O /tmp/${LOCALE} ${BASE_URL} /${LOCALE} \ && wget -q -O /tmp/${JDK_NAME} .tar.gz ${BASE_URL} /${JDK_NAME} .tar.gz \ && wget -q -O ${BASE_BIN} /agent.jar ${BASE_URL} /agent.jar \ && curl -fsSL -o ${BASE_BIN} /jenkins-agent.sh ${BASE_URL} /jenkins-agent.sh \ && curl -fsSL -o /tmp/${MAVEN_NAME} .tar.gz ${BASE_URL} /${MAVEN_NAME} .tar.gz \ && curl -fsSL -o /tmp/${SONAR_SCANNER_NAME} .zip ${BASE_URL} /${SONAR_SCANNER_NAME} .zip \ && curl -fsSL -o /usr/local /bin/release-cli ${BASE_URL} /${GITLAB_CLI} \ && curl -fsSL -o /usr/local /bin/kubectl ${BASE_URL} /kubectl \ && curl -fsSL -o /usr/local /bin/docker ${BASE_URL} /docker \ && sed -i "s/#PermitRootLogin.*/PermitRootLogin yes/g" /etc/ssh/sshd_config \ && sed -i "s/^#\s*StrictHostKeyChecking ask/StrictHostKeyChecking no/g" /etc/ssh/ssh_config \ && ssh-keygen -t dsa -P "" -f /etc/ssh/ssh_host_dsa_key \ && ssh-keygen -t rsa -P "" -f /etc/ssh/ssh_host_rsa_key \ && ssh-keygen -t ecdsa -P "" -f /etc/ssh/ssh_host_ecdsa_key \ && ssh-keygen -t ed25519 -P "" -f /etc/ssh/ssh_host_ed25519_key \ && ssh-keygen -t ed25519 -P "" -C "master@weiyigeek.top" -f /home/jenkins/.ssh/id_ed25519 \ && apk add /tmp/${GLIBC_NAME} /tmp/${GLIBC_BIN_NAME} /tmp/${GLIBC_I18N_NAME} \ && tar -zxf /tmp/${JDK_NAME} .tar.gz -C ${BASE_DIR} \ && mv ${JDK_DIR} ${JAVA_HOME} \ && tar -zxf /tmp/${MAVEN_NAME} .tar.gz -C ${BASE_DIR} \ && mv ${MAVEN_DIR} ${MAVEN_HOME} \ && unzip /tmp/${SONAR_SCANNER_NAME} .zip -d ${BASE_DIR} \ && mv ${SONAR_SCANNER_DIR} ${SONAR_SCANNER_HOME} \ && npm config set registry https://registry.npmmirror.com \ && chmod a+x ${BASE_BIN} /* \ && chown -R jenkins:jenkins ${BASE_DIR} / ${AGENT_WORKDIR} / ${NODEJS_MODULES} / \ && echo "root:WeiyiGeek" | chpasswd \ && echo "jenkins:WeiyiGeek" | chpasswd \ && cat /tmp/${LOCALE} | xargs -i /usr/glibc-compat/bin/localedef -i {} -f UTF-8 {}.UTF-8 \ && sed -i "s#use_embedded_jre=true#use_embedded_jre=false#g" ${SONAR_SCANNER_HOME} /bin/sonar-scanner \ && rm -rf /var/cache/apk/* /tmp/* ${SONAR_SCANNER_HOME} /jre/* \ && cd ${JAVA_HOME} \ && rm -rf COPYRIGHT LICENSE README release THIRDPARTYLICENSEREADME-JAVAFX.txt THIRDPARTYLICENSEREADME.txt Welcome.html javafx-src.zip src.zip \ lib/plugin.jar \ lib/ext/jfxrt.jar \ bin/javaws \ lib/javaws.jar \ lib/desktop \ plugin \ lib/deploy* \ lib/*javafx* \ lib/*jfx* \ lib/amd64/libdecora_sse.so \ lib/amd64/libprism_*.so \ lib/amd64/libfxplugins.so \ lib/amd64/libglass.so \ lib/amd64/libgstreamer-lite.so \ lib/amd64/libjavafx*.so \ lib/amd64/libjfx*.so \ && echo "export LANG=zh_CN.UTF-8" > /etc/profile.d/locale.sh USER jenkinsWORKDIR ${AGENT_WORKDIR} ENV CLASSPATH=.:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar \ PATH=${JAVA_HOME}/bin:${MAVEN_HOME}/bin:${SONAR_SCANNER_HOME}/bin:$PATH ENTRYPOINT ["/usr/local/bin/jenkins-agent.sh" ]