欢迎关注「WeiyiGeek」公众号
点击 下方卡片 即可关注我哟!
设为「星标⭐」每天带你 基础入门 到 全栈实践 再到 放弃学习!
涉及 网络安全运维、应用开发、物联网IOT、学习路径 、个人感悟 等知识
“ 花开堪折直须折,莫待无花空折枝。 ”
本章目录:
0x00 前言简述
0x01 基础环境准备
1.环境说明
2.添加新的Jenkins Agent节点
3.自行构建Jenkins Agent镜像(干货)
0x02 项目实践
1.使用在K8S部署的Jenkins连接Docker容器中运行的Agent分布式节点 (缺省端口:50000)
2.使用在K8S部署的Jenkins连接Docker容器中运行的自定义Agent端口节点 (直连方式)
0x03 实践调用Jenkins agent节点
1.牛刀小试
2.完整的pipeline流水线企业项目
0x00 前言简述
看过我前面Jenkins学习之路的朋友肯定知道,在Kubenetes中使用Jenkins可以进行动态生成分布式jnlp-slave的agent节点,相比于传统的agent节点来说极大的节约资源。
但是某一天开发反馈某个项目CICD无法正常进行,作为运维人员(搬砖)立马进入K8S集群,排除安装在集群中的Jenkins的异常问题,排查可知由于K8S集群证书到期导致动态jenkins agent节点无法正常被创建,此时项目又比较紧急。
遂利用装有Docker的机器,立即使用自行构建的jenkins-jnlp-agent镜像,并在 jenkins 中创建一个固定节点,通过docker运行该镜像并连接到Jenkins,在流水线项目绑定到该节点执行,通过几分钟的时间就快速解决了jenkins agent问题,在项目完成持续集成和交互后,趁着间隙更新Jenkins上配置连接kubernetes apiserver的证书,恢复了动态生成agent节点。
所以,为了便于自己总结知识,以及有相同需求的看友,遂将jenkins外部agent节点接入以及自行构建jnlp-agent镜像流程进行实践,希望能帮助到大家。
如果此篇文章对你有用,请您也转发、点赞、在看、给周边的朋友吧!
温馨提示: 若需要企业 Jenkins Pipeline 流水线脚本的朋友,可以关注【WeiyiGeek】或【全栈工程师修炼指南】公众号后获得 Jenkins-Pipeline.groovy
示例文件。
完整原文地址: 持续集成案例之使用Docker运行自构建Jenkins的Agent镜像固定工作节点实践(分享企业项目流水线代码)分享企业项目Jenkins流水线代码,并使用Docker运行自构建Jenkins的Agent镜像固定工作节点实践,看过我前面Jenkins学习之路的朋友肯定知道,在K8s中使用Jenkins可以进行动态生成分布式的agent节点。https://mp.weixin.qq.com/s/d-n6nG8egr9c2mg7b03IKQ
0x01 基础环境准备
1.环境说明
# 1.K8s 集群中安装的 Jenkins
~$ kubectl get pod,svc -n devops -l app=jenkins
NAME READY STATUS RESTARTS AGE
pod/jenkins-7fc6f4fcf6-glqxj 1/1 Running 0 28h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/jenkins NodePort 10.109.163.223 8080:30001/TCP,50000:30634/TCP 382d
# 2.Jenkins 安装版本
Jenkins 2.330
# 3.地址说明
Jenkins 面板: http://192.168.12.107:30001/
TCP port for inbound agents(Agent 端口): http://192.168.12.107:30634/ ( 内部为 50000,若是在集群中使用则需要将nodePort端口改成,可通过转发的形式 因为K8S默认nodePort范围在 30000-32767 之中)
温馨提示: 我们需要修改 Jenkins Agent 端口 可以访问 Dashboard 全局安全配置 -> 代理 (TCP port for inbound agents) 指定端口设置为 30634,注意相对应Pod暴露的端口也要一同修改。
$ kubectl edit deployments.apps -n devops jenkins
ports:
- containerPort: 8080
name: web
protocol: TCP
- containerPort: 30634 # 修改点
name: agent
protocol: TCP
$ kubectl edit svc -n devops jenkins
- name: agent
nodePort: 30634
port: 30634 # 修改点与 containerPort 要一致。
protocol: TCP:q
targetPort: agent
# 验证查看 Pod 与 服务是否正常
$ kubectl get svc,pod -n devops -l app=jenkins
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/jenkins NodePort 10.109.163.223 8080:30001/TCP,30634:30634/TCP 382d
NAME READY STATUS RESTARTS AGE
pod/jenkins-856bc9b47f-4t7k5 1/1 Running 0 2m9s
或者采用如下临时解决办法(下面实践1中采用的是此种方法,正式环境下还是建议使用上面的方法稳定,但是需要更改和注意的事项更多了)
$ kubectl -n devops port-forward --address 127.0.0.1,192.168.12.107 jenkins-7fc6f4fcf6-glqxj 50000:50000
# Forwarding from 127.0.0.1:50000 -> 50000
# Forwarding from 192.168.12.107:50000 -> 50000
# Handling connection for 50000
# Handling connection for 50000
# 或者在 jenkins 控制器资源清单中设置 hostNetwork: true
温馨提示: 若看友不了解Jenkins持续集成的,或者需要安装实践的,可以参考博主学习【Jenkins学习之路汇总】汇总,关注公众号后回复【jenkins学习之路
】即可获得学习资料:
2.添加新的Jenkins agent节点
操作步骤如下: Dashboard 系统管理 -> 节点管理 -> 新建节点 -> 按照提示输入如下信息 -> 最后点击保存
# 基础配置
节点名字: docker-jenkins-jnlp
Number of executors (最大执行数): 1~5
远程工作目录: /home/jenkins/agent
标签: docker-jnlp-1
启动方式: 通过 Java Web 启动代理
可用性: 尽量保持代理在线
# 节点属性
- 工具位置: 请按照实际情况填写。
# 例如, Docker 配置,名称 Docker ,目录 /var/run/docker.sock
- 环境变量:
# 例如,键值对列表,键 name 值 weiyigeek
温馨提示: 在点击保存后,我们可以点击此节点,看到其提示节点连接Jenkins的方式如下:
# 方式1
java -jar agent.jar -jnlpUrl http://192.168.12.107:30001/computer/docker%2Djenkins%2Djnlp/jenkins-agent.jnlp -secret b97b9d1e0cf083f9da5721caa6ebc63f6fe648375bd90cb2c2f484681d887bb7 -workDir "/home/jenkins/agent"
java -Xms512m -Xmx1g -Xss1m -jar /usr/local/bin/agent.jar -jnlpUrl http://192.168.12.107:30001/computer/jenkinsAgentWork1/jenkins-agent.jnlp -secret 2a789bbbd0193ef576e7b62eb2d205d1d024d0ea7b14f6f79f1cccdd6fb1ed20 -workDir "/home/jenkins/agent"
# 方式2
# Run from agent command line, with the secret stored in a file:
echo b97b9d1e0cf083f9da5721caa6ebc63f6fe648375bd90cb2c2f484681d887bb7 > secret-file
java -jar agent.jar -jnlpUrl http://192.168.12.107:30001/computer/docker%2Djenkins%2Djnlp/jenkins-agent.jnlp -secret @secret-file -workDir "/home/jenkins/agent"
3.自行构建Jenkins Agent镜像(干货)
描述: 在关注【WeiyiGeek】或者【全栈工程师修炼指南】公众号,即可获取最新Jenkins-jnlp镜像构建的Dockerfile及下述相关脚本文件,此处我们自定义的jnlp容器镜像主要实现功能如下:
用户权限控制(sudo)
ssh 远程连接
git 代码版本控制
docker 容器管理
kubectl 集群管理
Java 运行环境
Maven 运行环境
NodeJS 环境
SonarQube 扫描环境
Gitlab-Release 上传环境
中文环境支持
时区更改配置
自定义工作目录(/home/jenkins/agent)
温馨提示: 如下操作构建依赖于Docker环境,若你没有安装Docker环境或者不了解的Docker容器的朋友,可以参考博主学习【Docker的系列笔记】汇总,关注 WeiyiGeek
公众号回复【Docker容器学习之路汇总
】即可获得学习资料:
构建目录
~/k8s/jenkins/jnlp-slave$ tree .
.
├── agent.jar # Jenkins -> 2.330
├── agent.jar.bak
├── apache-maven-3.8.4-bin.tar.gz
├── build
│ └── Dockerfile
├── docker
├── glibc-2.32-r0.apk
├── glibc-bin-2.32-r0.apk
├── glibc-i18n-2.32-r0.apk
├── jdk-8u281-linux-x64.tar.gz
├── jenkins-agent.sh
├── kubectl
├── locale.md
├── release-cli-0.10.0-linux-amd64
├── remoting-4.11.2.jar
├── sgerrand.rsa.pub
└── sonar-scanner-cli-4.5.0.2216-linux.zip
1 directory, 16 files
温馨提示: 在Jenkins 2.330版本中添加一个新的节点, 即可获取匹配当前版本的 agent.jar (http://youjenkins-domainname-or-ip/jnlpJars/agent.jar), 或者是在 jenkins 官网 https://repo.jenkins-ci.org/public/org/jenkins-ci/main/remoting 进行下载;
自定义jnlp镜像的 Dockerfile
博主自定义jnlp镜像hub地址: https://hub.docker.com/r/weiyigeek/alpine-jenkins-jnlp 。
$ cat build/Dockerfile
#----------------------------------------------------------------------#
# Title: Base in Alpine Images Create Custom Jenkins Kubernetes jnlp Images
# Author: WeiyiGeek
# WebSite: https://weiyigeek.top
# Email: [email protected]
# Version: v1.12
# Image Version: alpine-3.13.1
# ChangeLog:
# v1.8 - 增加 docker
# v1.9 - 增加 中文环境
# v1.10 - 增加 node.js 环境支持
# v1.11 - 更新依赖软件版本及其agent.jar版本
#-------------------------------------------------#
FROM alpine:3.13.1
MAINTAINER Jenkins Custom Work Node Jnlp Container - - WeiyiGeek
ARG 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-8u281-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
# 用户ROOT切换
USER root
# Shell 命令 - 此种方式极大减少了构建的镜像大小;
RUN 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}/.ssh ${AGENT_WORKDIR}/.m2 ${AGENT_WORKDIR}/agent\
&& 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 "[email protected]" -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.npm.taobao.org \
&& 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"]
各组件模块版本:
# MainFunction:
# Install ssh-server docker git openssh tzdata curl tar sudo git ca-certificates wget unzip docker zlib nodejs npm jq
# Install JDK8 Version: 1.8.0_281
# - https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html
# - https://github.com/sgerrand/alpine-pkg-glibc/releases/
# - https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub
# Install jnlp Version: 4.11.2 (两种方式都可以下载agent)
# - https://repo.jenkins-ci.org/public/org/jenkins-ci/main/remoting/
# - http://youjenkins-domainname/jnlpJars/agent.jar
# Install Maven Version: 3.8.4
# - https://apache.osuosl.org/maven/maven-3/${MAVEN_VERSION}/binaries
# Install SonarqubeScan Version: 4.5.0
# - https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.5.0.2216-linux.zip
# Install Gitlab Release Version: 0.10.0
# - https://gitlab.com/gitlab-org/release-cli/-/releases
# Install kubernetes cli
# - kubectl Version: 1.23.1
# Install docker cli
# - kubectl Version: 20.10.3
镜像构建操作流程
....
完整原文地址: 持续集成案例之使用Docker运行自构建Jenkins的Agent镜像固定工作节点实践(分享企业项目流水线代码)分享企业项目Jenkins流水线代码,并使用Docker运行自构建Jenkins的Agent镜像固定工作节点实践,看过我前面Jenkins学习之路的朋友肯定知道,在K8s中使用Jenkins可以进行动态生成分布式的agent节点。https://mp.weixin.qq.com/s/d-n6nG8egr9c2mg7b03IKQ