這篇寫好一段時間了,一直也沒發佈上來,今天稍微整理下了交下做業,部份內容偷懶引用了一些別人的內容。
使用Jenkins作持續集成/持續交付,當業務達到必定規模的時候,Jenkins自己就很容易成爲整條流水線的瓶頸,各個業務端都依靠Jenkins,部署Jenkins服務時如何保障服務的高可用變得尤其重要。
以微醫爲例,目前Jenkins的業務承載量:>1,000 Build Jobs,>5,000 Buils/Day,光依靠單master已經沒法承載高併發的性能壓力,瓶頸來自多方面,不只僅是Jenkins 應用自己佔用 memory 和 CPU 資源,也包括各個job編譯、測試、部署等的資源開銷,隨着job數量的增長,大量的workspace也會耗盡服務器的存儲空間,嚴重影響整個技術團隊的工做效率和部署節奏。java
Jenkins 分佈式架構是由一個 Master 和多個 Slave Node組成的 分佈式架構。在 Jenkins Master 上管理你的項目,能夠把你的一些構建任務分擔到不一樣的 Slave Node 上運行,Master 的性能就提升了。
Master/Slave至關於Server和agent的概念。Master提供web接口讓用戶來管理job和slave,job能夠運行在master本機或者被分配到slave上運行構建。
一個master(jenkins服務所在機器)能夠關聯多個slave用來爲不一樣的job或相同的job的不一樣配置來服務。node
傳統的 Jenkins Slave 一主多從式會存在一些痛點。好比:git
因爲以上種種痛點,咱們渴望一種更高效更可靠的方式來完成這個 CI/CD 流程,而虛擬化容器技術能很好的解決這個痛點,下圖是基於 Kubernetes 搭建 Jenkins 集羣的簡單示意圖。github
Jenkins Master 和 Jenkins Slave 以 Docker Container 形式運行在 Kubernetes 集羣的 Node 上,Master 運行在其中一個節點,而且將其配置數據存儲到一個 Volume 上去,Slave 運行在各個節點上,而且它不是一直處於運行狀態,它會按照需求動態的建立並自動刪除。
這種方式的工做流程大體爲:當 Jenkins Master 接受到 Build 請求時,會根據配置的 Label 動態建立一個運行在 Docker Container 中的 Jenkins Slave 並註冊到 Master 上,當運行完 Job 後,這個 Slave 會被註銷而且 Docker Container 也會自動刪除,恢復到最初狀態。
這種方式帶來的好處有不少:web
在保證Jenkins Master高可用的前提下,能夠按傳統方式war包方式部署,可使用docker方式部署,也能夠在Kubernetes Node中部署,這部相對簡單,再也不展開詳述。docker
管理員帳戶登陸 Jenkins Master 頁面,點擊 「系統管理」 —> 「管理插件」 —> 「可選插件」 —> 「Kubernetes plugin」 勾選安裝便可。 shell
安裝完畢後,點擊 「系統管理」 —> 「系統設置」 —> 「新增一個雲」 —> 選擇 「Kubernetes」,而後填寫 Kubernetes 和 Jenkins 配置信息。 apache
接下來,咱們能夠配置 Job 測試一下是否會根據配置的 Label 動態建立一個運行在 Docker Container 中的 Jenkins Slave 並註冊到 Master 上,而且在運行完 Job 後,Slave 會被註銷而且自動刪除 Docker Container。
建立一個 Pipeline 類型 Job 並命名爲"pipeline_kubernetes_demo1,而後在 Pipeline 腳本處填寫一個簡單的測試腳本以下:npm
pipeline {
agent {
kubernetes {
//cloud 'kubernetes'
label 'k8s-jenkins-jnlp'
containerTemplate {
name 'jnlp'
image 'harbor.guahao-inc.com/base/jenkins/jnlp-slave:latest'
}
}
}
stages {
stage('Run shell') {
steps {
script {
git 'https://github.com/nbbull/demoProject.git'
sh 'sleep 5'
}
}
}
}
}
執行構建,此時去構建隊列裏面,能夠看到有一個構建任務,第一次構建的時候會稍慢,由於k8s的node須要去下載jnlp-slave的鏡像。
稍等一會就會看到k8s-jenkins-jnlp-8gqtp-j9948的容器正在建立,而後開始運行,Job 執行完畢後,jenkins-slave 會自動註銷並刪除容器,咱們經過 kubectl 命令行,能夠看到整個自動建立和刪除過程,整個過程自動完成。json
[root@kubernetes-master1 ~]# kubectl get pods|grep jenkins
k8s-jenkins-jnlp-8gqtp-j9948 0/1 ContainerCreating 0 4s
[root@kubernetes-master1 ~]# kubectl get pods|grep jenkins
k8s-jenkins-jnlp-8gqtp-j9948 1/1 Running 0 18s
具體的構建日誌參考以下:
經過 kubernetest plugin 默認提供的鏡像 jenkinsci/jnlp-slave 能夠完成一些基本的操做,它是基於 openjdk:8-jdk 鏡像來擴展的,可是對於咱們來講這個鏡像功能過於簡單,好比咱們想執行 Maven 編譯或者其餘命令時,就有問題了,那麼能夠經過製做本身的鏡像來預安裝一些軟件,既能實現 jenkins-slave 功能,又能夠完成本身個性化需求,dockfile以下:
FROM harbor.guahao-inc.com/base/jenkins/jnlp-slave:latest
USER root
//下載安裝必要組件
RUN apt-get update && apt-get install -y sudo && rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y vim && apt-get install -y sshpass
//下載和配置maven
COPY apache-maven-3.2.6-GH /usr/greenline/install/apache-maven-3.2.6-GH
RUN ln -s /usr/greenline/install/apache-maven-3.2.6-GH /usr/greenline/maven3
//下載和配置jdk
COPY jdk1.8.0_91 /usr/greenline/install/jdk1.8.0_91
RUN ln -s /usr/greenline/install/jdk1.8.0_91 /usr/greenline/jdk_1.8
ENV JAVA_HOME=/usr/greenline/jdk_1.8
ENV CLASSPATH=.:/usr/greenline/jdk_1.8/lib/dt.jar:/usr/greenline/jdk_1.8/lib/tools.jar:/usr/greenline/jdk_1.8/lib/rt.jar
ENV PATH=/usr/greenline/jdk_1.8/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr