K8S - Jenkins在K8S下的持续集成
准备nfs网络存储
[root@master ~]# yum -y install nfs-utils rpcbind
[root@master ~]# systemctl start rpcbind && systemctl enable rpcbind && systemctl status rpcbind
[root@master lv]# mkdir -p /nfsdata/data/jenkins
[root@master ~]# vim /etc/exports/data/jenkins
/nfsdata/data/jenkins *(rw,sync,no_root_squash)
[root@master ~]# systemctl start nfs-server && systemctl enable nfs-server && systemctl status nfs-server
[root@master ~]# showmount -e
Export list for master:
/nfsdata/data/jenkins *
安装Jenkins服务到K8S集群
使用Dockerfile制作Jenkins镜像
下载war包放到Dockerfile文件同一个目录下,Dockerfile如下,war包下载地址:https://mirrors.tuna.tsinghua.edu.cn/jenkins/
yaml文件资源下载地址:
https://gitee.com/fdd-39969/cicd.git git clone https://gitee.com/fdd-39969/cicd.git
cd cicd/jenkins
ls cicd/jenkins/
Dockerfile jenkins-pv.yaml jenkins-svc.yaml rbac.yaml
jenkins-deploy.yaml jenkins-slave jenkins.war
创建Dockerfile文件
FROM java:8
RUN echo 'hello docker, start build image' RUN mkdir -p /app
WORKDIR /app RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo "Asia/Shanghai" > /etc/timezone COPY jenkins.war . CMD ["java" ,"-Xms1024m","-Xmx1024m", "-jar","/app/jenkins.war"]
制作镜像
docker build -t 192.168.166.132/library/jenkins-2.273 .
docker push 192.168.166.132/library/jenkins-2.273
K8S安装Jenkins应用
在k8s集群内创建Jenkins工作的namespace,我这边统一放在devops这个ns底下;
# 创建命名空间
kubectl create ns devops
我这里把Jenkins工作目录单独挂载到PVC,需要先创建pv-pvc,挂载点是使用的nfs服务,请先创建好服务,jenkins-pv-pvc.yaml如下:
kind: PersistentVolume
apiVersion: v1
metadata:
name: jenkins-home-pv
namespace: devops
spec:
accessModes:
- ReadWriteOnce #访问模式定义为只能以读写的方式挂载到单个节点
capacity:
storage: 10Gi
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /nfsdata/data/jenkins
server: 192.168.166.128 ---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: jenkins-home-pvc
namespace: devops
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: nfs #这里指定关联的PV名称
为Jenkins创建单独的ServiceAccount,这里的ClusterRole直接使用的cluster-admin,jenkins-serveraccount.yaml如下;
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app: jenkins
name: jenkins-admin
namespace: devops
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: jenkins-admin
labels:
app: jenkins
subjects:
- kind: ServiceAccount
name: jenkins-admin
namespace: devops
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
jenkins-deployment.yaml如下:
注:如果需要指定在某个节点上运行,需要自行打污点设置 (格式: kubectl label nodes k8s-node1 app.k8s.icj1/devops=)
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins
namespace: devops
labels:
app: jenkins
spec:
replicas: 1
selector:
matchLabels:
app: jenkins
template:
metadata:
labels:
app: jenkins
spec:
serviceAccountName: jenkins-admin
imagePullSecrets:
- name: ram-secret
#affinity:
#nodeAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
#nodeSelectorTerms:
#- matchExpressions:
#- key: apps.k8s.icjl/devops
# operator: Exists
containers:
- name: jenkins
image: 192.168.166.132/library/jenkins-2.273
imagePullPolicy: IfNotPresent
volumeMounts:
- name: jenkins-home
mountPath: /root/.jenkins
readOnly: false
ports:
- containerPort: 8080
- containerPort: 50000
volumes:
- name: jenkins-home
persistentVolumeClaim:
claimName: jenkins-home-pvc # 关联PVC卷
创建service,这边使用了NodePort,jenkins-service.yaml如下;
apiVersion: v1
kind: Service
metadata:
labels:
app: jenkins
name: jenkins
namespace: devops
annotations:
prometheus.io/scrape: 'true'
spec:
type: NodePort
ports:
- name: jenkins-web
port: 8080
targetPort: 8080
nodePort: 30008 # jenkins 地址端口
- name: jenkins-agent
port: 50000
targetPort: 50000
nodePort: 30005 # jenkins 通道端口
selector:
app: jenkins
也可以使用ingress暴露的方式,jenkins-ingress.yaml如下:(我这里没有使用ingress)
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: jenkins
labels:
name: jenkins
namespace: devops
spec:
rules:
- host: jenkins.hiningmeng.cn
http:
paths:
- path: /
backend:
serviceName: jenkins
servicePort: 8080
执行yaml
kubectl apply -f jenkins-pv-pvc.yaml
kubectl apply -f jenkins-serveraccount.yaml
kubectl apply -f jenkins-deployment.yaml
kubectl apply -f jenkins-service.yaml
kubectl apply -f jenkins-ingress.yaml
查看pod状态
[root@k8s-master jenkins]# kubectl get pv,pvc,svc -n devops
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/jenkins-home-pv 10Gi RWO Retain Bound devops/jenkins-home-pvc nfs 44m NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/jenkins-home-pvc Bound jenkins-home-pv 10Gi RWO nfs 44m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/jenkins NodePort 10.111.96.4 <none> 8080:30008/TCP,50000:30005/TCP 44m
[root@k8s-master jenkins]# kubectl get ep -n devops
NAME ENDPOINTS AGE
jenkins 10.244.169.132:50000,10.244.169.132:8080 44m
[root@k8s-master jenkins]# kubectl get pods -n devops
NAME READY STATUS RESTARTS AGE
jenkins-74f44f658-rjfb2 1/1 Running 0 30m
[root@k8s-master jenkins]#
[root@k8s-master jenkins]# kubectl describe pods jenkins-74f44f658-rjfb2 -n devops
---
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 31m default-scheduler Successfully assigned devops/jenkins-74f44f658-rjfb2 to k8s-node2
Normal Pulled 31m kubelet, k8s-node2 Container image "192.168.166.132/library/jenkins-2.273" already present on machine
Normal Created 31m kubelet, k8s-node2 Created container jenkins
Normal Started 31m kubelet, k8s-node2 Started container jenkins # 看到以上这些信息说明启动成功
查看pod日志
kubectl logs jenkins-74f44f658-rjfb2 -n devops
--- # 复制管理员密码
访问Jenkins,如果没有做ingress 使用NodePort+暴露的端口

安装插件
# 进入到nfs共享目录
cd /nfsdata/data/jenkins/updates/
sed -i 's/https:\/\/updates.jenkins.io\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json
sed -i 's/http:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json # 删除pod重建,pod名称改成你实际的
kubectl delete pod jenkins-dccd449c7-vx6sj -n devops # 或者 xxx.yaml 是启动Jenkins pod的yaml文件
kubectl delete -f xxx.yaml
kubectl apply -f xxx.yaml
管理Jenkins->系统配置-->管理插件-->分别搜索Git Parameter/Git/Pipeline/kubernetes/Config
配置Kubernetes云信息
在系统管理 --> 系统设置 ,最后面有个Cloud设置,Add a new cloud

添加具体的Kubernetes信息,K8S服务器可以是Jenkins本身所在的服务器,也可以是其他集群(需要配置证书),这里以本身所在集群为例。
- 名称 :用于pipeline调用云名称
- Kubernetes地址:可以通过kubectl cluster-info命令获取
- Kubernetes 服务证书 key:本身所在的集群因为我们通过sa所以不需要
- Kubernetes 命名空间:Jenkins的nodePod节点启动的namespace
- Jenkins 地址:主节点8080端口通过nodeport暴露出来的,地址:端口
- Jenkins 通道:主节点50000端口通过nodeport暴露出来的,地址:端口

构建Slave镜像 - 课件目录里涉及四个文件:Dockerfile:构建镜像jenkins-slave:shell脚本启动slave.jarsettings.xml:修改maven官方源为阿里云源slave.jar:agent程序,接受master下发的任务
slave镜像资源下载地址:
https://gitee.com/fdd-39969/cicd.git
git clone https://gitee.com/fdd-39969/cicd.git
Dockerfile文件内容如下:
[root@k8s-master jenkins]# cd jenkins-slave/
[root@k8s-master jenkins-slave]# ls
Dockerfile jenkins-slave kubectl settings.xml slave.jar
[root@k8s-master jenkins-slave]#
[root@k8s-master jenkins-slave]#
[root@k8s-master jenkins-slave]# cat Dockerfile
FROM centos:7
LABEL maintainer fengyuanfei RUN yum install -y java-1.8.0-openjdk maven curl git libtool-ltdl-devel && \
yum clean all && \
rm -rf /var/cache/yum/* && \
mkdir -p /usr/share/jenkins COPY slave.jar /usr/share/jenkins/slave.jar
COPY jenkins-slave /usr/bin/jenkins-slave
COPY settings.xml /etc/maven/settings.xml
RUN chmod +x /usr/bin/jenkins-slave
COPY kubectl /usr/bin/ ENTRYPOINT ["jenkins-slave"]
构建并推送到镜像仓库:
docker build -t 192.168.166.132/library/jenkins-slave-jdk .
docker push 192.168.166.132/library/enkins-slave-jdk
war包可以通过添加 new新节点 获取下载


编写Pipeline脚本
// 公共
def registry = "reg.ctnrs.com"
// 项目
def project = "dev"
def app_name = "java-demo"
def image_name = "${registry}/${project}/${app_name}:${BUILD_NUMBER}"
def git_address = "http://192.168.31.70:9999/root/java-demo.git"
// 认证
def secret_name = "registry-pull-secret"
def docker_registry_auth = "c333c561-73af-43a7-bad8-83c9b9433916"
def git_auth = "d946c462-bec9-4b5b-9b77-9af538dd1776"
def k8s_auth = "d2374738-3c6f-4077-aa55-186b74c50002" pipeline {
agent {
kubernetes {
label "jenkins-slave"
yaml """
kind: Pod
metadata:
name: jenkins-slave
spec:
containers:
- name: jnlp
image: "${registry}/library/jenkins-slave-jdk:1.8"
imagePullPolicy: Always
volumeMounts:
- name: docker-cmd
mountPath: /usr/bin/docker
- name: docker-sock
mountPath: /var/run/docker.sock
- name: maven-cache
mountPath: /root/.m2
volumes:
- name: docker-cmd
hostPath:
path: /usr/bin/docker
- name: docker-sock
hostPath:
path: /var/run/docker.sock
- name: maven-cache
hostPath:
path: /tmp/m2
"""
} }
parameters {
gitParameter branch: '', branchFilter: '.*', defaultValue: 'master', description: '选择发布的分支', name: 'Branch', quickFilterEnabled: false, selectedValue: 'NONE', sortMode: 'NONE', tagFilter: '*', type: 'PT_BRANCH'
choice (choices: ['1', '3', '5', '7'], description: '副本数', name: 'ReplicaCount')
choice (choices: ['dev','test','prod'], description: '命名空间', name: 'Namespace')
}
stages {
stage('拉取代码'){
steps {
checkout([$class: 'GitSCM',
branches: [[name: "${params.Branch}"]],
doGenerateSubmoduleConfigurations: false,
extensions: [], submoduleCfg: [],
userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_address}"]]
])
}
} stage('代码编译'){
steps {
sh """
mvn clean package -Dmaven.test.skip=true
"""
}
} stage('构建镜像'){
steps {
withCredentials([usernamePassword(credentialsId: "${docker_registry_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
sh """
echo '
FROM ${registry}/library/tomcat:v1
LABEL maitainer lizhenliang
RUN rm -rf /usr/local/tomcat/webapps/*
ADD target/*.war /usr/local/tomcat/webapps/ROOT.war
' > Dockerfile
docker build -t ${image_name} .
docker login -u ${username} -p '${password}' ${registry}
docker push ${image_name}
"""
}
}
}
stage('部署到K8S平台'){
steps {
configFileProvider([configFile(fileId: "${k8s_auth}", targetLocation: "admin.kubeconfig")]){
sh """
sed -i 's#IMAGE_NAME#${image_name}#' deploy.yaml
sed -i 's#SECRET_NAME#${secret_name}#' deploy.yaml
sed -i 's#REPLICAS#${ReplicaCount}#' deploy.yaml
kubectl apply -f deploy.yaml -n ${Namespace} --kubeconfig=admin.kubeconfig
"""
}
}
}
}
}
构建测试
第一步测试:
pipeline {
agent {
kubernetes {
label "jenkins-slave"
yaml '''
apiVersion: v1
kind: Pod
metadata:
name: jenkins-slave
spec:
containers:
- name: jnlp
image: 192.168.166.132/library/jenkins-slave-jdk:1.8
'''
}
}
stages {
stage('第一步测试') {
steps {
sh 'hostname'
}
}
}
}


\未完。。。待续。。。
K8S - Jenkins在K8S下的持续集成的更多相关文章
- 构建gitlab+Jenkins+harbor+kubernetes的DevOps持续集成持续部署环境
构建gitlab+Jenkins+harbor+kubernetes的DevOps持续集成持续部署环境 整个环境的结构图. 一.准备工作 gitlab和harbor我是安装在kubernetes集群外 ...
- 使用Maven+Nexus+Jenkins+Svn+Tomcat+Sonar搭建持续集成环境(二)
前言 上一篇随笔Maven+Nexus+Jenkins+Svn+Tomcat+Sonar搭建持续集成环境(一)介绍maven和nexus的环境搭建,以及如何使用maven和nexus统一管理库 ...
- Jenkins+maven+git+sonar 系统持续集成&代码单測管理
Jenkins+maven+git+sonar 系统持续集成&代码单測管理 Jenkins的安装 Jenkins是基于Java开发的一种持续集成工具,用于监控持续反复的工作.功能包含: 1.持 ...
- Maven+Nexus+Jenkins+Svn+Tomcat+Sonar搭建持续集成环境(二)
上一篇随笔Maven+Nexus+Jenkins+Svn+Tomcat+Sonar搭建持续集成环境(一)介绍maven和nexus的环境搭建,以及如何使用maven和nexus统一管理库文件和版本,以 ...
- 使用Maven+Nexus+Jenkins+Svn+Tomcat+Sonar搭建持续集成环境
前言 但凡一个略有规模的项目都需要一个持续集成环境的支撑,为什么需要持续集成环境,我们来看一个例子.假如一个项目,由A.B两位程序员来协作开发,A负责前端模块,B负责后端模块,前端依赖后端.A和B都习 ...
- Maven+Nexus+Jenkins+Svn+Tomcat+Sonar搭建持续集成环境
使用Maven+Nexus+Jenkins+Svn+Tomcat+Sonar搭建持续集成环境(一) 2015-01-14 20:28 by 飘扬的红领巾, 4322 阅读, 5 评论, 收藏, 编辑 ...
- 使用Jenkins+Calabash+Cocoapods搭建iOS持续集成环境
使用jenkins+calabash+cocoapods搭建ios持续集成环境 持续集成 持续集成到底是什么呢?依据敏捷大师Martin Fowler的定义: 持续集成是一种软件开发实践. 在持续集成 ...
- Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成(上)
Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成(上) Jenkins+Docker+SpringCloud持续集成流程说明 大致流程说明: 1) 开发 ...
- Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成——部署方案优化
Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成--部署方案优化 之前我们做的方案部署都是只能选择一个微服务部署并只有一台生产服务器,每个微服务只有一个 ...
- Jenkins+Gitlab CE+Robot Framework持续集成
环境 Ubuntu 14.04.3 LTS Desktop 前提 1.在本地能执行测试脚本(pybot yourTestSuit.txt),本文不讲解如何学习使用RF框架 2.已有Gitlab环境,本 ...
随机推荐
- 即构 SDK 6月迭代:新增拉流画面镜像等功能,为开发者提供更大便利
即构SDK6月新版本已上线,本月SDK迭代主要新增了拉流画面镜像功能,媒体播放器新增支持缓存相关的设置,新增支持设置对焦模式和曝光模式等功能,多个功能模块的灵活设置,让开发者能更便利的自定义选择,为用 ...
- tensorflow神经网络归一化方法
参考https://blog.csdn.net/chary8088/article/details/81542879
- Bash 内建命令
官方文档 Bash内建命令 查看命令是否为Bash内建命令
- 《最新出炉》系列入门篇-Python+Playwright自动化测试-10-标签页操作(tab)
1.简介 标签操作其实也是基于浏览器上下文(BrowserContext)进行操作的,而且宏哥在之前的BrowserContext也有提到过,但是有的童鞋或者小伙伴还是不清楚怎么操作,或者思路有点模糊 ...
- HTML超文本标记语言4
框架标签...等等 1.框架 <frameset> 框架标签 cols="按列划分" rows="按行划分" 格式:rows="100,* ...
- 蜂鸟E203 仿真之路
本文记录自己在学习蜂鸟E203的过程.下面简单介绍一下仿真之路所遇到的困难和走过的坑. 1.环境开发 :一般选择ubuntu 18.04 这个版本,安装这个教程很多,可以自行学习. 2.在Linux中 ...
- 新一代开源流数据湖平台Apache Paimon入门实操-下
@ 目录 实战 写表 插入和覆盖数据 更新数据 删除数据 Merge Into 查询表 批量查询 时间旅行 批量增量查询 流式查询 时间旅行 ConsumerID 查询优化 系统表 表指定系统表 分区 ...
- Android13冻结进程分析:如何提高设备性能和用户体验
Android13冻结进程分析:如何提高设备性能和用户体验 本文介绍了Android13中的冻结进程功能,它是一种重要的资源管理策略,可以提高系统性能和稳定性,同时最大限度地节省设备的资源和电池消耗. ...
- CF1787E The Harmonization of XOR 题解
CF1787E The Harmonization of XOR 题目大意 给定 \(n\) 个数 \([1, 2, 3, \cdots, n]\) 和两个正整数 \(k\) 和 \(x\). 将这些 ...
- 三维模型OBJ格式轻量化压缩变形现象分析
三维模型OBJ格式轻量化压缩变形现象分析 三维模型的OBJ格式轻量化压缩是一种常见的处理方法,它可以减小模型文件的体积,提高加载和渲染效率.然而,在进行轻量化压缩过程中,有时会出现模型变形的现象,即压 ...