写在最前
因为有一些比较前沿的springboot项目采用的是gradle没有使用maven, 故而本篇章介绍一下如何自定义podTemplate接入gradle到kubesphere
1. 构建流程
KubeSphere 官方的 builder-base
代码库可以在 https://github.com/kubesphere/devops-agent/tree/master/gradle 找到,里面包含了 DevOps 相关的构建工具与配置。如果你需要下载其他版本的 OpenJDK,可以参考 JDK 官方提供的 https://jdk.java.net/java-se-ri/17-MR1,该页面列出了各个版本的详细下载信息,方便你根据需求选择合适的版本进行使用。
1.1 openjdk11
FROM kubespheredev/builder-base:v3.1.0
# gradle6
ENV GRADLE_VERSION 6.9.1
ENV GRADLE_HOME /usr/local/gradle-${GRADLE_VERSION}
ENV PATH ${GRADLE_HOME}/bin:$PATH
# 下载并安装 Gradle
RUN curl -fSL https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip -o gradle.zip && \
echo "$(curl -sLf https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip.sha256) gradle.zip" | sha256sum --check && \
unzip -q gradle.zip -d /usr/local && \
rm -f gradle.zip
# 通过 RUN 检查 Gradle 版本
RUN gradle --version
# 下载并安装 OpenJDK 11(使用指定的 URL)
RUN curl -fSL https://download.java.net/openjdk/jdk11.0.0.2/ri/openjdk-11.0.0.2_linux-x64.tar.gz -o /tmp/openjdk-11.tar.gz && \
tar -xzf /tmp/openjdk-11.tar.gz -C /usr/local && \
rm -f /tmp/openjdk-11.tar.gz
# 设置 JAVA_HOME 和 PATH
ENV JAVA_HOME /usr/local/jdk-11.0.0.2
ENV PATH $JAVA_HOME/bin:$PATH
# 通过 RUN 检查 Java 版本
RUN java -version
1.2 openjdk17
FROM kubespheredev/builder-base:v3.1.0
# gradle6
ENV GRADLE_VERSION 6.9.1
ENV GRADLE_HOME /usr/local/gradle-${GRADLE_VERSION}
ENV PATH ${GRADLE_HOME}/bin:$PATH
# 下载并安装 Gradle
RUN curl -fSL https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip -o gradle.zip && \
echo "$(curl -sLf https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip.sha256) gradle.zip" | sha256sum --check && \
unzip -q gradle.zip -d /usr/local && \
rm -f gradle.zip
# 通过 RUN 检查 Gradle 版本
RUN gradle --version
# 下载并安装 OpenJDK 17(使用指定的 URL)
RUN curl -fSL https://download.java.net/openjdk/jdk17.0.0.1/ri/openjdk-17.0.0.1+2_linux-x64_bin.tar.gz -o /tmp/openjdk-17.tar.gz && \
tar -xzf /tmp/openjdk-17.tar.gz -C /usr/local && \
rm -f /tmp/openjdk-17.tar.gz
# 设置 JAVA_HOME 和 PATH
ENV JAVA_HOME /usr/local/jdk-17.0.0.1
ENV PATH $JAVA_HOME/bin:$PATH
# 通过 RUN 检查 Java 版本
RUN java -version
2. 连接测试
2.1 jenkins-casc-config
我就用gradle6.9.1-openjdk11来演示
- name: "gradle6.9.1-openjdk11"
namespace: "kubesphere-devops-worker"
label: "gradle6.9.1-openjdk11"
nodeUsageMode: "EXCLUSIVE"
idleMinutes: 0
containers:
- name: "gradle"
image: "registry.cn-hangzhou.aliyuncs.com/tanqidi/build-gradle:gradle6.9.1-openjdk11"
command: "cat"
args: ""
ttyEnabled: true
privileged: false
resourceRequestCpu: "100m"
resourceLimitCpu: "4000m"
resourceRequestMemory: "100Mi"
resourceLimitMemory: "8192Mi"
- name: "jnlp"
image: "registry.cn-beijing.aliyuncs.com/kubesphereio/inbound-agent:4.10-2"
args: "^${computer.jnlpmac} ^${computer.name}"
resourceRequestCpu: "50m"
resourceLimitCpu: "500m"
resourceRequestMemory: "400Mi"
resourceLimitMemory: "1536Mi"
workspaceVolume:
emptyDirWorkspaceVolume:
memory: false
volumes:
- hostPathVolume:
hostPath: "/var/run/docker.sock"
mountPath: "/var/run/docker.sock"
- hostPathVolume:
hostPath: "/data/gradle"
mountPath: "/root/.gradle/"
yaml: |
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: node-role.kubernetes.io/worker
operator: In
values:
- ci
tolerations:
- key: "node.kubernetes.io/ci"
operator: "Exists"
effect: "NoSchedule"
- key: "node.kubernetes.io/ci"
operator: "Exists"
effect: "PreferNoSchedule"
containers:
- name: "gradle"
resources:
requests:
ephemeral-storage: "1Gi"
limits:
ephemeral-storage: "10Gi"
securityContext:
fsGroup: 1000
2.2 jenkinsfile
我写了一个简单的gradle的springboot小demo项目,你可以fork到你的gitee仓库里面去,https://gitee.com/tanqidi/gradle
pipeline {
agent {
node {
label 'gradle6.9.1-openjdk11'
}
}
stages {
stage('拉取项目') {
agent none
when {
environment name: 'BUILD_ENV', value: 'UAT_CICD'
}
steps {
container('gradle') {
git(credentialsId: 'gitee-secret', branch: 'master', url: 'https://gitee.com/tanqidi/gradle.git', changelog: true, poll: false)
}
}
}
stage('项目编译') {
agent none
when {
environment name: 'BUILD_ENV', value: 'UAT_CICD'
}
steps {
container('gradle') {
sh 'gradle build --info'
}
}
}
stage('镜像构建') {
agent none
when {
environment name: 'BUILD_ENV', value: 'UAT_CICD'
}
steps {
container('gradle') {
script {
sh 'docker build -t $REGISTRY/$HARBOR_NAMESPACE/$MODULE_NAME:$MODULE_VERSION .'
}
}
}
}
stage('镜像推送') {
agent none
when {
environment value: 'UAT_CICD', name: 'BUILD_ENV'
}
steps {
container('gradle') {
withCredentials([usernamePassword(credentialsId : 'aliyun-harbor-secret' ,passwordVariable : 'name' ,usernameVariable : 'passwd' ,)]) {
sh 'echo "$name" | docker login $REGISTRY -u "$passwd" --password-stdin'
sh 'docker push $REGISTRY/$HARBOR_NAMESPACE/$MODULE_NAME:$MODULE_VERSION'
}
}
}
}
stage('部署到UAT环境') {
agent none
steps {
container('gradle') {
withCredentials([kubeconfigFile(credentialsId: "$KUBECONFIG_CREDENTIAL_ID", variable: 'KUBECONFIG')]) {
script {
sh "echo \'${DEPLOY_YAML}\' > deploy.yaml"
sh "cat deploy.yaml"
sh "envsubst < deploy.yaml | kubectl apply -f -"
}
}
}
}
}
}
environment {
KUBECONFIG_CREDENTIAL_ID = 'k8s-kubeconfig'
REGISTRY = 'registry.cn-hangzhou.aliyuncs.com'
HARBOR_NAMESPACE = 'tanqidi-temp'
PROJECT_NAMESPACE = 'test'
DEPLOY_YAML = '''
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: ${MODULE_NAME}
annotations:
kubesphere.io/description: \'${HARBOR_NAMESPACE}/${MODULE_NAME}:$MODULE_VERSION\'
name: ${MODULE_NAME}
namespace: ${PROJECT_NAMESPACE}
spec:
replicas: 1
selector:
matchLabels:
app: ${MODULE_NAME}
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25%
maxSurge: 25%
revisionHistoryLimit: 10
progressDeadlineSeconds: 600
template:
metadata:
labels:
app: ${MODULE_NAME}
spec:
imagePullSecrets:
- name: harbor
containers:
- name: ${MODULE_NAME}
imagePullPolicy: Always
image: $REGISTRY/$HARBOR_NAMESPACE/$MODULE_NAME:$MODULE_VERSION
ports:
- name: http-8080
containerPort: 8080
protocol: TCP
resources:
limits:
cpu: \'1\'
memory: 2Gi
requests:
cpu: 25m
memory: 850Mi
restartPolicy: Always
terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
name: ${MODULE_NAME}
namespace: ${PROJECT_NAMESPACE}
labels:
app: ${MODULE_NAME}
spec:
ports:
- port: 8080
targetPort: 8080
selector:
app: ${MODULE_NAME}
type: ClusterIP
sessionAffinity: None
'''
}
parameters {
choice(name: 'MODULE_NAME', choices: '''test-gradle
''', description: '模块构建')
choice(name: 'BUILD_ENV', choices: '''UAT_CICD
UAT_CD''', description: '构建环境')
string(name: 'MODULE_VERSION', defaultValue: 'v0.0Beta', description: '模块版本')
}
}
2.3 构建测试
选择gradle6.9.1-openjdk11,运行结果完整正确
2.4 试验访问
流水线会自动生成deployment,service要手动变更为NodePort来试验访问
3. 镜像制品
registry.cn-hangzhou.aliyuncs.com/tanqidi/build-gradle:gradle6.9.1-openjdk11
registry.cn-hangzhou.aliyuncs.com/tanqidi/build-gradle:gradle6.9.1-openjdk17
4. 操作总结
总的来说还是比较快速的就配置上了gradle并且构建通过了,在jenkins-case-conig那个部分比较晦涩难懂,可以看看前面的构建章节是有详细截图和描述的。