隨着Kubernetes的普遍應用,基於Kubernetes的jenkins發佈模式也需要隨之做出一些改變,本博客基於之前搭建的Kubernetes 1.16.0高可用集羣搭建一套企業級別Jenkins CI/CD發佈流程。
Jenkins採用Pipline發佈,容器化部署,主從結構,Jenkins master負責調度slave,而slave進行拉代碼,打包,構建鏡像發佈等操作,待發布完成後slave自動消亡,不佔用服務器資源。代碼存儲這裏爲了方便採用的Git倉庫,鏡像存儲採用最新的1.9.0 Harbor。
服務器資源:
172.30.0.109 k8smaster1 Harbor
172.30.0.81 k8smaster2
172.30.0.89 k8snode1 Git倉庫
注意:master節點設置爲可調度,也可作爲node,運行業務容器,K8S部署方案,請參考上一篇博客,在這裏不過多描述。
本博客中相關配置文件,後面會上傳到百度網盤中
一、部署Harbor
1、安裝docker-compose
harbor需要基於docker-compose插件進行安裝,管理
# curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
2、安裝docker
Harbor 1.9版本的docker驅動需要至少18.03以上,請自行安裝
3、下載Harbor安裝包
Github上面搜索Harbor
4、修改harbor配置
修改haribor.yml,
若使用IP登錄,需要修改成IP地址,域名登錄,需要修改成域名,這裏Harbor使用的是http模式,若要修改成https訪問,則要修改密鑰配置
Harbor使用非安全認證,docker需要修改安全配置,設置爲新人非安全,否則無法上傳鏡像包
docker.service配置如下
5、Harbor效果,正常上傳鏡像
二、Git倉庫
生產建議使用Gitlab圖形化工具,方便管理
1、初始化Git服務器
下載git
# yum install git -y
# useradd git
# groupadd git
# su - git 切換到git用戶,創建倉庫
# mkdir tomcat-java-demo
# cd tomcat-java-demo
# git init --bare 初始化git
# git服務器初始化完成
2、上傳代碼到Git倉庫
解壓java demo代碼
# unzip tomcat-java-demo.zip
# cd tomcat-java-demo
# git init 初始化客戶端git,準備上傳代碼至遠程服務端
# git add . 添加代碼至本地git倉庫
# git commit -m 'test'
# git remote add origin [email protected]:/home/git/tomcat-java-demo 設置git倉庫爲遠程客戶端
# git push origin master 上傳代碼至遠程客戶端master分支
驗證代碼是否正常上傳:
重新創建一個目錄,初始化git,拉取代碼
# mkdir test && cd test
# git init && git remote add origin [email protected]:/home/git/tomcat-java-demo
# git pull origin master
代碼拉取成功,上傳代碼無誤
上傳代碼至指定分支,如1.0.0
本地創建1.0.0的分支,切換到1.0.0分支,因爲默認是在master分支,然後上傳代碼到遠程1.0.0分支
# git branch 1.0.0 創建1.0.0分支
# git checkout 1.0.0 切換到1.0.0分支
# git push origin 1.0.0 代碼上傳到遠程1.0.0
會在遠程git服務器上看到多了一個1.0.0分支
三、Jenkins部署
1、部署Jenkins master
[root@k8s-master1 jenkins]# cat jenkins.yml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: jenkins
labels:
name: jenkins
spec:
serviceName: jenkins
replicas: 1
updateStrategy:
type: RollingUpdate
selector:
matchLabels:
name: jenkins
template:
metadata:
name: jenkins
labels:
name: jenkins
spec:
terminationGracePeriodSeconds: 10
serviceAccountName: jenkins
#imagePullSecrets:
# - name: registry-pull-secret
nodeName: k8s-master1
containers:
- name: jenkins
image: jenkins/jenkins:lts
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
- containerPort: 50000
resources:
limits:
cpu: 1
memory: 1Gi
requests:
cpu: 0.5
memory: 500Mi
env:
- name: LIMITS_MEMORY
valueFrom:
resourceFieldRef:
resource: limits.memory
divisor: 1Mi
- name: JAVA_OPTS
# value: -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1 -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85
value: -Xmx$(LIMITS_MEMORY)m -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85
volumeMounts:
- name: data
mountPath: /var/jenkins_home
securityContext:
fsGroup: 1000
volumes:
- name: data
hostPath:
path: /app/jenkins
---
apiVersion: v1
kind: Service
metadata:
name: jenkins
spec:
type: NodePort
selector:
name: jenkins
ports:
-
name: http
port: 80
targetPort: 8080
protocol: TCP
nodePort: 30009
-
name: agent
port: 50000
protocol: TCP
對jenkins容器進行授權
[root@k8s-master1 jenkins]# cat rbac.yaml
# In GKE need to get RBAC permissions first with
# kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin [--user=<user-name>|--group=<group-name>]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: jenkins
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get","list","watch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: jenkins
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jenkins
subjects:
- kind: ServiceAccount
name: jenkins
# kubectl apply -f rbac.yaml
# kubectl apply -f jenkins.yaml
訪問http://172.30.0.109:30009 打開Jenkins web頁面,插件安裝默認就好,之後再到插件管理頁面自行安裝需要的插件
2、Jenkins系統配置
①集成Kubernetes到Jenkins中
在系統管理的系統設置中,修改配置
修改後可以進行連接測試,在右下角
②下載Jenkins與Kubernetes集成的插件
在系統管理的插件管理中
Kubernetes
Kubernetes Continuous Deploy
Extended Choice Parameter
③配置Git倉庫訪問密鑰以及Jenkins容器訪問Kubernetes使用的kubeconfig配置
在憑據中
訪問Git服務器的密鑰,只需要做Jenkins服務器到Git無密登錄,並複製Jenkins所在服務器的私鑰到以上位置,即可實現代碼拉取過程的無密登錄
將K8S集羣/root/.kube/config文件複製到以上地區,使Jenkins可以訪問K8S集羣,部署pod
3、Jenkins slave
構建Jenkins Slave,再Jenkins上通過Pipline流水線調用JnekinsFile進行發佈操作
Jenkins Slave Dockerfile:
構建鏡像
# docker build -t 172.30.0.109/wujqc/jenkins-slave:lts -f dockerfile-jenkins-slave .
上傳到Harbor上
# docker login 172.30.0.109
輸入harbor管理員賬號密碼,進行登錄
# docker push 172.30.0.109/wujqc/jenkins-slave:lts
4、創建Pipline發佈Java項目到K8S環境
①創建流水線項目
②設置參數化構建
可以通過標籤,字符參數指定代碼分支,Branch等多種方式去拉取Git,Gitlab指定位置的代碼,進行編譯,這裏採用的是字符參數指定代碼分支的方式
③配置Pipline流水線
設置git地址,配置能夠拉取git的免登錄密鑰(前面配置的)
通過字符參數Tag,獲取到想要編譯的代碼分支,如1.0.0,載入變量origin/1.0.0拉取代碼,在拉取的代碼中讀取JenkinsFile進行下一步Jenkins Slave的maven構建,鏡像構建,K8S deploy操作
可以說整個Jenkins項目中,是通過${Tag}版本去拉取指定分支的JenkinsFile以及代碼,在此基礎上進行的流水線式部署,JenkinsFile中封裝的就是整個打包編譯,拉取指定服務的dockerfile,deploy.yaml,構建鏡像,上傳鏡像,部署K8S deploy.yaml的流水線操作。
注意:JenkinsFile需要在git代碼路徑中,要不然Jenkins識別不到,會報NotFoundFile
JenkinsFile文件如下:
注意:這兩處ID,需要替換成Jenkins上面的git,kubeconfig密鑰ID
因爲Jenkins Slave需要要到Docker進行鏡像構建,上傳操作,於是將docker以掛載的方式放入Jenkins Slave中,讓其能夠使用
Download Deploy File操作,是爲了區分各個系統服務,微服務模塊,因爲不同的服務模塊,其deploy.yaml以及Dockerfile可能都不一樣,所以需要有一個統一管理的路徑去獲取到這兩個文件,方便管理,只需要將目錄掛載到Jenkins Slave中即可,這個路徑,可以採用NFS,在這裏爲了方便使用的hostpath,生產不建議這麼使用
5、啓動Pipline項目,輸入分支號1.0.0
構建成功!