前言
本篇文章基于 k8s 集群部署 gitlab、sonarQube、Jenkins 等工具,并把上述工具集成到 Jenkins 中,以 Django 項(xiàng)目和 SpringBoot 項(xiàng)目為例,通過(guò)多分支流水線及 Jenkinsfile 實(shí)現(xiàn)項(xiàng)目代碼提交到不同的倉(cāng)庫(kù)分支,實(shí)現(xiàn)自動(dòng)代碼掃描、單元測(cè)試、docker 容器構(gòu)建、k8s 服務(wù)的自動(dòng)部署。
1. DevOps介紹
Continuous Integration (CI) 和 Continuous Delivery (CD)
傳統(tǒng)的軟件交付流程如下:
一個(gè)軟件從零開(kāi)始到最終交付,大概包括以下幾個(gè)階段:規(guī)劃、編碼、構(gòu)建、測(cè)試、發(fā)布、部署和維護(hù),基于這些階段,我們的軟件交付模型大致經(jīng)歷了以下幾個(gè)階段。
?? 瀑布式流程
前期需求確立之后,軟件開(kāi)發(fā)人員花費(fèi)數(shù)周和數(shù)月編寫代碼,把所有需求一次性開(kāi)發(fā)完,然后將代碼交給 QA(質(zhì)量保障)團(tuán)隊(duì)進(jìn)行測(cè)試,然后將最終的發(fā)布版交給運(yùn)維團(tuán)隊(duì)去部署。
瀑布模型,簡(jiǎn)單來(lái)說(shuō),就是等一個(gè)階段所有工作完成之后,再進(jìn)入下一個(gè)階段。這種模式的問(wèn)題也很明顯,產(chǎn)品迭代周期長(zhǎng),靈活性差。一個(gè)周期動(dòng)輒幾周幾個(gè)月,適應(yīng)不了當(dāng)下產(chǎn)品需要快速迭代的場(chǎng)景。
?? 敏捷開(kāi)發(fā)
任務(wù)由大拆小,開(kāi)發(fā)、測(cè)試協(xié)同工作,注重開(kāi)發(fā)敏捷,不重視交付敏捷。
?? DevOps
開(kāi)發(fā)、測(cè)試、運(yùn)維協(xié)同工作,持續(xù)開(kāi)發(fā)+持續(xù)交付。
我們是否可以認(rèn)為 DevOps = 提倡開(kāi)發(fā)、測(cè)試、運(yùn)維協(xié)同工作來(lái)實(shí)現(xiàn)持續(xù)開(kāi)發(fā)、持續(xù)交付的一種軟件交付模式?
大家想一下為什么最初的開(kāi)發(fā)模式?jīng)]有直接進(jìn)入 DevOps 的時(shí)代?
原因是:溝通成本。
各角色人員去溝通協(xié)作的時(shí)候都是手動(dòng)去做,交流靠嘴,靠人去指揮,很顯然會(huì)出大問(wèn)題。所以說(shuō)不能認(rèn)為 DevOps 就是一種交付模式,因?yàn)榻鉀Q不了溝通協(xié)作成本,這種模式就不具備可落地性。
那 DevOps 時(shí)代如何解決角色之間的成本問(wèn)題?DevOps 的核心就是自動(dòng)化。自動(dòng)化的能力靠什么來(lái)支撐,工具和技術(shù)。
DevOps工具鏈
靠這些工具和技術(shù),才實(shí)現(xiàn)了自動(dòng)化流程,進(jìn)而解決了協(xié)作成本,使得 devops 具備了可落地性。因此我們可以大致給 devops 一個(gè)定義:
devops = 提倡開(kāi)發(fā)、測(cè)試、運(yùn)維協(xié)同工作來(lái)實(shí)現(xiàn)持續(xù)開(kāi)發(fā)、持續(xù)交付的一種軟件交付模式 + 基于工具和技術(shù)支撐的自動(dòng)化流程的落地實(shí)踐。
因此 devops 不是某一個(gè)具體的技術(shù),而是一種思想+自動(dòng)化能力,來(lái)使得構(gòu)建、測(cè)試、發(fā)布軟件能夠更加地便捷、頻繁和可靠的落地實(shí)踐。
本篇文章的核心內(nèi)容就是要教會(huì)大家如何利用工具和技術(shù)來(lái)實(shí)現(xiàn)完整的 DevOps 平臺(tái)的建設(shè)。我們主要使用的工具有:
- gitlab,代碼倉(cāng)庫(kù),企業(yè)內(nèi)部使用最多的代碼版本管理工具。
- Jenkins, 一個(gè)可擴(kuò)展的持續(xù)集成引擎,用于自動(dòng)化各種任務(wù),包括構(gòu)建、測(cè)試和部署軟件。
- robotFramework, 基于Python的自動(dòng)化測(cè)試框架
- sonarqube,代碼質(zhì)量管理平臺(tái)
- maven,java包構(gòu)建管理工具
- Kubernetes
- Docker
2. Jenkins初體驗(yàn)
關(guān)于 Jenkins 的介紹這里不過(guò)多敘述,除了下面我自己的部署方案,大家還可以參考這個(gè)網(wǎng)站:Jenkins部署方案
?? K8s環(huán)境中部署jenkins
安裝的注意點(diǎn):
- 第一次啟動(dòng)很慢
- 因?yàn)楹竺?Jenkins 會(huì)與 kubernetes 集群進(jìn)行集成,會(huì)需要調(diào)用 kubernetes 集群的 api,因此安裝的時(shí)候創(chuàng)建了 ServiceAccount 并賦予了 cluster-admin 的權(quán)限
- 初始化容器來(lái)設(shè)置權(quán)限
- ingress 來(lái)外部訪問(wèn)
- 數(shù)據(jù)存儲(chǔ)通過(guò) pvc 掛載到宿主機(jī)中
(1)jenkins/jenkins-all.yaml
文件
apiVersion: v1
kind: Namespace
metadata:
name: jenkins
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: jenkins
namespace: jenkins
spec:
accessModes:
- ReadWriteOnce
storageClassName: nfs
resources:
requests:
storage: 200Gi
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins
namespace: jenkins
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: jenkins-crb
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: jenkins
namespace: jenkins
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins-master
namespace: jenkins
spec:
replicas: 1
selector:
matchLabels:
devops: jenkins-master
template:
metadata:
labels:
devops: jenkins-master
spec:
serviceAccount: jenkins #Pod 需要使用的服務(wù)賬號(hào)
initContainers:
- name: fix-permissions
image: busybox
command: ["sh", "-c", "chown -R 1000:1000 /var/jenkins_home"]
securityContext:
privileged: true
volumeMounts:
- name: jenkinshome
mountPath: /var/jenkins_home
containers:
- name: jenkins
image: jenkinsci/blueocean:1.24.7
imagePullPolicy: IfNotPresent
ports:
- name: http #Jenkins Master Web 服務(wù)端口
containerPort: 8080
- name: slavelistener #Jenkins Master 供未來(lái) Slave 連接的端口
containerPort: 50000
volumeMounts:
- name: jenkinshome
mountPath: /var/jenkins_home
env:
- name: JAVA_OPTS
value: "-Xms4096m -Xmx5120m -Duser.timezone=Asia/Shanghai -Dhudson.model.DirectoryBrowserSupport.CSP="
volumes:
- name: jenkinshome
persistentVolumeClaim:
claimName: jenkins
---
apiVersion: v1
kind: Service
metadata:
name: jenkins
namespace: jenkins
spec:
ports:
- name: http
port: 8080
targetPort: 8080
- name: slavelistener
port: 50000
targetPort: 50000
type: ClusterIP
selector:
devops: jenkins-master
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: jenkins-web
namespace: jenkins
spec:
rules:
- host: jenkins.luffy.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: jenkins
port:
number: 8080
(2)創(chuàng)建服務(wù):
## 部署服務(wù)
$ kubectl create -f jenkins-all.yaml
## 查看服務(wù)
$ kubectl -n jenkins get po
NAME READY STATUS RESTARTS AGE
jenkins-master-767df9b574-lgdr5 1/1 Running 0 20s
# 查看日志,第一次啟動(dòng)提示需要完成初始化設(shè)置
$ kubectl -n jenkins logs -f jenkins-master-767df9b574-lgdr5
......
*************************************************************
Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:
5396b4e1c395450f8360efd8ee641b18
This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
*************************************************************
(3)訪問(wèn)服務(wù):
配置 hosts
解析,172.21.51.143 jenkins.luffy.com
,然后使用瀏覽器域名訪問(wèn)服務(wù)。第一次訪問(wèn)需要大概幾分鐘的初始化時(shí)間。
使用 jenkins 啟動(dòng)日志中的密碼,或者執(zhí)行下面的命令獲取解鎖的管理員密碼:
$ kubectl -n jenkins exec jenkins-master-767df9b574-lgdr5 bash
/ # cat /var/jenkins_home/secrets/initialAdminPassword
35b083de1d25409eaef57255e0da481a
點(diǎn)擊叉號(hào),跳過(guò)選擇安裝推薦的插件環(huán)節(jié),直接進(jìn)入 Jenkins。由于默認(rèn)的插件地址安裝非常慢,我們可以替換成國(guó)內(nèi)清華的源,進(jìn)入 jenkins 工作目錄,目錄下面有一個(gè) updates 的目錄,下面有一個(gè) default.json 文件,我們執(zhí)行下面的命令替換插件地址:
$ cd /var/jenkins_home/updates
$ sed -i 's/http:\/\/updates.jenkins-ci.org\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json
$ sed -i 's/http:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json
注意:暫時(shí)先不用重新啟動(dòng) pod,漢化后一起重啟。
選擇右上角 admin->configure->password
重新設(shè)置管理員密碼,設(shè)置完后,會(huì)退出要求重新登錄,使用 admin/xxxxxx
(新密碼),登錄即可。
?? 安裝漢化插件
Jenkins -> manage Jenkins -> Plugin Manager -> Avaliable
,搜索 chinese
關(guān)鍵字
選中后,選擇 [Install without restart]
,等待下載完成,然后點(diǎn)擊 [ Restart Jenkins when installation is complete and no jobs are running ]
,讓 Jenkins 自動(dòng)重啟
啟動(dòng)后,界面默認(rèn)變成中文。
3. Jenkins基本使用演示
?? 演示目標(biāo)
- 代碼提交 gitlab,自動(dòng)觸發(fā) Jenkins 任務(wù)
- Jenkins 任務(wù)完成后發(fā)送釘釘消息通知
?? 演示準(zhǔn)備
gitlab 代碼倉(cāng)庫(kù)搭建
## 全量部署的組件
$ gitlab-ctl status
run: alertmanager: (pid 1987) 27s; run: log: (pid 1986) 27s
run: gitaly: (pid 1950) 28s; run: log: (pid 1949) 28s
run: gitlab-exporter: (pid 1985) 27s; run: log: (pid 1984) 27s
run: gitlab-workhorse: (pid 1956) 28s; run: log: (pid 1955) 28s
run: logrotate: (pid 1960) 28s; run: log: (pid 1959) 28s
run: nginx: (pid 2439) 1s; run: log: (pid 1990) 27s
run: node-exporter: (pid 1963) 28s; run: log: (pid 1962) 28s
run: postgres-exporter: (pid 1989) 27s; run: log: (pid 1988) 27s
run: postgresql: (pid 1945) 28s; run: log: (pid 1944) 28s
run: prometheus: (pid 1973) 28s; run: log: (pid 1972) 28s
run: puma: (pid 1968) 28s; run: log: (pid 1966) 28s
run: redis: (pid 1952) 28s; run: log: (pid 1951) 28s
run: redis-exporter: (pid 1971) 28s; run: log: (pid 1964) 28s
run: sidekiq: (pid 1969) 28s; run: log: (pid 1967) 28s
部署分析:
- 依賴 postgres
- 依賴 redis
使用 k8s 部署:
(1)準(zhǔn)備 secret 文件
$ cat gitlab-secret.txt
postgres.user.root=root
postgres.pwd.root=1qaz2wsx
$ kubectl -n jenkins create secret generic gitlab-secret --from-env-file=gitlab-secret.txt
(2)部署postgres
注意點(diǎn):
- 使用 secret 來(lái)引用賬戶密碼
- 使用 postgres=true 來(lái)指定節(jié)點(diǎn)
$ cat postgres.yaml
apiVersion: v1
kind: Service
metadata:
name: postgres
labels:
app: postgres
namespace: jenkins
spec:
ports:
- name: server
port: 5432
targetPort: 5432
protocol: TCP
selector:
app: postgres
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: postgredb
namespace: jenkins
spec:
accessModes:
- ReadWriteOnce
storageClassName: nfs
resources:
requests:
storage: 200Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: jenkins
name: postgres
labels:
app: postgres
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
tolerations:
- operator: "Exists"
containers:
- name: postgres
image: postgres:11.4
imagePullPolicy: "IfNotPresent"
ports:
- containerPort: 5432
env:
- name: POSTGRES_USER #PostgreSQL 用戶名
valueFrom:
secretKeyRef:
name: gitlab-secret
key: postgres.user.root
- name: POSTGRES_PASSWORD #PostgreSQL 密碼
valueFrom:
secretKeyRef:
name: gitlab-secret
key: postgres.pwd.root
resources:
limits:
cpu: 1000m
memory: 2048Mi
requests:
cpu: 50m
memory: 100Mi
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgredb
volumes:
- name: postgredb
persistentVolumeClaim:
claimName: postgredb
#創(chuàng)建postgres
$ kubectl create -f postgres.yaml
# 創(chuàng)建數(shù)據(jù)庫(kù)gitlab,為后面部署gitlab組件使用
$ kubectl -n jenkins exec -ti postgres-7ff9b49f4c-nt8zh bash
root@postgres-7ff9b49f4c-nt8zh:/# psql
root=# create database gitlab;
CREATE DATABASE
(3)部署 redis
$ cat redis.yaml
apiVersion: v1
kind: Service
metadata:
name: redis
labels:
app: redis
namespace: jenkins
spec:
ports:
- name: server
port: 6379
targetPort: 6379
protocol: TCP
selector:
app: redis
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: jenkins
name: redis
labels:
app: redis
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
tolerations:
- operator: "Exists"
containers:
- name: redis
image: sameersbn/redis:4.0.9-2
imagePullPolicy: "IfNotPresent"
ports:
- containerPort: 6379
resources:
limits:
cpu: 1000m
memory: 2048Mi
requests:
cpu: 50m
memory: 100Mi
# 創(chuàng)建
$ kubectl create -f redis.yaml
(4)部署gitlab
注意點(diǎn):
- 使用 ingress 暴漏服務(wù)
- 添加 annotation,指定 nginx 端上傳大小限制,否則推送代碼時(shí)會(huì)默認(rèn)被限制 1m 大小,相當(dāng)于給 nginx 設(shè)置
client_max_body_size
的限制大小 - 使用服務(wù)發(fā)現(xiàn)地址來(lái)訪問(wèn) postgres 和 redis
- 在 secret 中引用數(shù)據(jù)庫(kù)賬戶和密碼
- 數(shù)據(jù)庫(kù)名稱為 gitlab
$ cat gitlab.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gitlab
namespace: jenkins
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
spec:
rules:
- host: gitlab.luffy.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: gitlab
port:
number: 80
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: gitlab
namespace: jenkins
spec:
accessModes:
- ReadWriteOnce
storageClassName: nfs
resources:
requests:
storage: 200Gi
---
apiVersion: v1
kind: Service
metadata:
name: gitlab
labels:
app: gitlab
namespace: jenkins
spec:
ports:
- name: server
port: 80
targetPort: 80
protocol: TCP
selector:
app: gitlab
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: jenkins
name: gitlab
labels:
app: gitlab
spec:
replicas: 1
selector:
matchLabels:
app: gitlab
template:
metadata:
labels:
app: gitlab
spec:
tolerations:
- operator: "Exists"
containers:
- name: gitlab
image: sameersbn/gitlab:13.2.2
imagePullPolicy: "IfNotPresent"
env:
- name: GITLAB_HOST
value: "gitlab.luffy.com"
- name: GITLAB_PORT
value: "80"
- name: GITLAB_SECRETS_DB_KEY_BASE
value: "long-and-random-alpha-numeric-string"
- name: GITLAB_SECRETS_DB_KEY_BASE
value: "long-and-random-alpha-numeric-string"
- name: GITLAB_SECRETS_SECRET_KEY_BASE
value: "long-and-random-alpha-numeric-string"
- name: GITLAB_SECRETS_OTP_KEY_BASE
value: "long-and-random-alpha-numeric-string"
- name: DB_HOST
value: "postgres"
- name: DB_NAME
value: "gitlab"
- name: DB_USER
valueFrom:
secretKeyRef:
name: gitlab-secret
key: postgres.user.root
- name: DB_PASS
valueFrom:
secretKeyRef:
name: gitlab-secret
key: postgres.pwd.root
- name: REDIS_HOST
value: "redis"
- name: REDIS_PORT
value: "6379"
ports:
- containerPort: 80
resources:
limits:
cpu: 2000m
memory: 5048Mi
requests:
cpu: 100m
memory: 500Mi
volumeMounts:
- mountPath: /home/git/data
name: data
volumes:
- name: data
persistentVolumeClaim:
claimName: gitlab
# 創(chuàng)建
$ kubectl create -f gitlab.yaml
配置 hosts 解析:
172.21.51.143 gitlab.luffy.com
設(shè)置root密碼
訪問(wèn) http://gitlab.luffy.com
,設(shè)置管理員密碼
配置 k8s-master 節(jié)點(diǎn)的 hosts
$ echo "172.21.51.143 gitlab.luffy.com" >>/etc/hosts
myblog 項(xiàng)目推送到 gitlab
mkdir demo
cp -r python-demo demo/
cd demo/myblog
git remote rename origin old-origin
git remote add origin http://gitlab.luffy.com/root/myblog.git
git push -u origin --all
git push -u origin --tags
釘釘推送
官方文檔
-
配置機(jī)器人
-
試驗(yàn)發(fā)送消息
$ curl 'https://oapi.dingtalk.com/robot/send?access_token=4778abd23dbdbaf66fc6f413e6ab9c0103a039b0054201344a22a5692cdcc54e' \
-H 'Content-Type: application/json' \
-d '{"msgtype": "text",
"text": {
"content": "基于K8s的DevOps平臺(tái)實(shí)踐"
}
}'
?? 演示過(guò)程
流程示意圖:
(1)安裝 gitlab plugin
插件中心搜索并安裝gitlab,直接安裝即可
(2)配置 Gitlab
系統(tǒng)管理->系統(tǒng)配置->Gitlab,其中的 API Token
,需要從下個(gè)步驟中獲取
(3)獲取 AccessToken
登錄 gitlab,選擇 user->Settings->access tokens
新建一個(gè)訪問(wèn) token
(4)配置 host 解析
由于我們的 Jenkins 和 gitlab 域名是本地解析,因此需要讓 itlab 和 Jenkins 服務(wù)可以解析到對(duì)方的域名。兩種方式:
-
在容器內(nèi)配置hosts
-
配置coredns的靜態(tài)解析
hosts {
172.21.51.143 jenkins.luffy.com gitlab.luffy.com
fallthrough
}
(5)創(chuàng)建自由風(fēng)格項(xiàng)目
- gitlab connection 選擇為剛創(chuàng)建的 gitlab
- 源碼管理選擇 Git,填項(xiàng)項(xiàng)目地址
- 新建一個(gè) Credentials 認(rèn)證,使用用戶名密碼方式,配置 gitlab 的用戶和密碼
- 構(gòu)建觸發(fā)器選擇
Build when a change is pushed to GitLab
- 生成一個(gè)
Secret token
- 保存
(6)到 gitlab 配置 webhook
- 進(jìn)入項(xiàng)目下
settings->Integrations
- URL:
http://jenkins.luffy.com/project/free
- Secret Token 填入在 Jenkins 端生成的token
- Add webhook
- test push events,報(bào)錯(cuò):
Requests to the local network are not allowed
(7)設(shè)置 gitlab 允許向本地網(wǎng)絡(luò)發(fā)送 webhook 請(qǐng)求
訪問(wèn) Admin Aera -> Settings -> Network
,展開(kāi)Outbound requests
Collapse,勾選第一項(xiàng)即可。再次 test push events
,成功。
(8)配置 free 項(xiàng)目,增加構(gòu)建步驟,執(zhí)行 shell,將發(fā)送釘釘消息的 shell 保存
(9)提交代碼到 gitlab 倉(cāng)庫(kù),查看構(gòu)建是否自動(dòng)執(zhí)行
4. Master-Slaves(agent)模式
上面演示的任務(wù),默認(rèn)都是在 master 節(jié)點(diǎn)執(zhí)行的,多個(gè)任務(wù)都在 master 節(jié)點(diǎn)執(zhí)行,對(duì) master 節(jié)點(diǎn)的性能會(huì)造成一定影響,如何將任務(wù)分散到不同的節(jié)點(diǎn),做成多 slave 的方式?
(1)添加 slave 節(jié)點(diǎn)
- 系統(tǒng)管理 -> 節(jié)點(diǎn)管理 -> 新建節(jié)點(diǎn)
- 比如添加
172.21.51.68
,選擇固定節(jié)點(diǎn),保存 - 遠(yuǎn)程工作目錄
/opt/jenkins_jobs
- 標(biāo)簽為任務(wù)選擇節(jié)點(diǎn)的依據(jù),如
172.21.51.68
- 啟動(dòng)方式選擇通過(guò)
java web
啟動(dòng)代理,代理是運(yùn)行jar
包,通過(guò)JNLP
(是一種允許客戶端啟動(dòng)托管在遠(yuǎn)程 Web 服務(wù)器上的應(yīng)用程序的協(xié)議 )啟動(dòng)連接到 maste r節(jié)點(diǎn)服務(wù)中
(2)執(zhí)行 java 命令啟動(dòng) agent 服務(wù)
## 登錄172.21.51.68,下載agent.jar
$ wget http://jenkins.luffy.com/jnlpJars/agent.jar
## 會(huì)提示找不到agent錯(cuò)誤,因?yàn)闆](méi)有配置地址解析,由于連接jenkins master會(huì)通過(guò)50000端口,直接使用cluster-ip
$ kubectl -n jenkins get svc #在master節(jié)點(diǎn)執(zhí)行查詢cluster-ip地址
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
jenkins ClusterIP 10.99.204.208 <none> 8080/TCP,50000/TCP 4h8m
## 再次回到68節(jié)點(diǎn)
$ wget 10.99.204.208:8080/jnlpJars/agent.jar
$ java -jar agent.jar -jnlpUrl http://10.99.204.208:8080/computer/172.21.51.68/slave-agent.jnlp -secret 4be4d164f861d2830835653567867a1e695b30c320d35eca2be9f5624f8712c8 -workDir "/opt/jenkins_jobs"
...
INFO: Remoting server accepts the following protocols: [JNLP4-connect, Ping]
Apr 01, 2020 7:03:51 PM hudson.remoting.jnlp.Main$CuiListener status
INFO: Agent discovery successful
Agent address: 10.99.204.208
Agent port: 50000
Identity: e4:46:3a:de:86:24:8e:15:09:13:3d:a7:4e:07:04:37
Apr 01, 2020 7:03:51 PM hudson.remoting.jnlp.Main$CuiListener status
INFO: Handshaking
Apr 01, 2020 7:03:51 PM hudson.remoting.jnlp.Main$CuiListener status
INFO: Connecting to 10.99.204.208:50000
Apr 01, 2020 7:03:51 PM hudson.remoting.jnlp.Main$CuiListener status
INFO: Trying protocol: JNLP4-connect
Apr 01, 2020 7:04:02 PM hudson.remoting.jnlp.Main$CuiListener status
INFO: Remote identity confirmed: e4:46:3a:de:86:24:8e:15:09:13:3d:a7:4e:07:04:37
Apr 01, 2020 7:04:03 PM hudson.remoting.jnlp.Main$CuiListener status
INFO: Connected
若出現(xiàn)如下錯(cuò)誤:
SEVERE: http://jenkins.luffy.com/ provided port:50000 is not reachable
java.io.IOException: http://jenkins.luffy.com/ provided port:50000 is not reachable
at org.jenkinsci.remoting.engine.JnlpAgentEndpointResolver.resolve(JnlpAgentEndpointResolver.java:311)
at hudson.remoting.Engine.innerRun(Engine.java:689)
at hudson.remoting.Engine.run(Engine.java:514)
可以選擇: 配置從節(jié)點(diǎn) -> 高級(jí) -> Tunnel連接位置
,參考下圖進(jìn)行設(shè)置:
(3)查看 Jenkins 節(jié)點(diǎn)列表,新節(jié)點(diǎn)已經(jīng)處于可用狀態(tài)
(4)測(cè)試使用新節(jié)點(diǎn)執(zhí)行任務(wù)
-
配置
free
項(xiàng)目 -
限制項(xiàng)目的運(yùn)行節(jié)點(diǎn) ,標(biāo)簽表達(dá)式選擇
172.21.51.68
-
立即構(gòu)建
-
查看構(gòu)建日志
Started by user admin
Running as SYSTEM
Building remotely on 172.21.51.68 in workspace /opt/jenkins_jobs/workspace/free-demo
using credential gitlab-user
Cloning the remote Git repository
Cloning repository http://gitlab.luffy.com/root/myblog.git
> git init /opt/jenkins_jobs/workspace/free-demo # timeout=10
...
5. Jenkins定制化容器
由于每次新部署 Jenkins 環(huán)境,均需要安裝很多必要的插件,因此考慮把插件提前做到鏡像中。
Dockerfile
FROM jenkinsci/blueocean:1.23.2
LABEL maintainer="inspur_lyx@hotmail.com"
ENV JENKINS_UC https://updates.jenkins-zh.cn
ENV JENKINS_UC_DOWNLOAD https://mirrors.tuna.tsinghua.edu.cn/jenkins
ENV JENKINS_OPTS="-Dhudson.model.UpdateCenter.updateCenterUrl=https://updates.jenkins-zh.cn/update-center.json"
ENV JENKINS_OPTS="-Djenkins.install.runSetupWizard=false"
## 用最新的插件列表文件替換默認(rèn)插件文件
COPY plugins.txt /usr/share/jenkins/ref/
## 執(zhí)行插件安裝
RUN /usr/local/bin/install-plugins.sh < /usr/share/jenkins/ref/plugins.txt
plugins.txt
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
...
get_plugin.sh
admin:
123456@localhost
需要替換成 Jenkins 的用戶名、密碼及訪問(wèn)地址
#!/usr/bin/env bash
curl -sSL "http://admin:123456@localhost:8080/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
執(zhí)行構(gòu)建,定制 jenkins 容器
$ docker build . -t 172.21.51.143:5000/jenkins:v20200414 -f Dockerfile
$ docker push 172.21.51.143:5000/jenkins:v20200414
至此,我們可以使用定制化的鏡像啟動(dòng) jenkins 服務(wù)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-780461.html
## 刪掉當(dāng)前服務(wù)
$ kubectl delete -f jenkins-all.yaml
## 刪掉已掛載的數(shù)據(jù)
$ rm -rf /var/jenkins_home
## 替換使用定制化鏡像
$ sed -i 's#jenkinsci/blueocean#172.21.51.143:5000/jenkins:v20200404#g' jenkins-all.yaml
## 重新創(chuàng)建服務(wù)
$ kubectl create -f jenkins-all.yaml
6. 總結(jié)
自由風(fēng)格項(xiàng)目弊端:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-780461.html
- 任務(wù)的完成需要在Jenkins端維護(hù)大量的配置
- 沒(méi)法做版本控制
- 可讀性、可移植性很差,不夠優(yōu)雅
到了這里,關(guān)于基于K8s的DevOps平臺(tái)實(shí)踐(一)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!