kuboard部署java项目(自动版)
常见问题
当一个镜像用于两个服务时,通过latest标签,只会更新成功一个,因此修改为指定版本号进行更新。
分析:1. sh脚本
'''
三个单引号不支持环境变量,修改为三个双引号"""
才支持。 2. 相同镜像,两个服务通过重启,怀疑其中一个镜像还没拉取完但是检测到镜像版本已经是最新的了,因为另一个已经在执行了,就直接重启了。
1
2
3
4
5
6
7sh """#!/bin/bash
curl -X PUT \
-H "content-type: application/json" \
-H "Cookie: KuboardUsername=admin; KuboardAccessKey=4xx" \
-d '{"kind":"deployments","namespace":"base","name":"dev-system-business","images":{"harbor/business":"harbor/business:${env.gitlabMergeRequestTitle}"}}' \
"http://172.1.1.44/kuboard-api/cluster/kubernates/kind/CICDApi/admin/resource/updateImageTag"
"""
环境信息:
软件 | 版本 |
---|---|
Kubernetes | 1.26.4 |
Kuboard | 3.5.2.4 |
Jenkins | 2.375.1 |
Harbor | 2.0 |
Gitlab | 10.0.0 |
后端
基础架构:
graph LR A[gitlab合并] -->|通知| B(Jenkins编译) B -->|1.push| D[harbor] B -->|2.执行| E[kuboard重启项目负载] D -->|完成后| E
详细步骤:
配置gitlab的webhook
- 点击项目
Settings-->Integrations
- 输入URL,勾选jenkins里面的``Build when a change is pushed to GitLab. GitLab webhook URL:
可以拿到地址,eg: URL为
http://172.1.1.24:8080/project/xxxdemo` - 输入SecretToken,SecretToken为jenkins项目的
Configure-->General-->Secret token-->generate
生产的token,eg:035311df1e0bbedf1c1efb0cb5f5a630
- 只勾选
Trigger
触发方式Merge Request events
,关闭其他包括SSL - 点击Add webhook
配置Jenkins的configure
点击jenkins项目的
configure-->General-->Build Triggers
勾选
Build when a change is pushed to GitLab. GitLab webhook URL: http://172.1.1.24:8080/project/xxxdemo
子集勾选:
Accepted Merge Request Events
Approved Merge Requests(EE-only)
点击
Advanced...
其他不变,点击
Generate
生成Secret token
在Pipeline Script一栏,输入
script
脚本1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186pipeline {
agent any
tools {
jdk 'jdk8'
dockerTool 'docker'
}
environment {
GITLAB_API_URL = 'http://172.1.1.2:9999/api/v4'
GITLAB_PROJECT_ID = '138'
GITLAB_PRIVATE_TOKEN = 'Ny9ywkxxggjo9CwfuWMz'
DOCKER_REGISTRY = 'harbor.exxktech.dev'
DOCKER_REGISTRY_URL = 'http://harbor.exxktech.dev'
DOCKER_REGISTRY_CREDENTIALS = 'c7da3fce-7e0c-415e-a684-e49e17560120'
DOCKERFILE_PATH = 'src/main/docker'
projectVersion = ''
projectName = ''
projectVersion1 = ''
projectName1 = ''
}
stages {
stage('Checkout') {
steps {
git branch: 'release',
credentialsId: '123456',
url: 'http://172.1.1.2:9999/exxk_backend_project/exxk_center.git'
}
}
stage('maven build') {
steps {
script {
sh 'mvn -Dmaven.test.failure.ignore=true clean install'
}
}
}
stage('multi build') {
parallel {
//项目一
stage('exxk_center_manager') {
stages {
stage('docker build') {
steps {
dir('exxk_center_manager') {
script {
projectVersion = sh(script: 'mvn -f pom.xml help:evaluate -Dexpression=project.version -q -DforceStdout', returnStdout: true).trim()
projectName = sh(script: 'mvn -f pom.xml help:evaluate -Dexpression=project.artifactId -q -DforceStdout', returnStdout: true).trim()
// 执行Maven构建
sh 'mvn -Dmaven.test.failure.ignore=true clean package dockerfile:build'
}
}
}
}
stage('Docker tags') {
steps {
// 使用Docker插件构建和推送镜像
script {
def dockerImage = docker.image("${DOCKER_REGISTRY}/exxk_center/${projectName}:${projectVersion}")
dockerImage.tag("${env.gitlabMergeRequestTitle}")
}
}
}
stage('Push Docker Image') {
steps {
// 使用Docker插件构建和推送镜像
script {
def dockerImage = docker.image("${DOCKER_REGISTRY}/exxk_center/${projectName}:${env.gitlabMergeRequestTitle}")
withDockerRegistry(credentialsId: "${DOCKER_REGISTRY_CREDENTIALS}", toolName: 'docker', url: "${DOCKER_REGISTRY_URL}") {
dockerImage.push()
}
}
}
}
stage('Docker latest tags') {
steps {
// 使用Docker插件构建和推送镜像
script {
def dockerImage = docker.image("${DOCKER_REGISTRY}/exxk_center/${projectName}:${projectVersion}")
dockerImage.tag("latest")
}
}
}
stage('Push latest Image') {
steps {
// 使用Docker插件构建和推送镜像
script {
def dockerImage = docker.image("${DOCKER_REGISTRY}/exxk_center/${projectName}:latest")
withDockerRegistry(credentialsId: "${DOCKER_REGISTRY_CREDENTIALS}", toolName: 'docker', url: "${DOCKER_REGISTRY_URL}") {
dockerImage.push()
}
}
}
}
}
post {
success {
script {
sh '''#!/bin/bash
curl -X PUT \
-H "Content-Type: application/yaml" \
-H "Cookie: KuboardUsername=admin; KuboardAccessKey=4ip7hrrs6ias.2npbn4kc546tdxb8ew58nsdyz37j7cby" \
-d '{"kind":"deployments","namespace":"arts-center","name":"exxk-center-manager"}' \
"http://172.1.1.44/kuboard-api/cluster/kubernates/kind/CICDApi/admin/resource/restartWorkload"
'''
}
}
}
}
//项目二
stage('exxk_center_application') {
stages {
stage('docker build') {
steps {
dir('exxk_center_application') {
script {
projectVersion1 = sh(script: 'mvn -f pom.xml help:evaluate -Dexpression=project.version -q -DforceStdout', returnStdout: true).trim()
projectName1 = sh(script: 'mvn -f pom.xml help:evaluate -Dexpression=project.artifactId -q -DforceStdout', returnStdout: true).trim()
// 执行Maven构建
sh 'mvn -Dmaven.test.failure.ignore=true clean package dockerfile:build'
}
}
}
}
stage('Docker tags') {
steps {
// 使用Docker插件构建和推送镜像
script {
def dockerImage = docker.image("${DOCKER_REGISTRY}/exxk_center/${projectName1}:${projectVersion1}")
dockerImage.tag("${env.gitlabMergeRequestTitle}")
}
}
}
stage('Push Docker Image') {
steps {
// 使用Docker插件构建和推送镜像
script {
def dockerImage = docker.image("${DOCKER_REGISTRY}/exxk_center/${projectName1}:${env.gitlabMergeRequestTitle}")
withDockerRegistry(credentialsId: "${DOCKER_REGISTRY_CREDENTIALS}", toolName: 'docker', url: "${DOCKER_REGISTRY_URL}") {
dockerImage.push()
}
}
}
}
stage('Docker latest tags') {
steps {
// 使用Docker插件构建和推送镜像
script {
def dockerImage = docker.image("${DOCKER_REGISTRY}/exxk_center/${projectName1}:${projectVersion1}")
dockerImage.tag("latest")
}
}
}
stage('Push latest Image') {
steps {
// 使用Docker插件构建和推送镜像
script {
def dockerImage = docker.image("${DOCKER_REGISTRY}/exxk_center/${projectName1}:latest")
withDockerRegistry(credentialsId: "${DOCKER_REGISTRY_CREDENTIALS}", toolName: 'docker', url: "${DOCKER_REGISTRY_URL}") {
dockerImage.push()
}
}
}
}
}
post {
success {
script {
sh '''#!/bin/bash
curl -X PUT \
-H "Content-Type: application/yaml" \
-H "Cookie: KuboardUsername=admin; KuboardAccessKey=4ip7hrrs6ias.xxxbn4kc546tdxb8ew58nsdyz37j7cby" \
-d '{"kind":"deployments","namespace":"arts-center","name":"exxk-center-application"}' \
"http://172.1.1.44/kuboard-api/cluster/kubernates/kind/CICDApi/admin/resource/restartWorkload"
'''
}
}
}
}
}
}
}
}java项目配置
文件结构
1
2
3
4
5
6
7|-parent
|-demo1
|-src\main\docker\Dockerfile
|-pom.xml
|-demo2
|-src\main\docker\Dockerfile
|-pom.xmlDockerfile
1
2
3
4
5
6
7
8
9
10
11
12FROM harbor.exxktech.dev/base/java8:1.0.0
ARG JAR_FILE
ADD target/${JAR_FILE}.jar app.jar
ENV JAVA_OPTS -Xms128m -Xmx256m
ENV BOOT_PARAMS ""
EXPOSE 8080
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS $JAVA_OPTS_AGENT -Djava.security.egd=file:/dev/./urandom -jar app.jar $BOOT_PARAMS" ]pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.13</version>
<executions>
<execution>
<id>default</id>
<phase>none</phase>
</execution>
<execution>
<id>after-deploy</id>
<phase>deploy</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<repository>harbor.exxktech.dev/exxk_center/${project.name}</repository>
<tag>${project.version}</tag>
<buildArgs>
<JAR_FILE>${project.build.finalName}</JAR_FILE>
</buildArgs>
<dockerfile>src/main/docker/Dockerfile</dockerfile>
</configuration>
</plugin>
微前端
架构
graph LR A[gitlab前端项目1合并] -->|通知| B(Jenkins编译) c[gitlab前端项目2合并] -->|通知| B(Jenkins编译) B -->|1.push| D[harbor] B -->|2.执行| E[kuboard重启项目负载] D -->|完成后| E
配置
jenkins
1 | pipeline { |
Dockerfile
1 | FROM nginx |
nginx default.conf
1 | # 后端接口代理地址 |