公司内部各个开发团队,一直有独立运作的习惯,持续集成基本是各自的Jenkins,又由于办公内网,没有足够的硬件资源,搭建ceph这类的分布式存储(我也尝试用几台虚机,搭建了ceph,并测试了存储io,性能感人的差,经费也下不来),所以Jenkins 也一直放在K8S集群外。接下里简单记录一下目前的使用方式
Jenkins添加集群信息:
添加用于构建镜像的docker主机,实际上镜像打包还可以通过maven的插件,开发同事在本地开发构建时便是通过maven的docker插件。
编写Jenkins的Dockerfile(略,springcloud微服务的话,官方有一个案例,拿来开始改改就可以用了)
仓库里添加jenkinsfile,在此需要考虑到各种语言的编译过程的包的缓存,用来加速下一次构建编译的速度,以下便是将maven本地仓库的本地路径,挂载到PVC中。
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
76pipeline {
agent {
kubernetes {
cloud 'k8s-api-cs-software.sunvalley.com.cn'
nodeSelector 'app=jenkins'
idleMinutes 5
yaml """
apiVersion: v1
kind: Pod
metadata:
labels:
app: jenkins-jnlp
spec:
containers:
- name: jnlp
image: harbor.sunvalley.com.cn/library/jenkins-jnlp-slave:3.35-5
- name: maven
image: cs-harbor.sunvalley.com.cn/library/maven-base-image:3.0.5
command:
- cat
tty: true
volumeMounts:
- mountPath: /data/m2_dev/
name: m2-dev
- name: docker-ci
image: harbor.sunvalley.com.cn/library/docker-ci:v19.03.5
command:
- cat
tty: true
volumeMounts:
- mountPath: /var/run/docker.sock
name: docker-sock
- mountPath: /data/m2_dev/
name: m2-dev
- name: kubectl-tools
image: harbor.sunvalley.com.cn/library/kubectl-tools:1.16.3
command:
- cat
tty: true
volumes:
- name: docker-sock
hostPath:
path: /var/run/docker.sock
- name: m2-dev
hostPath:
path: /data/m2_dev/
"""
// serviceAccountName: admin-sample-user
}
}
stages {
stage('Run maven') {
steps {
// container('maven') {
// sh 'mvn -B -f pom.xml -s /data/m2_dev/settings.xml clean package -Dmaven.test.skip=true -pl com.sunvalley:mwp-message-center -am -Pdev1 -e -U'
// }
// container('docker-ci') {
// dir(path: "mwp-message-center") {
// script {
// docker.withRegistry('https://cs-harbor.sunvalley.com.cn', 'harbor' ){
// def customImage = docker.build("cs-harbor.sunvalley.com.cn/internal/${env.JOB_NAME}:${env.GIT_COMMIT}")
// customImage.push()
// }
// }
// }
// }
container('kubectl-tools') {
// sh "sed -i 's/<PROJECT_NAME>/${env.JOB_NAME}/' deployment.yaml"
// sh "sed -i 's/<BUILD_TAG>/${env.GIT_COMMIT}/' deployment.yaml"
// sh 'kubectl apply -f deployment.yaml'
sh "kubectl get pods"
}
}
}
}
}
Jenkinsfile 无论时声明式还是脚本式。都不是yaml语法,Jenkins自身提供了一个Linter,不过呀。总是在界面上切来切去。有点麻烦。如果是vscode用户可以用下面的插件,毕竟项目多了,jenkinsfile 熟悉了,这个工作会帮上忙。
然而,也有需要吐糟的地方,Jenkins的插件管理,管理起来好崩溃。有些插件会依赖另一个插件的高版本。所以升级插件的时候,一并把依赖插件一起升级了。举例就是pipeline的升级,把Jenkins maven插件一并升级了。结果新的Jenkins maven的版本不支持jdk1.6。 老旧的java项目构建时报错。又比如jenkins k8s cloud 的插件的部分功能,在较新的Jenkins上才能运行(也是测试了好久才发现),文档半点没提。甚至试过在升级jenkins插件的是,官方下载中心垮掉了。第二天才恢复。
再吐糟一点,Jenkins的agent,需要回调master的端口来通讯,我们目前是固定了50000端口。在跨公网的场景下,就有点为难了,我不想暴露50000端口到公网啊。
还有呀,Jenkins 的K8S 插件,目前不支持在构建编译过程中, 调用两个K8S集群。描述个案例:我在内网自建的K8S构建后,最后一步再apply到AWS的EKS。(还要花点时间,寻找到优雅的解决方式)