全部的 K8S学习笔记总目录 ,请点击查看。
CI/CD 是一种通过在应用开发阶段引入自动化来频繁向客户交付应用的方法。CI/CD 的核心概念是持续集成、持续交付和持续部署。作为一种面向开发和运维团队的解决方案,CI/CD 主要针对在集成新代码时所引发的问题。这里主要介绍jenkins的使用。
ci/cd常用的持续集成工具:
travis-ci
circleci
bamboo
teamcity
gitlabci
jenkins
tekton
argo
spinnaker
drone
concourse
等等……
本次要实现的效果是基于k8s集群部署gitlab、sonarQube、Jenkins等工具,并把上述一些工具集成到Jenkins中,以Django项目和SpringBoot项目为例,通过多分支流水线及Jenkinsfile实现项目代码提交到不同的仓库分支,实现自动代码扫描、单元测试、docker容器构建、k8s服务的自动部署。
其中包含的内容有:
DevOps、CI、CD介绍
Jenkins、sonarQube、gitlab的快速部署
Jenkins初体验
流水线入门及Jenkinsfile使用
Jenkins与Kubernetes的集成
sonarQube代码扫描与Jenkins的集成
实践Django项目的基于Jenkinsfile实现开发、测试环境的CI/CD
DevOps、CI、CD介绍 CI/CD就是持续集成 Continuous Integration (CI ) / 持续交付Continuous Delivery (CD )
一般的软件交付流程如下:
软件交付发展历程 一个软件从零开始到最终交付,大概包括以下几个阶段:规划、编码、构建、测试、发布、部署和维护,基于这些阶段,我们的软件交付模型大致经历了几个阶段:
瀑布式流程 软件交付的早期阶段,大家都是采用瀑布式流程,如下图所示:
前期需求确立之后,软件开发人员花费数周和数月编写代码,把所有需求一次性开发完,然后将代码交给QA(质量保障)团队进行测试,然后将最终的发布版交给运维团队去部署。
瀑布模型,简单来说,就是等一个阶段所有工作完成之后,再进入下一个阶段。这种模式的问题也很明显,产品迭代周期长,灵活性差。一个周期动辄几周几个月,适应不了当下产品需要快速迭代的场景。
敏捷开发 为了解决瀑布模型的问题,以及更好地适应当下快速迭代的场景,敏捷开发模式越来越多地被采用。敏捷开发模式的核心是任务由大拆小,开发、测试协同工作,注重开发敏捷,不重视交付敏捷。
DevOps 敏捷开发模式注重开发敏捷,不重视交付敏捷。那么如何解决交付敏捷呢?DevOps就是为了解决这个问题而诞生的。
开发、测试、运维协同工作, 持续开发+持续交付。
DevOps的工具链 我们是否可以认为DevOps = 提倡开发、测试、运维协同工作来实现持续开发、持续交付的一种软件交付模式?为什么最初的开发模式没有直接进入DevOps的时代?
原因是:沟通成本。
各角色人员去沟通协作的时候都是手动去做,交流靠嘴,靠人去指挥,很显然会出大问题。所以说不能认为DevOps就是一种交付模式,因为解决不了沟通协作成本,这种模式就不具备可落地性。
那DevOps时代如何解决角色之间的成本问题?DevOps的核心就是自动化。自动化的能力靠什么来支撑,工具和技术。
DevOps工具链
靠这些工具和技术,才实现了自动化流程,进而解决了协作成本,使得devops具备了可落地性。因此我们可以大致给devops一个定义:
devops = 提倡开发、测试、运维协同工作来实现持续开发、持续交付的一种软件交付模式 + 基于工具和技术支撑的自动化流程的落地实践。
因此devops不是某一个具体的技术,而是一种思想+自动化能力,来使得构建、测试、发布软件能够更加地便捷、频繁和可靠的落地实践。本次核心内容就是要教会大家如何利用工具和技术来实现完整的DevOps平台的建设。我们主要使用的工具有:
gitlab,代码仓库,企业内部使用最多的代码版本管理工具。
Jenkins, 一个可扩展的持续集成引擎,用于自动化各种任务,包括构建、测试和部署软件。
robotFramework, 基于Python的自动化测试框架
sonarqube,代码质量管理平台
maven,java包构建管理工具
Kubernetes
Docker
Kubernetes环境中部署jenkins 本次部署使用helm部署的方式,也可以使用yaml文件部署,参考其他部署方式
注意点:
第一次启动很慢
因为后面Jenkins会与kubernetes集群进行集成,会需要调用kubernetes集群的api,因此安装的时候创建了ServiceAccount并赋予了cluster-admin的权限
初始化容器来设置权限
ingress来外部访问
数据存储通过pvc挂载到宿主机中
安装jenkins 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 # 新建chart仓库 $ helm repo add jenkins https://charts.jenkins.io $ helm repo update # 搜索jenkins $ helm search repo jenkins # 下载chart包 $ helm pull jenkins/jenkins # 解压 $ tar -zxvf jenkins-4.9.1.tgz $ vim jenkins/values.yaml ...... ingress: # 启用ingress enabled: true ...... # 配置ingressClassName ingressClassName: nginx # 配置ingress的hosts hostName: jenkins.test.com ...... # 不进行测试 testEnabled: false ...... persistence: enabled: true # 配置storageClass storageClass: "nfs-client" annotations: {} labels: {} # 设置pvc的模式 accessMode: "ReadWriteMany" # 设置pvc的大小 size: "200Gi" ...... ...... # 安装 $ helm -n jenkins upgrade --create-namespace -i jenkins ./jenkins # 等待安装完成 $ kubectl -n jenkins get all # 获取登录密码 $ kubectl exec --namespace jenkins -it svc/jenkins -c jenkins -- /bin/cat /run/secrets/additional/chart-admin-password && echo # 使用浏览器访问jenkins,输入账号密码就可以登录了
由于默认的插件地址安装非常慢,我们可以替换成国内清华的源,进入 jenkins 工作目录,目录下面有一个 updates 的目录,下面有一个 default.json 文件,我们执行下面的命令替换插件地址:
1 2 3 4 $ kubectl -n jenkins exec -it jenkins-0 -c jenkins -- bash jenkins@jenkins-0:/$ cd /var/jenkins_home/updates jenkins@jenkins-0:~/updates$ sed -i 's/https:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json jenkins@jenkins-0:~/updates$ sed -i 's/https:\/\/updates.jenkins.io\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json
暂时先不用重新启动pod,汉化后一起重启。
配置升级站点的URL:
进入 web ui 的界面,点击 Manage Jenkins -> Plugins 按钮,进入插件管理页面:http://jenkins.test.com/manage/pluginManager/advanced
选择最后一项 Advanced settings
在 Update Site 中将原有url替换为:https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
点击 Submit 按钮,保存设置
接下来我们就可以重启服务了。重启jenkins服务有两种方式:
删除pod,kubernetes会自动重启
访问下面这个url重启:http://jenkins.test.com/restart/ 这样重启的话,pod不会重建
安装插件 分别点击以下菜单 Jenkins -> Manage Jenkins -> Plugins -> Avaliable plugins
主要安装以下插件:
GitLab
Pipeline: Multibranch
Blue Ocean
Localization: Chinese (Simplified)
Gogs (太老了,没有维护,但是gitlab比较重,这里先安装gogs,仅实验使用,之后webhook和gitlab用法相同)
如果安装超时,需要查看之前更改的数据源是否生效,如果没有生效,需要重新配置。
选中后,选择[Install],等待下载完成,然后点击[ Restart Jenkins when installation is complete and no jobs are running ],让Jenkins自动重启
启动后,界面默认变成中文。
Kubernetes环境中部署gogs 这里我们需要一个git仓库,因为实验使用的环境比较轻量,因此选用gogs来部署。
安装gogs gogs的helm仓库已经很老了,因此整理了以下的资源清单,使用k8s部署gogs。
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 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 apiVersion: v1 kind: Secret metadata: name: postgres namespace: gogs type: Opaque data: password: cG9zdGdyZXM= user: cG9zdGdyZXM= dbname: Z29ncw== --- apiVersion: v1 kind: Service metadata: name: postgres namespace: gogs spec: ports: - name: postgres port: 5432 targetPort: 5432 protocol: TCP type: ClusterIP selector: app: postgres --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: postgres namespace: gogs spec: accessModes: - ReadWriteMany resources: requests: storage: 10Gi storageClassName: nfs-client --- apiVersion: apps/v1 kind: Deployment metadata: name: postgres namespace: gogs labels: app: postgres spec: replicas: 1 selector: matchLabels: app: postgres template: metadata: labels: app: postgres spec: containers: - name: postgres image: postgres:15 ports: - containerPort: 5432 env: - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: postgres key: password - name: POSTGRES_USER valueFrom: secretKeyRef: name: postgres key: user - name: POSTGRES_DB valueFrom: secretKeyRef: name: postgres key: dbname volumeMounts: - name: postgres mountPath: /var/lib/postgresql/data volumes: - name: postgres persistentVolumeClaim: claimName: postgres --- apiVersion: v1 kind: Service metadata: name: memcache namespace: gogs spec: ports: - name: memcache port: 11211 targetPort: 11211 protocol: TCP type: ClusterIP selector: app: memcache --- apiVersion: apps/v1 kind: Deployment metadata: name: memcache namespace: gogs labels: app: memcache spec: replicas: 1 selector: matchLabels: app: memcached template: metadata: labels: app: memcached spec: containers: - name: memcached image: memcached:1.6.22 imagePullPolicy: IfNotPresent command: ["memcached" , "-m" , "64" , "-p" , "11211" , "-u" , "memcache" , "-v" , "-c" , "1024" , "-o" , "modern" ] ports: - containerPort: 11211 name: memcached livenessProbe: tcpSocket: port: memcached initialDelaySeconds: 30 timeoutSeconds: 5 periodSeconds: 10 failureThreshold: 3 readinessProbe: tcpSocket: port: memcached initialDelaySeconds: 30 timeoutSeconds: 5 periodSeconds: 10 failureThreshold: 3 securityContext: runAsUser: 1000 --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: gogs namespace: gogs spec: accessModes: - ReadWriteMany resources: requests: storage: 10Gi storageClassName: nfs-client --- apiVersion: v1 kind: ConfigMap metadata: name: gogs-config namespace: gogs data: app.ini: |- BRAND_NAME = TestGogs [server ] EXTERNAL_URL = http://gogs.test.com/ DOMAIN = gogs.test.com HTTP_PORT = 3000 [database ] TYPE = postgres HOST = postgres:5432 NAME = gogs USER = postgres PASSWORD = postgres [cache ] ADAPTER = memcache INTERVAL = 60 HOST = memcached:11211 [ui ] EXPLORE_PAGING_NUM = 50 ISSUE_PAGING_NUM = 50 [ui.user ] REPO_PAGING_NUM = 50 COMMITS_PAGING_NUM = 50 [prometheus ] ENABLED = false [other ] SHOW_FOOTER_BRANDING = true [security ] INSTALL_LOCK = true SECRET_KEY = sHyaED0SMrLCR7x LOCAL_NETWORK_ALLOWLIST = * --- apiVersion: v1 kind: Service metadata: name: gogs namespace: gogs spec: ports: - name: http port: 3000 targetPort: 3000 protocol: TCP - name: ssh port: 22 targetPort: 22 protocol: TCP type: ClusterIP selector: app: gogs --- apiVersion: apps/v1 kind: Deployment metadata: name: gogs namespace: gogs labels: app: gogs spec: replicas: 1 selector: matchLabels: app: gogs template: metadata: labels: app: gogs spec: containers: - name: gogs image: gogs/gogs:0.13.0 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 3000 - name: ssh containerPort: 22 livenessProbe: httpGet: path: / port: 3000 initialDelaySeconds: 30 timeoutSeconds: 5 periodSeconds: 10 failureThreshold: 3 readinessProbe: httpGet: path: / port: 3000 initialDelaySeconds: 30 timeoutSeconds: 5 periodSeconds: 10 failureThreshold: 3 volumeMounts: - name: gogs mountPath: /data - name: gogs-config mountPath: /data/gogs/conf/app.ini subPath: app.ini volumes: - name: gogs persistentVolumeClaim: claimName: gogs - name: gogs-config configMap: name: gogs-config --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: gogs namespace: gogs annotations: kubernetes.io/ingress.class: "nginx" spec: ingressClassName: nginx rules: - host: gogs.test.com http: paths: - path: / pathType: Prefix backend: service: name: gogs port: number: 3000
有了资源配置清单,我们就可以部署gogs了。
1 2 3 4 5 6 7 $ kubectl create namespace gogs $ kubectl apply -f gogs.yaml $ kubectl get pod -n gogs
全部容器启动成功后,我们就可以配置host然后通过浏览器访问gogs了。
这时可以点击右上角的注册按钮,注册一个账户,在gogs中id=0,也就是第一个注册的账户,是管理员账户,可以创建组织、创建仓库等操作。
注册完成后,我们就可以使用这个账户登录gogs了。
创建仓库 安装完成gogs我们就可以创建一个仓库了。这里创建一个django项目的仓库,仓库名称为moonlight。创建方法与github类似,这里就不再赘述。
创建完成后的仓库如下图所示:
然后就可以创建django项目了,然后将远程仓库地址添加到django项目中,合并后提交到远程仓库。
1 2 3 4 5 6 7 8 $ django-admin startproject moonlight $ cd moonlight $ git init $ git add . $ git commit -m "first commit" $ git remote add origin http://gogs.test.com/administrator/moonlight.git $ git pull --rebase origin master $ git push origin master
通过gogs的网页,可以看到代码已经提交到了仓库中。
配置jenkins 在gogs中,我们可以配置webhook,当代码提交到仓库后,会触发webhook,然后调用jenkins的接口,从而触发jenkins的流水线。
webhook触发的是jenkins的流水线,因此我们需要先创建一个流水线,然后再配置webhook。
因此我们先创建一个流水线
然后选择自由风格的软件项目,名字叫free-style-demo,然后点击确定。
然后我们就可以配置流水线了。首先我们先配置源码管理。选择git,然后填写仓库地址,这里填写的是gogs的仓库地址。然后当焦点离开仓库地址的时候,会发现git报错了,提示指定一个git仓库。
这是因为我们使用的是url地址,而k8s内部无法解析这个地址,要想解决这个问题,有两种方式:
在容器内配置hosts
配置coredns的静态解析
这里我们使用第二种方式,配置coredns的静态解析。
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 $ kubectl -n kube-system edit configmap coredns ...... apiVersion: v1 data: Corefile: | .:53 { errors health { lameduck 5s } ready kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa ttl 30 } hosts { 192.168.100.1 gogs.test.com jenkins.test.com fallthrough } prometheus :9153 forward . /etc/resolv.conf { max_concurrent 1000 } cache 30 loop reload loadbalance } ......
然后保存即可。保存后我们再回到jenkins的配置页面,重新刷新配置,发现git的报错已经消失了。
因为这里我们的仓库是公有的,因此不需要配置认证信息,如果是私有仓库,需要配置认证信息。
这里我们直接配置认证信息,做一个演示。点击添加,选择用户名密码,然后填写用户名密码,id保证内部唯一即可,然后点击添加。
然后认证选择刚刚添加的认证信息。
往下走,构建触发器。这里我们选择”Build when a change is pushed to GoGS”,也就是当代码提交到gogs的时候,触发构建。
再往下,Build Steps,我们选择执行shell命令。这个就是说,当代码提交到gogs的时候,jenkins会下载代码,然后执行Buile Steps中的命令。
这里我们主要是测试,先写一个简单点的echo success
,点击”可用的环境变量”,可以看到jenkins提供了很多环境变量,这些环境变量可以在shell中使用,这里也打印一个环境变量。
然后点击保存即可。
配置webhook jenkins的流水线配置完成后,我们就可以配置webhook了。点击仓库的设置按钮,然后选择管理Web钩子,点击添加Web钩子,选择Gogs
然后填写推送地址,推送地址为 http://jenkins.test.com/gogs-webhook/?job=free-style-demo
,这里的free-style-demo
为jenkins的流水线名称。
gogs 配置的推送地址格式为 http(s)://<Jenkins地址>/gogs-webhook/?job=<Jenkins任务名>
然后点击添加Web钩子即可。
添加成功后能看到Web钩子列表中多了一个Web钩子。
然后我们点进去,点击测试按钮,测试一下是否能够触发jenkins的流水线。然后就能看到测试已经推送了。
测试按钮底下也有一个成功的推送记录。
此时,去jenkins的流水线页面,可以看到流水线已经触发了。
触发构建 在moonlight
项目中,创建一个test.md
文件,然后提交到远程仓库,触发jenkins的流水线。
1 2 3 4 $ echo "test" > test.md $ git add . $ git commit -m "test" $ git push origin master
然后我们可以看到jenkins的流水线已经触发了。
等待build完成后,点击序号,可以看到build的日志。
点击控制台输出,可以看到整个流水线的执行过程以及日志。
拉倒最后可以看到整体是先把git仓库拉取到本地,然后执行了我们配置的shell命令。
Jenkins 的 Master-Slave 模式 工作节点 在 Jenkins 页面中,点击系统管理
, 然后点击节点和云管理
,可以看到 Jenkins 的工作节点列表。
可以看到在 Jenkins 中,只有一个节点,这个节点就是 Jenkins 的 Master 节点,也就是 Jenkins 的主节点。
如果有多个任务都在master节点执行,对master节点的性能就会造成一定影响。因此我们可以添加多个工作节点,让工作节点来执行任务,这样就可以减轻master节点的压力。
Jenkins 的 Master-Slave 模式是指 Jenkins 的 Master 节点负责分发任务,Slave 节点负责执行任务。这样做的好处是可以将任务分发到不同的节点上执行,从而提高任务的执行效率。
添加工作节点
因为目前这个环境已经接入了k8s集群,因此我们使用k8s集群中的节点作为jenkins的工作节点。以下内容仅作为演示,最后还是会切换回k8s集群中的节点。 多个k8s管理和多个slave节点的添加方式大致相同,这里不再赘述,可以尝试添加基本就会了。
点击新建节点
,进入新建节点页面。
定义一个节点名称,这里我们定义为slave
,然后选择固定节点
,然后点击确定。
之后是填写更详细的信息
Number of executors:这个是指这个节点可以同时执行多少个任务,这里我们填写5,也就是这个节点可以同时执行5个任务。
远程工作目录:这个是指这个节点的工作目录,这里我们填写/home/jenkins
,也就是这个节点的工作目录为/home/jenkins
。
标签:这个是指这个节点的标签,这里我们填写slave
,也就是这个节点的标签为slave
。之后我们可以在任务中指定任务执行在哪个节点上,就是通过标签来进行控制。
启动方法:这个是指这个节点的启动方式,也就是通过什么方式实现Master-Slave的通信。这里我们选择通过Java Web启动代理
,也就是通过Java Web启动代理的方式来实现Master-Slave的通信。
自定义工作目录:这个是指这个节点的工作目录,这里我们填写/home/jenkins
,也就是和上面的远程工作目录一样。
Tunnel连接位置:点开”高级”按钮就可以看到了。
这个是指这个节点连接到Master节点的时候,通过什么方式来连接。这里我们填入10.99.223.156:50000
。
Jenkins 默认就会开放50000端口供Slave节点连接、通信。
因为我们使用的node节点,因此ClusterIP就可以在集群内部访问,因此填写Jenkins的ClusterIP即可。
填写完成后,点击保存即可。
保存后,我们可以看到节点列表中多了一个节点。但是节点的状态是离线的,因为我们还没有启动这个节点。
启动工作节点 点击节点列表中的节点名称,进入节点详情页面。可以看到连接节点的命令,这个命令就是启动节点的命令。
我们在node节点上执行这个命令,启动节点。
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 $ sudo vim /etc/hosts 192.168.100.1 jenkins.test.com gogs.test.com $ sudo yum install java-17-openjdk.x86_64 -y $ sudo mkdir -p /home/jenkins $ sudo chown -R jenkins:jenkins /home/jenkins $ curl -sO http://jenkins.test.com/jnlpJars/agent.jar $ java -jar agent.jar -jnlpUrl http://jenkins.test.com/computer/slave/jenkins-agent.jnlp -secret e74b242a6a58da754a7bdecb0e0511a0fa70f305321974b052a79d6aa8d9c56d -workDir "/home/jenkins" ...... 12月 29, 2023 11:56:51 下午 hudson.remoting.jnlp.Main$CuiListener status 信息: Agent discovery successful Agent address: 10.99.223.156 Agent port: 50000 Identity: de:25:39:3d:94:4e:ca:0b:9b:c7:e8:fb:19:e2:92:70 12月 29, 2023 11:56:51 下午 hudson.remoting.jnlp.Main$CuiListener status 信息: Handshaking 12月 29, 2023 11:56:51 下午 hudson.remoting.jnlp.Main$CuiListener status 信息: Connecting to 10.99.223.156:50000 12月 29, 2023 11:56:51 下午 hudson.remoting.jnlp.Main$CuiListener status 信息: Trying protocol: JNLP4-connect 12月 29, 2023 11:56:51 下午 org.jenkinsci.remoting.protocol.impl.BIONetworkLayer$Reader run 信息: Waiting for ProtocolStack to start. 12月 29, 2023 11:56:52 下午 hudson.remoting.jnlp.Main$CuiListener status 信息: Remote identity confirmed: de:25:39:3d:94:4e:ca:0b:9b:c7:e8:fb:19:e2:92:70 12月 29, 2023 11:56:52 下午 hudson.remoting.jnlp.Main$CuiListener status 信息: Connected
此时我们再回到jenkins的节点列表中,可以看到节点的状态已经变成在线了。
测试工作节点 此时我们进入到free-style-demo
任务中,然后点击配置
,在Gogs Webhook
中,选择限制项目的运行节点
,然后填入slave
,也就是这个任务只能在slave
节点上执行。
然后点击保存,保存成功后,我们再次提交代码,触发jenkins的流水线。
1 2 3 $ echo "test again" > test.md $ git commit -am "test again" $ git push origin master
然后我们可以看到jenkins的流水线已经触发了。
等待build完成后,点击序号,查看build的日志。可以看到build的时候,是在slave节点上执行的。
登录到slave节点上,可以看到slave节点上已经有了我们的代码。
1 2 3 4 5 $ ls /home/jenkins/workspace/free-style-demoLICENSE manage.py moonlight README.md test.md $ cd /home/jenkins/workspace/free-style-demo$ cat test.mdtest again
Jenkins定制化容器 由于每次新部署Jenkins环境,都需要安装很多必要的插件,因此考虑把插件提前做到镜像中,这样再部署的时候就不需要再在线安装插件了。
首先得知道插件都有哪些,我们可以访问Jenkins的url,然后生成插件列表文件。
1 2 3 curl -sSL "http://admin:admin@jenkins.test.com/pluginManager/api/xml?depth=1&xpath=/*/*/shortName|/*/*/version&wrapper=plugins" | perl -pe 's/.*?<shortName>([\w-]+).*?<version>([^<]+)()(<\/\w+>)+/\1:\2\n/g' |sed 's/ /:/' > plugins.txt
插件列表文件大致格式如下,这个文件中包含了我们需要安装的插件。
1 2 3 4 5 6 7 ace-editor:1.1 allure-jenkins-plugin:2.28.1 ant:1.10 antisamy-markup-formatter:1.6 apache-httpcomponents-client-4-api:4.5.10-1.0 authentication-tokens:1.3 ...
下面是一个定制化的Jenkins镜像的Dockerfile文件,主要为了构建一个包含插件的镜像。
1 2 3 4 5 6 7 8 9 10 11 12 13 FROM jenkinsci/blueocean:1.25 .2 LABEL maintainer="me@example.com" ENV JENKINS_UC https://updates.jenkins-zh.cnENV JENKINS_UC_DOWNLOAD https://mirrors.tuna.tsinghua.edu.cn/jenkinsENV JENKINS_OPTS="-Dhudson.model.UpdateCenter.updateCenterUrl=https://updates.jenkins-zh.cn/update-center.json" ENV JENKINS_OPTS="-Djenkins.install.runSetupWizard=false" COPY plugins.txt /usr/share/jenkins/ref/ RUN /usr/local/bin/install-plugins.sh < /usr/share/jenkins/ref/plugins.txt
执行构建,定制jenkins容器
1 2 $ docker build . -t harbor.test.com/jenkins:v1 -f Dockerfile $ docker push harbor.test.com/jenkins:v1
至此,我们已经有了定制化的Jenkins镜像,接下来我们就可以使用这个镜像来部署Jenkins了。
1 2 $ kubectl -n jenkins edit statefulset jenkins