jenkins cicd k8s 多分支流水线构建
环境:centos7.6 、Docker version 19.03.5、Jenkins 2.249.3(jackson = 2.11.2、docker plugin = 1.2.1)主要思想: 使用 docker plugin 配置一个动态的docker jenkins jnlp slave,该镜像中包含 mvn、git、docker、kubectl 等命令。创建多分支流水线,Jenkinsfi
环境:centos7.6 、Docker version 19.03.5、Jenkins 2.249.3(jackson = 2.11.2、docker plugin = 1.2.1)
主要思想: 使用 docker plugin 配置一个动态的docker jenkins jnlp slave,该镜像中包含 mvn、git、docker、kubectl 等命令。创建多分支流水线,Jenkinsfile 使用前面配置好的 jenkins slave。在该 jenkins slave 中执行 maven 构建、docker build、jave 、kubectl apply 等操作。
1、配置动态 docker jenkins jnlp slave,参考 https://blog.csdn.net/Man_In_The_Night/article/details/111614431
2、创建 k8s 和 docker hub credential。参考 https://blog.csdn.net/Man_In_The_Night/article/details/111614431
3、创建一个 springboot java web 项目,见 github 项目 https://github.com/pretendhigh/javawebdemo
Jenkinsfile 如下:
node("mapleaves") {
def APP_NAME = "javaWebDemo"
def APP_PORT = "8081"
def NODE_PORT_DEV = "30040"
def NODE_PORT_PRO = "32040"
def REPLICAS = "1"
def cicd_admin = "mapleaves"
def myRepo = checkout scm
def gitCommit = myRepo.GIT_COMMIT
def gitBranch = myRepo.GIT_BRANCH
def imageTag = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim()
def imageEndpoint = "mapleaves/javawebdemo-${gitBranch}"
def IMAGE = "${imageEndpoint}:${imageTag}"
if (gitBranch != 'dev' && gitBranch != 'master'){
echo "${gitBranch} 分支不参与执行,开始退出,如有疑问,请联系运维人员 ${cicd_admin}"
return
}
stage('SonarQube 代码检测') {
echo "============================== 1.代码检测阶段 =============================="
echo "branch name is ${gitBranch}"
if (gitBranch == 'dev' ){
echo "branch name is ${gitBranch}"
// 此处可以调用 sonarqube,这里不展开,可以参考 jenkinsfile-demo
} else {
echo "${gitBranch} 分支不做代码检测,如有疑问,请联系运维人员 ${cicd_admin}"
}
}
stage('代码编译打包') {
echo "============================== 2.代码编译打包阶段 =============================="
try {
sh "ls"
sh "ls target"
sh "mvn clean package -s settings.xml -Dmaven.test.skip=true"
sh "ls"
sh "ls target"
} catch (exc) {
println "构建失败 - ${currentBuild.fullDisplayName}"
throw(exc)
}
}
stage('构建 Docker 镜像') {
echo "============================== 3.构建 Docker 镜像阶段 =============================="
withCredentials([[$class: 'UsernamePasswordMultiBinding',
credentialsId: 'mydockerhub',
usernameVariable: 'dockerHubUser',
passwordVariable: 'dockerHubPassword']]) {
// 此处可以使用 harbor,这里不展开,可以参考 jenkinsfile-demo
sh """
sed -i 's/<APP_PORT>/${APP_PORT}/g' Dockerfile
docker login -u ${dockerHubUser} -p ${dockerHubPassword}
docker build -t ${IMAGE} .
docker push ${IMAGE}
"""
}
}
stage('部署 recommend-system 到 infra-k8s') {
echo "============================== 4.部署 recommend-system ${gitBranch} 分支到 infra-k8s =============================="
if (gitBranch == 'master') {
input "确认要部署到生产环境吗?"
NAMESPACE = "pro"
NODE_PORT = "${NODE_PORT_PRO}"
}
if (gitBranch == 'dev') {
NAMESPACE = "dev"
NODE_PORT = "${NODE_PORT_DEV}"
}
withKubeConfig([credentialsId: 'infra-k8s',contextName: 'kubernetes',]) {
sh """
sed -i 's/<APP_NAME>/${APP_NAME}/g' k8s.yaml
sed -i 's/<APP_PORT>/${APP_PORT}/g' k8s.yaml
sed -i 's/<NODE_PORT>/${NODE_PORT}/g' k8s.yaml
sed -i 's/<REPLICAS>/${REPLICAS}/g' k8s.yaml
sed -i 's?<IMAGE>?${IMAGE}?g' k8s.yaml
sed -i 's/<NAMESPACE>/${NAMESPACE}/g' k8s.yaml
"""
sh "kubectl apply -f k8s.yaml --record"
}
}
}
Dockerfile 如下:
FROM openjdk:8-jdk-alpine
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
ENV TZ=Asia/Shanghai
RUN mkdir /app
WORKDIR /app
COPY target/javawebdemo-1.0-SNAPSHOT.jar /app/javawebdemo.jar
EXPOSE <APP_PORT>
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "--server.port=<APP_PORT>", "javawebdemo.jar"]
k8s.yaml 如下:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: <APP_NAME>
namespace: <NAMESPACE>
labels:
app: <APP_NAME>
spec:
replicas: <REPLICAS>
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
labels:
app: <APP_NAME>
spec:
restartPolicy: Always
hostAliases:
- ip: "10.2.7.1"
hostnames:
- "kafka01"
- ip: "10.2.7.9"
hostnames:
- "kafka02"
containers:
- image: <IMAGE>
name: <APP_NAME>
imagePullPolicy: IfNotPresent
ports:
- containerPort: <APP_PORT>
name: api
resources:
limits:
cpu: 800m
memory: 1200Mi
requests:
cpu: 50m
memory: 600Mi
---
kind: Service
apiVersion: v1
metadata:
name: <APP_NAME>
namespace: <NAMESPACE>
spec:
selector:
app: <APP_NAME>
type: NodePort
ports:
- name: api-port
port: 8080
targetPort: api
nodePort: <NODE_PORT>
4、创建一个多分支流水线
设置 github 代码仓库 https://github.com/pretendhigh/javawebdemo (gitlab 仓库同理),如果是私有仓库,需要设置 github crendential,可以参考
https://docs.github.com/cn/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token
https://stackoverflow.com/questions/61105368/how-to-use-github-personal-access-token-in-jenkins
选择每 5 分钟扫描一次代码仓库
5、当有 github 仓库有代码更新或者点击“立即构建” 就可以执行流水线了。
推荐使用私有 gitlab 和 harbor 代替 github 和 docker hub,不然由于网络原因,容易 timeout。
更多推荐
所有评论(0)