将练习jenkins使用pipeline项目,结合k8s发布一个简单的springboot项目
前提:jenkins的环境和k8s环境都已经安装完成,提前准备了gitlab和一个简单的springboot项目
创建一个流水线项目
流水线中选择git,并选择gitlab的test项目,拉取分支为main
后端代码整体结构如下
jenkinsfile
在代码根目录下创建一个Jenkinsfile文件
需要注意的是environment中的value比如gitlab访问凭证gitlab-root一定要和jenkins中配置的凭证名称一致
Groovy
pipeline {
//agent 选择jenkins节点进行构建
//any表示任意
agent any
//环境变量
environment {
//gitlab访问凭证
GIT_CREDENTIAL_ID = 'gitlab-root'
//gitlab地址
GIT_REPO_URL = '10.190.9.23:28080'
//gitlab分组
GIT_GROUP = 'devops'
//gitlab项目名称
GIT_NAME = 'test'
//harbor凭证
HARBOR_ID = 'harbor-admin'
//harbor地址
HARBOR_URL = '30.14.181.51:8858'
//harbor项目
HARBOR_REPO = 'repo'
//发送delpoment.yml到k8s服务器上的地址
K8S_FILE_PATH = '/usr/local/k8s'
//gitlab发送到服务器的目录
GITLAB_DEPLOYMENT_FILE = 'deploy'
}
parameters {
//git插件 分支参数
gitParameter(
branchFilter: '.*',
defaultValue: "${env.BRANCH_NAME ?: 'main'}",
name: 'BRANCH_NAME',
type: 'PT_BRANCH',
description: '请选择要发布的分支'
)
//git插件 标签参数
gitParameter(
branchFilter: '.*',
defaultValue: "${env.TAG_NAME ?: 'v:1.0.0'}",
name: 'TAG_NAME',
type: 'PT_TAG',
description: '请选择要发布的标签'
)
}
stages {
stage("基本信息输出"){
steps{
echo '选定待发布信息'
echo "项目地址 ${GIT_REPO_URL}"
echo "项目组 ${GIT_GROUP}"
echo "项目名 ${GIT_NAME}"
echo "分支 ${BRANCH_NAME}"
echo "TAG ${TAG_NAME}"
}
}
stage('拉取gitlab代码') {
steps {
//拉取gitlab代码,选择分支
checkout scmGit(
branches: [
[name: env.BRANCH_NAME]
],
extensions: [],
userRemoteConfigs: [
[
credentialsId: env.GIT_CREDENTIAL_ID,
url: "http://${env.GIT_REPO_URL}/${env.GIT_GROUP}/${env.GIT_NAME}.git"
]
]
)
echo '拉取gitlab代码 --SUCCESS'
}
}
stage('Maven构建项目') {
steps {
//maven构建项目打包
//maven命令位置 /var/jenkins_home/apache-maven-3.9.3
sh "/var/jenkins_home/apache-maven-3.9.3/bin/mvn clean package -DskipTests"
echo 'Maven构建项目 --SUCCESS'
}
}
stage('通过docker制作镜像') {
steps {
//docker制作镜像
//将maven打包的jar移动到docker目录下
//使用dockerfile进行构建镜像,镜像名称为 项目名:标签
sh """
mv target/*.jar docker/
docker build -t ${env.GIT_NAME}:${env.TAG_NAME} docker/
"""
echo '通过docker制作镜像 --SUCCESS'
}
}
stage('推送镜像到harbor') {
steps {
//使用harbor凭证推送镜像
withCredentials([
usernamePassword(
credentialsId: env.HARBOR_ID,
passwordVariable: 'DOCKER_PASSWORD',
usernameVariable: 'DOCKER_USERNAME'
)
]) {
//打标签为远程仓库标签
//登陆到harbor
//推送镜像
sh """
docker tag ${env.GIT_NAME}:${env.TAG_NAME} ${env.HARBOR_URL}/${env.HARBOR_REPO}/${env.GIT_NAME}:${env.TAG_NAME}
echo "\$DOCKER_PASSWORD" | docker login -u "\$DOCKER_USERNAME" -p "\$DOCKER_PASSWORD" ${env.HARBOR_URL}
docker push ${env.HARBOR_URL}/${env.HARBOR_REPO}/${env.GIT_NAME}:${env.TAG_NAME}
"""
}
echo '推送镜像到harbor --SUCCESS'
}
}
stage('发送k8s部署yml文件至目标服务器') {
steps {
//使用ssh插件 发送deploy目录下的部署yml文件到目标服务器
//须提前配置ssh免密登陆
sshPublisher(
publishers: [
sshPublisherDesc(
configName: 'k8s',
transfers: [
sshTransfer(
cleanRemote: false,
excludes: '',
execCommand: '',
execTimeout: 120000,
flatten: false,
makeEmptyDirs: false,
noDefaultExcludes: false,
patternSeparator: '[, ]+',
remoteDirectory: '',
remoteDirectorySDF: false,
removePrefix: '',
sourceFiles: "${env.GITLAB_DEPLOYMENT_FILE}/*yml"
)
],
usePromotionTimestamp: false,
useWorkspaceInPromotion: false,
verbose: false
)
]
)
echo '发送yml文件至目标服务器 --SUCCESS'
}
}
stage('远程执行k8s部署yaml命令') {
steps {
//替换发送过来的部署文件
//部署
sh """
ssh root@10.199.99.200 sed -i'' "s#REGISTRY#${env.HARBOR_URL}#" ${env.K8S_FILE_PATH}/${env.GITLAB_DEPLOYMENT_FILE}/deployment.yml
ssh root@10.199.99.200 sed -i'' "s#DOCKERHUB_NAMESPACE#${env.HARBOR_REPO}#" ${env.K8S_FILE_PATH}/${env.GITLAB_DEPLOYMENT_FILE}/deployment.yml
ssh root@10.199.99.200 sed -i'' "s#APP_NAME#${env.GIT_NAME}#" ${env.K8S_FILE_PATH}/${env.GITLAB_DEPLOYMENT_FILE}/deployment.yml
ssh root@10.199.99.200 sed -i'' "s#BUILD_NUMBER#${env.TAG_NAME}#" /${env.K8S_FILE_PATH}/${env.GITLAB_DEPLOYMENT_FILE}/deployment.yml
ssh root@10.199.99.200 kubectl apply -f ${env.K8S_FILE_PATH}/${env.GITLAB_DEPLOYMENT_FILE}/
"""
echo '远程执行k8s部署yaml命令 --SUCCESS'
}
}
}
}
deployment.yml
说明:
imagePullSecrets:
- name: harbor-secret
因为将镜像上传到私人镜像仓库,所以k8s中拉取镜像时从harbor中拉取,需要进行配置harbor的secret
Groovy
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: mytest
component: devops
tier: backend
name: mytest
spec:
progressDeadlineSeconds: 600
replicas: 1
selector:
matchLabels:
app: mytest
component: devops
tier: backend
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 100%
type: RollingUpdate
template:
metadata:
labels:
app: mytest
component: devops
tier: backend
spec:
imagePullSecrets:
- name: harbor-secret
containers:
- name: mytest
image: REGISTRY/DOCKERHUB_NAMESPACE/APP_NAME:BUILD_NUMBER
readinessProbe:
httpGet:
path: /test
port: 8080
timeoutSeconds: 10
failureThreshold: 30
periodSeconds: 5
imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
resources:
limits:
cpu: 300m
memory: 600Mi
requests:
cpu: 100m
memory: 100Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
labels:
app: mytest
component: devops
name: mytest
spec:
ports:
- name: http
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: mytest
component: devops
tier: backend
sessionAffinity: None
type: NodePort
dockerfile
用于构建docker镜像
Groovy
FROM eclipse-temurin:8-jre
LABEL org.opencontainers.image.authors="fooleryang@139.com"
COPY mytest.jar /usr/local/
WORKDIR /usr/local
CMD java -jar mytest.jar
发布
修改代码后提交,版本修改为v6.0.0
在gitlab中新加标签v6.0.0
在jenkins中构建,选择v6.0.0
查看
总结
目前使用了jenkins的pipeline项目,发布项目到k8s中