引言
本文描述如何一键式把idea开发好的springboot Maven项目代码,推送gitee仓库,再通过jenkins流水线自动拉取gitee代码构建阿里云镜像,再自动部署到k8s集群。
以上环境配置好以后,我们只需要把代码提交到gitee,再在jenkins点一下构建,就自动部署应用到k8s了,无需其他任何操作。
环境准备
本地开发环境:
idea:Windows或者mac环境的idea
Maven:springboot2.6.13+Maven3.9.9
linux server:
jenkins服务器:独立于k8s之外的服务器,jenkins v2.492.3,且能web访问,且安装了docker、k8s等插件
k8s集群服务器:3台虚拟机组成k8s集群,版本v1.28.0
其他外部环境:
gitee码云:https://gitee.com/yekunlee/tcpserverdemo
阿里云私有镜像仓库:如下图

Jenkins基础环境配置
新增gitee阿里云k8s凭据
新增完成后如下

对接k8s
需要安装k8s插件,安装完成后才能新增k8s的cloud配置


新增一个cloud配置

k8s的master节点上获取server地址


获取到server地址和命名空间后,填入Jenkins




点击save。
gitee码云配置
新增仓库

idea配置
需要先安装gitee插件

新增gitee账号


输入用户密码登录

配置好以后idea会出现git,选择manage remote

新增远程仓库地址

复制gitee上的地址到idea

至此idea配置完成
阿里云配置
创建命名空间

创建镜像仓库并设置为私有




设置固定密码,用于后续流水线配置

jenkins新增流水线
Jenkins新增流水线



勾选使用gitee webhook进行构建

生成密码,

其他默认即可
将上两步的URL和密码复制到gitee

流水线定义选择scm


填写要构建的分支


点击save。
idea代码实现
为了便于演示,只展示一个最小的springboot maven项目,提供http服务,对外只暴露一个/test接口,http端口8090


此外,还需要3个文件,分别是Dockerfile、Jenkinsfile、k8s.yaml
Dockerfile内容
# 使用 OpenJDK 8 官方镜像可能会有网络问题连接超时,替换为国内华为云jdk,防止网络超时
FROM swr.cn-south-1.myhuaweicloud.com/library/openjdk:8-jdk
LABEL authors="yekunlee"
# 设置工作目录
VOLUME /tcpserverdemo
WORKDIR /app
# 将本地的 JAR 包拷贝到容器内
COPY target/tcpserverdemo-0.0.1-SNAPSHOT.jar /app/tcpserverdemo.jar
# 暴露 HTTP 服务和 TCP 服务端口,如果只有http,则去掉9090
EXPOSE 8090 9090
# 配置容器启动命令,分别指定 HTTP 端口和 TCP 端口,如果只有http,则去掉9090
ENTRYPOINT ["java", "-jar", "-Dserver.port=8090", "-Dtcp.server.port=9090", "/app/tcpserverdemo.jar"]
Jenkinsfile内容
需要填写阿里云私有镜像地址,和凭据id
pipeline {
agent any
environment {
DOCKER_IMAGE = 'crpi-0swe8dzdgqldwblh.cn-chengdu.personal.cr.aliyuncs.com/yekunlee/tcpserver'
GIT_CREDENTIALS_ID = '10667fcf-7547-46c9-95e2-c42acb320c5f'
REGISTRY_CREDENTIALS_ID = 'b26ed7d2-9556-453e-8d30-7ede5a7cc2b6'
DOCKERFILE_PATH = 'Dockerfile'
}
stages {
stage('获取最新代码') {
steps {
deleteDir()
checkout([
$class: 'GitSCM',
branches: [[name: '*/test']],
userRemoteConfigs: [[
url: 'https://gitee.com/yekunlee/tcpserverdemo.git',
credentialsId: "${GIT_CREDENTIALS_ID}"
]],
extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: '.']]
])
}
}
stage('Maven 构建') {
steps {
sh 'mvn clean package -Dmaven.test.skip=true'
}
}
stage('构建并推送 Docker 镜像') {
steps {
script {
def shortCommitId = sh(
script: "git rev-parse --short HEAD",
returnStdout: true
).trim()
echo "当前短commit ID为: ${shortCommitId}"
withCredentials([usernamePassword(
credentialsId: "${REGISTRY_CREDENTIALS_ID}",
usernameVariable: 'ALIYUN_USER',
passwordVariable: 'ALIYUN_PASS'
)]) {
sh """
docker login --username=${ALIYUN_USER} -p ${ALIYUN_PASS} crpi-0swe8dzdgqldwblh.cn-chengdu.personal.cr.aliyuncs.com
docker build -t ${DOCKER_IMAGE}:${shortCommitId} . -f ${DOCKERFILE_PATH}
docker tag ${DOCKER_IMAGE}:${shortCommitId} ${DOCKER_IMAGE}:latest
docker push ${DOCKER_IMAGE}:${shortCommitId}
docker push ${DOCKER_IMAGE}:latest
"""
}
}
}
}
stage('修改 K8s 镜像版本并部署') {
steps {
withCredentials([file(credentialsId: '641b931c-cff3-4c76-8c1c-c472257e2bdc', variable: 'KUBECONFIG_PATH')]) {
script {
def shortCommitId = sh(
script: "git rev-parse --short HEAD",
returnStdout: true
).trim()
sh """
sed -i 's|tcpservertestimage|${DOCKER_IMAGE}:${shortCommitId}|g' k8s.yaml
kubectl apply -f k8s.yaml --kubeconfig=${KUBECONFIG_PATH}
"""
}
}
}
}
}
}k8s.yaml内容
apiVersion: apps/v1
kind: Deployment
metadata:
name: tcpserver
namespace: test # 添加命名空间
labels:
app: tcpserver
spec:
replicas: 2
selector:
matchLabels:
app: tcpserver
template:
metadata:
labels:
app: tcpserver
spec:
containers:
- name: tcpserver
image: tcpservertestimage # Jenkins 中自动替换为实际镜像
ports:
- containerPort: 8090 # HTTP 服务
- containerPort: 9090 # TCP 服务
imagePullSecrets:
- name: aliyun-acr-secret
---
apiVersion: v1
kind: Service
metadata:
name: tcpserver
spec:
selector:
app: tcpserver
type: NodePort
ports:
- name: http-port
port: 8090
targetPort: 8090
nodePort: 30080
protocol: TCP
- name: tcp-port
port: 9090
targetPort: 9090
nodePort: 30090
protocol: TCP
构建流水线
先提交代码到gitee




构建流水线

查看构建过程

如下图,阿里云可以查到docker镜像构建成功

如下图,全部构建成功

成果检验

容器日志:

postman访问:
