隨着Kubernetes的廣泛應用,基於Kubernetes的jenkins發佈模式也須要隨之作出一些改變,本博客基於以前搭建的Kubernetes 1.16.0高可用集羣搭建一套企業級別Jenkins CI/CD發佈流程。java
Jenkins採用Pipline發佈,容器化部署,主從結構,Jenkins master負責調度slave,而slave進行拉代碼,打包,構建鏡像發佈等操做,待發布完成後slave自動消亡,不佔用服務器資源。代碼存儲這裏爲了方便採用的Git倉庫,鏡像存儲採用最新的1.9.0 Harbor。
node
服務器資源:git
172.30.0.109 k8smaster1 Harborgithub
172.30.0.81 k8smaster2 web
172.30.0.89 k8snode1 Git倉庫docker
注意:master節點設置爲可調度,也可做爲node,運行業務容器,K8S部署方案,請參考上一篇博客,在這裏不過多描述。api
本博客中相關配置文件,後面會上傳到百度網盤中
tomcat
1、部署Harbor安全
一、安裝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
二、安裝docker
Harbor 1.9版本的docker驅動須要至少18.03以上,請自行安裝
三、下載Harbor安裝包
Github上面搜索Harbor
四、修改harbor配置
修改haribor.yml,
若使用IP登陸,須要修改爲IP地址,域名登陸,須要修改爲域名,這裏Harbor使用的是http模式,若要修改爲https訪問,則要修改密鑰配置
Harbor使用非安全認證,docker須要修改安全配置,設置爲新人非安全,不然沒法上傳鏡像包
docker.service配置以下
五、Harbor效果,正常上傳鏡像
2、Git倉庫
生產建議使用Gitlab圖形化工具,方便管理
一、初始化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服務器初始化完成
二、上傳代碼到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 git@172.30.0.89:/home/git/tomcat-java-demo 設置git倉庫爲遠程客戶端
# git push origin master 上傳代碼至遠程客戶端master分支
驗證代碼是否正常上傳:
從新建立一個目錄,初始化git,拉取代碼
# mkdir test && cd test
# git init && git remote add origin git@172.30.0.89:/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分支
3、Jenkins部署
一、部署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頁面,插件安裝默認就好,以後再到插件管理頁面自行安裝須要的插件
二、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
三、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
四、建立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,生產不建議這麼使用
五、啓動Pipline項目,輸入分支號1.0.0
構建成功!