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环境,本 ...
随机推荐
- 为什么使用ioutil.ReadAll 函数需要注意
1. 引言 当我们需要将数据一次性加载到内存中,ioutil.ReadAll 函数是一个方便的选择,但是ioutil.ReadAll 的使用是需要注意的. 在这篇文章中,我们将首先对ioutil.Re ...
- 飞桨paddlespeech语音唤醒推理C定点实现
前面的文章(飞桨paddlespeech语音唤醒推理C浮点实现)讲了飞桨paddlespeech语音唤醒推理的C浮点实现.但是嵌入式设备通常CPU频率低和memory小,在嵌入式设备上要想流畅的运行语 ...
- 应用debezium将postgresql数据送至kafka(官网示例,本地docker部署)
版本 conncet 2.2 postgresql 15.2 1 postgresql 1.1 获取 docker pull debezium/example-postgres 1.2 运行 dock ...
- 2021-3-9 excel导出
public void ExportExcel(DataTable dt) { //要添加epplus的nuget包 ExcelPackage.LicenseContext = LicenseCont ...
- 【go语言】3.1.2 接口的定义和实现
在 Go 中,接口是一种抽象类型,用来描述其他类型应该有哪些方法.它定义了一组方法,但没有实现.这些方法由其他类型实现. 接口的定义 接口定义的格式如下: type InterfaceName int ...
- 【pandas小技巧】--缺失值的列
在实际应用中,数据集中经常会存在缺失值,也就是某些数据项的值并未填充或者填充不完整.缺失值的存在可能会对后续的数据分析和建模产生影响,因此需要进行处理. pandas提供了多种方法来处理缺失值,例如删 ...
- [prometheus]配置alertmanager和钉钉告警
目录 prometheus发起告警的逻辑 节点 配置alertmanager 配置钉钉告警插件 配置supervisor守护进程 关联prometheus和alertmanager prometheu ...
- DASCTF 2023 & 0X401七月暑期挑战赛
比赛只出了一道,小菜不是罪过-_- controlflow 这个题动调到底就行 for i in range(40): after_xor[i]=inp[i]^0x401 after_xor[i] + ...
- 如何在linux上安装neovim0.9(以debian和ubuntu为例) – 东凭渭水流
发布于 1 分钟前 3 次阅读 由于apt中只有neovim-0.72的安装包.想使用新版需要自己安装,以下是安装过程 1.首先需要卸载旧版neovim sudo remove neovim 2.从 ...
- Android源码-生成系统签名文件
一.生成keystore签名文件 android 源码目录build\target\product\security 取platform.pk8 platform.x509.pem放到一个目录下 生成 ...