本文將對OpenShift中共享jenkins的方式進行說明。共享jenkins主要針對默認的行爲而言的,OpenShift默認狀況下,在每一個project中第一次建立pipeline都會自動運行一個jenkins實例,那麼有沒有一種方法實現多個project共用一個jenkins或者整個OCP平臺使用一個jenkins呢?答案是確定的。
爲了便於描述,咱們將OCP中多個project共用的jenkins稱爲共享jenkins。OpenShift中實現共享jenkins有兩種方法:
方法一:在一個全局項目中部署jenkins,全部的pipeline建立在該項目中
方法二:在一個項目中建立jenkins,採集分佈在不一樣project中的pipeline
在開始說明上述兩種方法以前,先說明一點jenkins相關的配置。由於共享jenkins意味着jenkins中jobs會不少,須要配置更多的資源(CPU/MEM)來支撐job運行,不然jenkins常常會OOM錯誤退出。默認內存限制爲512M,建議將JVM_ARCH設置爲x86_64,內存限制設置爲4G或者8G,增長MetaspaceSize(默認100m)的大小。
經過在jenkins的dc中增長環境變量OPENSHIFT_JENKINS_JVM_ARCH=x86_64來修改JVM_ARCH,增長環境變量JAVA_GC_OPTS=「-XX:+UseParallelGC -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -XX:MaxMetaspaceSize=1024m」設置MetaspaceSize大小。
更多OpenShift jenkins的參數設置,請參考官方說明。
本文全部測試在OCP 3.6驗證經過,建議先閱讀《鮮爲人知的OpenShift Jenkins權限細節》理解OCP jenkins的權限再閱讀本博客。node
在實現共享jenkins以前,先要禁用掉OCP的默認行爲——也就是每一個project在第一次建立jenkins的時候會自動建立一個jenkins實例。
默認行爲解析:OpenShift在每一個項目中,第一次建立pipeline時,會檢測當前項目中是否存在名爲jenkins的service,若是不存在,則會在openshift project中查找名爲jenkins-ephemeral的template,並在當前project下實例化一個jenkins server,關於jenkins-ephemeral中的內容可查看模版的定義。
默認使用openshift項目下的jenkins-ephemeral模版進行實例化jenkins,這樣管理員就能夠經過修改jenkins-ephemeral模版來實如今jenkins實例化中建立一些其餘的資源對象。固然這種默認行爲是能夠定義的,經過在master配置文件(/etc/origin/master/master-config.yaml)中設置以下參數:git
1 |
jenkinsPipelineConfig: |
參數說明:
1)autoProvisionEnabled:默認爲true,若是設置爲false,則表示不開啓默認行爲,第一次建立pipeline時,不會實例化jenkins。
2)templateNamespace:實例化jenkins使用的模版所在的namespace,默認爲openshift。
3)templateName:實例化jenkins所使用的模版名稱,默認爲jenkins-ephemeral。
4)serviceName:第一次建立pipeline後檢測jenkins service的名稱,在實例化jenkins的模版中定義的service名稱必須與該參數一致。
5)parameters:能夠定義傳入實例化jenkins模版的參數,須要在模版中預先定義好。
使用上述參數管理員徹底能夠自定義默認行爲或者禁用自動實例化jenkins的行爲。github
實現共享jenkins的前提是經過設置autoProvisionEnabled=false禁用每一個project自動啓動jenkins實例的行爲,其餘參數保持默認便可。注意修改master配置文件以後必須重啓master服務使得配置更改生效。web
使用一個項目建立jenkins實例,將該項目作爲一個全局項目,在該項目下建立全部的pipeline。下面描述操做過程:api
1. 禁用默認行爲
1)修改master配置文件,設置autoProvisionEnabled=false安全
1 |
# vi /etc/origin/master/master-config.yaml |
2)重啓master服務app
1 |
# systemctl restart atomic-openshift-master |
注:高可用狀況下,在全部master節點修改配置文件,重啓atomic-openshift-master-api服務。maven
2. 建立一個項目,並實例化jenkins
1)建立名爲share-jenkins的項目ide
1 |
# oc login -u system:admin |
2)實例化jenkins server
可經過web界面和命令行實現,這裏咱們使用命令行測試
1 |
# oc project share-jenkins |
具體實例化jenkins的參數可根據須要設置,或部署以後再次修改dc文件都可,但必須保證建立的service名稱爲jenkins。
3. 設置項目爲全局項目
1)設置用戶可見性爲全局
此操做目的是讓全部須要使用jenkins的用戶均可以訪問該項目,一般是將特定的用戶或組指定爲項目的view或edit。這裏咱們直接將全部認證用戶賦予view權限,權限控制後續在jenins中實現。
1 |
# oc policy add-role-to-group view system:authenticated |
2)設置jenkins可操做其餘項目
這種方式須要賦予serviceaccount jenkins對其餘全部項目有操做權限,由於該項目中的pipeline要對其餘項目執行操做。
若是項目數量相對固定,那麼能夠單獨對這幾個項目設置權限
1 |
# oc policy add-role-to-user edit system:serviceaccount:share-jenkins:jenkins -n [other_project] |
若是項目數量不固定,則能夠設置爲將serviceaccount jenkins賦予cluster-admin的role
1 |
# oadm policy add-cluster-role-to-user cluster-admin -z jenkins |
4. 建立測試pipeline
爲了後續測試pipeline,咱們建立兩個pipeline,並實現簡單操做其餘項目。
1)建立測試項目demo-dev和demo-uat
1 |
# oc project demo-dev |
若是使用對單獨項目賦權,則執行以下操做:
1 |
# oc policy add-role-to-user edit system:serviceaccount:share-jenkins:jenkins -n demo-dev |
2)建立演示pipeline
建立兩個pipeline,用於演示,分別操做demo-dev和demo-uat中的資源 ,實際應用中pipeline根據具體的場景編寫。
在share-jenkens項目中建立名爲dev-mariadb的演示pipeline,內容以下:
1 |
node('maven') { |
一樣在share-jenkens項目中建立名爲uat-mariadb的演示pipeline,內容與dev-mariadb一致,只須要把project_name設置爲demo-uat便可。建立以後就能夠在jenkins中看到兩個job,以下圖所示:
測試運行兩個job,能夠看看到均正確運行,且分別在demo-dev和demo-uat項目中建立了mariadb的容器。
5. 設置jenkins中job權限
能夠看到這種方式已經實現了共享jenkins,可是默認jenkins中的job,普通用戶是沒辦法呢運行和編輯的,由於普通用戶在該項目中被賦予的是view權限。須要解決jenkins中job的權限問題,可參考上一篇博客《鮮爲人知的OpenShift Jenkins權限細節》瞭解原理,這裏咱們直接說明操做過程。
1)在OCP中增長測試用戶
建立兩個用於測試的用戶user-dev和user-uat
1 |
# htpasswd /etc/origin/master/htpasswd user-dev |
賦予user-dev對project demo-dev爲edit role,賦予user-uat對project demo-uat爲edit role;這樣使用user-dev登陸OCP後能夠看到項目demo-dev和share-jenkins,使用user-uat登陸OCP後能夠看到項目demo-uat和share-jenkins,可是對share-jenkins項目只有view權限。
2)修改jenkins權限爲「項目矩陣受權策略」
使用管理員登陸jenkins,進入「系統管理——Configure Global Security」,將受權策略設置爲「項目矩陣受權策略」,並開啓匿名用戶的overall/read權限
3)分別賦予user-dev和user-uat對應的job權限
分別進入jenkins job中,設置user-dev對job dev-mariadb有讀寫權限,設置user-uat對job uat-mariadb有讀寫權限。
6. 分別登陸用戶測試
使用user-dev登陸jenkins,能夠看到jenkins中全部的job,可是僅對job dev-mariadb有構建和修改的權限,其他均爲只讀權限。用戶user-uat也是相似的。
到此爲止,已經完成了共享jenkins的配置,這種方法的優缺點以下:
優勢:
1)實現了jenkins job層面的權限控制 2)實現和配置過程相對簡單 3)權限統一由jenkins控制,簡化了賦權操做
缺點:
1)全部pipeline須要由管理員統一建立,增長管理員負擔 2)全部pipeline在一個項目中,未作到pipeline的隔離
使用一個項目建立jenkins實例,使用jenkins plugins——[OpenShift sync](https://github.com/jenkinsci/openshift-sync-plugin)來同步不一樣project中的pipeline。
下面描述操做過程(最好將方法一中環境刪除避免衝突):
1. 禁用默認行爲
1)修改master配置文件,設置autoProvisionEnabled=false
1 |
# vi /etc/origin/master/master-config.yaml |
2)重啓master服務
1 |
# systemctl restart atomic-openshift-master |
注:高可用狀況下,在全部master節點修改配置文件,重啓atomic-openshift-master-api服務。
2. 建立一個項目,並實例化jenkins
1)建立名爲share-jenkins的項目
1 |
# oc login -u system:admin |
2)實例化jenkins server
可經過web界面和命令行實現,這裏咱們使用命令行
1 |
# oc project share-jenkins |
具體實例化jenkins的參數可根據須要設置,或部署以後再次修改dc文件都可,但必須保證建立的service名稱爲jenkins。
3. 設置項目爲全局項目
1)設置用戶可見性爲全局
此操做目的是讓全部須要使用jenkins的用戶均可以訪問該項目,一般是將特定的用戶或組指定爲項目的view或edit。這裏咱們直接將全部認證用戶賦予view權限,權限控制後續在jenins中實現。
1 |
# oc policy add-role-to-group view system:authenticated |
2)設置jenkins可操做其餘項目
這種方式須要賦予serviceaccount jenkins對其餘全部項目有操做權限,由於該項目中的pipeline要對其餘項目執行操做。
若是項目數量相對固定,那麼能夠單獨對這幾個項目設置權限
1 |
# oc policy add-role-to-user edit system:serviceaccount:share-jenkins:jenkins -n [other_project] |
若是項目數量不固定,則能夠設置爲將serviceaccount jenkins賦予cluster-admin的role
1 |
# oadm policy add-cluster-role-to-user cluster-admin -z jenkins |
4. 建立測試項目
1)建立測試項目demo-dev和demo-uat
1 |
# oc project demo-dev |
2)分別設置user-dev和user-uat有項目edit權限
1 |
# oc policy add-role-to-user edit user-dev -n demo-dev |
3)賦予jenkins sa可操做權限
若是使用單獨項目賦權,則執行以下命令:
1 |
# oc policy add-role-to-user edit system:serviceaccount:share-jenkins:jenkins -n demo-dev |
5. 配置共享jenkins
1)建立jenkins service
根據OCP查找jenkins server的原理可知,在項目中建立pipeline時,會查找名爲jenkins的service,因此咱們手動建立service,並使用cname將訪問service請求轉發到share-jenkins項目中的jenkins server。
使用以下service定義文件建立jenkins service。
1 |
cat > jenkins-svc.yaml << EOF |
分別在demo-dev和demo-uat中建立jenkins service
1 |
# oc create -f jenkins-svc.yaml -n demo-dev |
2)建立route
1 |
cat > jenkins-route.yaml << EOF |
分別在demo-dev和demo-uat中建立jenkins route
1 |
# oc create -f jenkins-route.yaml -n demo-dev |
注意:必須建立route對象,並將hostname指定爲share-jenkins中對應的jenkins域名,不然沒法經過點擊view log跳轉到jenkins server中。由於此處hostname已被share-jenkins項目的jenkins server使用,因此web console中會出現以下警告提示,忽略便可。
3)配置jenkins pipeline同步插件
默認OpenShift Jenkins Sync的插件僅會同步當前project的pipeline,咱們手動在插件中添加須要同步的project。
使用管理員登陸jenkins,切換到「系統管理——系統設置」,配置OpenShift Jenkins Sync插件,添加建立的演示項目demo-dev和demo-uat,以下圖:
如圖所示,多個項目使用空格分隔。
6. 建立演示pipeline
1)在demo-dev下建立pipeline
使用user-dev登陸OCP,在demo-dev項目下建立名爲test-mariadb的演示pipeline,內容以下:
1 |
def project_name = 'demo-dev' |
2)在demo-uat下建立pipeline
一樣使用user-uat登陸OCP,在demo-uat項目下建立名爲test-mariadb的演示pipeline,內容與demo-dev中的基本一致,僅須要修改project_name=’demo-uat’。
7. 測試共享jenkins
建立完成以後,使用user-dev登陸jenkins,能夠看到全部pipeline已經同步到jenkins job中了,以下圖所示:
從圖中能夠看出對user-dev對全部job爲只讀權限,沒法構建job。
注意:OpenShift Jnekins Sync插件配置多個項目後,會有必定的延遲(同步週期爲5分鐘),請心裏等待數分鐘。
以user-dev登陸OCP,在項目demo-dev中,切換到pipeline界面,點擊「start pipeline」按鈕,pipeline開始構建,而且狀態同步到jenkins中。
點擊pipeline中的「view log」按鈕,能夠正常的跳轉到share-jenkins項目中的jenkins server查看構建日誌。
一樣的可使用user-uat登陸測試。能夠發現,user-uat登陸以後,一樣在jenkins中對job只有只讀權限。用戶只能夠在OCP中啓動pipeline,修改pipeline以及查看構建日誌等。實際上,用戶也徹底沒有對jenkins job有任何操作權限的必要。
另外在這種實現方法中,想要使用共享jenkins,每次新建一個project就須要在project中建立jenkins的service和route對象,若是project數目對固定,則手動建立便可,若是project名稱不固定,則可使用project-template實現自動建立。
到此爲止,已經完成了共享jenkins的配置,這種方法的優缺點以下:
優勢:
1)實現了pipeline的隔離 2)不一樣項目的pipeline由用戶本身建立維護,無需管理員參與 3)jenkins中全部job爲只讀權限,安全性更高
缺點:
1)實現和配置過程相對複雜 2)在同步多個項目的pipeline時,效率偏低,第一次同步延遲在分鐘級別
1)方法一中pipeline構建權限由jenkins控制,方法二中pipeline構建權限由OCP控制
2)方法一沒法作到pipeline隔離,全部pipeline均在同一個項目中;儘管在jenkins中能夠實現隔離 ,可是用戶依然能夠在OCP的項目中查看全部pipeline,但沒法執行任何操做。方法二完美的實現了pipeline的隔離。
3)方法一全部的pipeline首次必須由管理員建立模版,後續能夠由用戶自行在jenkins中修改,而方法二pipeline徹底交由用戶管理,交給用戶本身管理就有可能出現亂用。
4)方法一相對於方法二更健壯,在同步pipeline上出錯的可能性更小,主要因爲OpenShift Jenkins Sync插件的不穩定性致使。
由兩種方法對比能夠看出,均可以實現共享jenkins的目的,主要的區別在權限以及pipeline隔離性上。用戶能夠根據實際場景選擇合適的方式。
下面咱們嘗試可否將方法一與方法二結合,理論上是可行的。咱們在方法二的基礎上,引入方法一中的job權限隔離,彷佛是一種完美的方案。大體過程以下:
1)首先完成方法二的全部配置
2)切換jenkins認證策略爲「項目矩陣受權策略」,開啓匿名用戶的overall/read權限,以下圖:
3)開啓指定job的項目權限,並賦予特定的人
4)登陸測試job可見性及操做權限
用戶user-dev僅對job demo-dev/test-mariadb可見,並且有操做權限。
雖然能夠將兩種方法的優點都結合起來,可是引入了更多複雜性,若是單獨使用方法一或方法二就能知足需求,則直接單獨使用方法一或方法二便可。
本文經過不一樣的方法實現OCP中共享jenkins,分析了優缺點,並嘗試將兩者的優點結合在一塊兒。用戶能夠根據具體的場景需求選擇合適的方案。
第二種方法中不一樣project中的pipeline經過service設定的cname鏈接jenkins server,在初始中,可能會出現啓動pipeline/job緩慢的問題,此時pipeline的狀態new,以下圖:
這種狀況不用擔憂,該現象只是出如今剛開始的階段,也可能不會出現。