Jenkins在K8s下的三種部署流程和實戰演示

【人物簡介】

丁崎詩,前遊族網絡MOB雲平臺運維負責人、前趣醫網運維總監,中科大自動化系軟件工程專業碩士,8年互聯網運維工做經驗,4年運維管理經驗,帶過20人的團隊,也負責過近萬臺設備,擅長雲原生技術、容器雲建設、監控體系、持續集成等領域。nginx

【內容提要】

Jenkins在K8s下的有幾種部署模式?
如何使用原生控制器和資源?
包管理器是什麼?怎麼使用?
自定義控制器如何部署?web

【講座整理】

通常來講,Jenkins在K8s上部署,不管是有狀態運維也好,或者無狀態運維也好,無非經過如下三個手段進行:第一,原生控制器和資源,即利用已有的K8s基礎架構和技術控制器,如deployment、service、基礎資源來作部署;第二,包管理器Helm2來作部署;第三,自定義控制器,這部分主要是指Operator。下面就這三種模式分別展開論述。編程

1、原生控制器和資源

1. 傳統架構不管是雲上仍是雲下,最外層有一個負載均衡器SLB,下面是LVS,到後面就直接到nginx這一層,以後到app和應用,到最後的DB。整體來講,傳統架構的服務自愈性是比較欠缺的。爲何要用K8s?正是由於能夠解決這一問題:它可讓咱們把單體應用本身拉起來,讓用戶指望的狀態和運行狀態保持一致。安全

正以下面右圖所示,外面一層是不變的,讓SLB/LVS流量進來,下面開始就發生了變化,到了nginx的一個模塊後,這個模塊會把流量分發到nginx pod上面去,經過nginx pod controller讓用戶指望的狀態和運行狀態保持一致,這樣一來,即便在nginx pod少一個的狀況下,在nginx pod controller的做用下也能保持始終有兩個nginx pod的運行。App service也是相似的,先到app service的一個模塊,再把流量分發到app pod上面去,具體到app pod的運行數量和運行狀態也都由K8s 的組件app pod controller來負責,再到最後的DB。
Jenkins在K8s下的三種部署流程和實戰演示
2. K8s下面有不少基礎資源,不管是跑Jenkins仍是Grafana或者其餘,如何選用這些基礎資源是部署時首先要考慮的問題。
2.1 service。service有五種,比較常見的有Headless、NodePort、ClusterIP。以NodePort型service爲例,它提供了一種外部流量訪問K8s集羣中service入口的方式。當外部用戶要訪問K8s集羣中的一個web應用時,那麼咱們能夠配置對應service類型爲NodePort。
2.2 Volume。對於K8s來講,有兩大類的存儲:經過PVC+PV來定義靜態的存儲,經過PVC+SC(存儲類)+PV來定義動態的存儲。初學者容易混淆的是,PVC是用戶指望定義的一個東西,PV纔是它的存儲時限。
2.3 RBAC。即基於角色的訪問控制,首先會定義一個服務帳號ServiceAccount。這個服務帳號是給應用用的,好比Jenkins確定也要用到一個ServiceAccount。規則是Role、ClusterRole。咱們能夠把ServiceAccount經過RoleBinding綁定到Role上,則該用戶擁有role定義的權限;經過Clusterrolebinding綁定到Clusterrole,則該用戶擁有Clusterrole定義的權限。對於namespace內的受權使用RoleBinding,集羣範圍內使用ClusterRoleBinding。
2.4 ConfigMap&Secret。這兩個都是用來保存K8s上面應用的配置。它們兩個惟一的區別就是ConfigMap是保存非敏感的信息,Secret能夠保存敏感信息。這兩個組件的申請、使用、加載其實都是大同小異的。
2.5其餘須要注意的點。其一,調度指望和調度機制。機器不少時要管理好運維類pod和業務pod的分離。同時要努力實現真正的業務高可用;其二,網絡策略。當有不少pod在運行時,網絡策略是必須考慮的;其三,安全。在K8s上面把一個pod跑起來其實很簡單,難的是如何跑好,安全也是須要考慮的一大因素。
3. 如何用原生控制器和資源區部署一個Jenkins應用。
3.1劃分所需的名稱空間。這一條不是非必選的,咱們對於一個應用會劃分一個專門的namespace,能夠按環境來分,也能夠按業務組來分。
3.2基礎控制器選型。基礎控制器有哪些?Deployment控制器、SatefulSet控制器、DaemonSet控制器、job控制器、cronjob控制器。對於Jenkins來講,無疑選擇Deployment來作基礎控制器。
3.3基礎資源選型。應用跑起來以後,怎麼讓K8s集羣外的人能訪問到咱們的應用?簡單來講,能夠直接用NodePort來作,在存儲上選的是PVC+PV,PV是使用NFS來實現。
3.4服務暴露(可選)。由於解決Jenkins是南北流量的問題,而不是集羣內訪問東西流量的問題,因此服務暴露是咱們須要考慮的。對於Jenkins來講能夠用NodePort直接來作,也能夠後面去接Ingress nginx作服務暴露,也能夠掛到SLB後面作服務暴露。
3.5網絡策略、安全、調度機制。要讓一個Jenkins應用跑起來、能用以外還能跑的好,就須要考慮全面周到一點。網絡

  • 4. 小結。關於現狀和挑戰。
    4.1無狀態業務、微服務,沒有別的選擇,確定是選原生控制器,可能只是會在服務暴露時有一個基礎選型,這是傳統架構轉型至K8S的必經之路。
    4.2挑戰在於:依樣畫葫蘆看似簡單,觸類旁通卻舉步維艱;用原生控制器須要充分了解k8s原生組件和資源細分的應用場景和區別;對所涉及配置文件的生命週期,缺乏完善的管理手段;只解決了部署剛需,卻沒有完善複雜應用的部署邏輯和本土化用戶的使用習慣。

2、包管理器:Helm

前述提到,原生控制器缺什麼?配置文件的生命週期管理是原生控制器所欠缺的。哪些文件該是我考慮的,這個文件變動了怎麼辦?怎麼作版本管理?這就是Helm要解決的問題。
1. Helm2的拓撲架構。以下圖所示,charts是基礎配置模板,config是charts配置參數,helm是命令行客戶端,經過grpc協議,向tiller發送請求,用來作版本發佈、回滾、打包、升級。tiller存儲在CM裏面的,而後在Helm3裏已經移除了,由於它有一些侷限性。要注意的是,Helm和Docker是同樣的,有一個倉庫的概念。對於一個成熟的軟件來講,第三方的支持是不多的,不可能讓全部的helm都本身寫,因此對於helm來講,它有本身成熟的遠程倉庫,我是寫在集羣外的。事實上還有一個集羣內的,版本管理以後會有一個local倉庫,能夠把本身的發版應用打包,而後發佈到local倉庫,作內部的版本管理。
Jenkins在K8s下的三種部署流程和實戰演示架構

2. 部署流程。
2.1工具的部署安裝。對於基礎選型來講並無不少選擇,無非是選Helm2或Helm3。
2.2 charts製做。Helm有兩種類型的repo,一個是已有chart使用,直接在repo中搜索和安裝,不用本身造輪子;第二個是自定義chart製做。 以Jenkins爲例,能夠經過Helm create Jenkins幫咱們生成一個樹狀結構的整個東西(以下圖)。再看外面兩個文件,這裏templates是K8S內置的,就是它本身的基礎控制器的文件。templates以外的這兩個charts、values是Helm本身定義的東西。
Jenkins在K8s下的三種部署流程和實戰演示app

咱們把前面參數定義好以後,能夠經過Helm install -n 「namespace」 Jenkins,把Jenkins目錄下的項目裝起來。第一步,初始deployment;第二步,相關pod在建立;下一步,service,pod去跑,全部運行完成以後,跟你說「你是經過這些命令去拿到你對應的URL」。最後能夠經過helm list看到剛纔發佈的應用,Jenkins版本發了1版,發佈的時間點、狀態是已部署,chart是Jenkins-0.1.0,namespace是default。
Jenkins在K8s下的三種部署流程和實戰演示
2.3 release迭代。對於自定義好的create以後的charts怎麼玩?不可能發了一版後就徹底不動了,更新(upgrade)怎麼作?若是不符合預期,多是產品預期、業務預期、技術預期,須要回滾(rollback),又要怎麼作?
2.3.1更新。看下圖中的chart.yaml文件,先要去變動helm的描述清單,appVersion變動,version也要變動。除了以前變動以外,把鏡像倉庫版本也進行變動。
Jenkins在K8s下的三種部署流程和實戰演示
2.3.2回滾。回滾是用命令helm rollback,後面跟位置參數。Jenkins須要回滾哪一個應用?第一個位置參數是業務名,第二個字段是有一個default值,是默認後幫你回滾到1版本,寫一個1。回滾以後,前面進行第一次初始化發版,第二次更新,第三次回滾,爲何這個版本仍是3呢?這裏是讓咱們每次發版都有記錄可查,因此記錄是遞增的。
Jenkins在K8s下的三種部署流程和實戰演示
2.4打包和發佈。當這兩個狀態結束以後,要進行打包和發佈,打包到哪裏?打包到咱們定義好的local repo裏來。第一步就是用Helm package打包項目,而後建立項目存放路徑,把打包好的項目丟過來,再經過helm.serve的命令指定好本地倉庫的地址是哪裏,最後就能夠在本地倉庫裏找到剛纔的項目了。
3. 小結。關於現狀和挑戰
3.1 Helm完善l k8s資源生命週期的管理,如:升級、回滾、下線、發佈等;解決了單體應用建立時的配置依賴問題;提供了更上層的編排能力,交付的標準顆粒度是應用,而不是k8s基礎對象或組件;Helm的生態圈和官方提供的衆多包含有最佳實踐的chart包。
3.2 挑戰在於:須要充分了解k8s原生組件和資源細分的應用場景和區別;Helm工具自己架構設計和用戶體驗的不足:如Tiller權限控制、數據存儲(CM)、發佈體驗等。負載均衡

3、自定義控制器

1.自定義控制器(Operator)的誕生。2016年秋天,CoreOS在福斯特城(Foster City)公寓結對編程。當時兩我的作了一個小項目,也就是Operator。由於他們發現K8S原生的東西並不能知足用戶指望。好比在傳統架構之上,MySQL集羣,不管是主從也好,Mango集羣,分片、副本級也好,怎麼作數據備份,怎麼作數據遷移,怎麼作回滾,怎麼作備份,用K8S原生的基礎組件、基礎資源其實根本作不了。Operator所作的就是教咱們定義平常運維的經驗、操做代碼化。less

2.自定義控制器(Operator)作了什麼?總體能夠分爲四點。其一,用戶指望。K8S的維護者確定但願用戶能更簡單、更方便地去用,幫助他本身的產品去上集羣;其二,研發實現。除了幫助用戶支撐所須要的第三方組件快速上K8S集羣以外,完善和本土化這些複雜應用集羣的運維功能也相當重要;其三,K8s賦能,容許用戶添加 API 對象的插件能力。若是K8S沒有一個暴露的API或暴露接口讓研發人員去作事也是紙上談兵;其四,社區推廣。使用方能夠在Operatorhub.io和awesome-Operators快速分享或找到Operator。
3.如何經過Operator部署一個Jenkins應用。簡言之,先定義CRD,再定義Controller,最後定義他的用戶狀態,幫用戶去識別化他的應用集羣。
3.1定義CRD。CRD是K8s給用戶可以本身寫Controller的一個API,擴展K8s API的地方。
Jenkins在K8s下的三種部署流程和實戰演示
3.2定義Controller。對Jenkins來講,Jenkins Operator0.3.3是Jenkins官方已經寫好的一個Operator,咱們只要拿下來去用。
Jenkins在K8s下的三種部署流程和實戰演示
3.3定義用戶指望的狀態。
Jenkins在K8s下的三種部署流程和實戰演示
4. Jenkins operator幫咱們簡化了什麼?
4.1自動化發現和配置。以seed job爲例。和傳統玩法相比,運維人員須要作的只是把這些job寫成Jenkinsfile,保存在Git裏面去,這樣就能夠作一鍵遷移了。這讓咱們有更多的視角去看到底哪些好、哪些很差。
4.2配置代碼。這裏所有基於配置代碼的方式去作,而不是傳統的基於磁盤的備份,這麼作的好處顯而易見。
4.3備份和還原。backup and restore內置字段,清楚地告訴你這一塊是作backup的,這一塊是作restore的。這樣作至關於把用戶習慣直接分裝掉了,所見即所得。
5 小結。關於現狀和挑戰。
5.1完善複雜應用的部署邏輯;本土化用戶的使用習慣;自由度高,用戶能夠可定製化開發controllers。
5.2挑戰在於:須要充分了解k8s原生組件和資源細分的應用場景和區別;須要充分了解CRD和K8s API;須要必定的研發能力。運維

【總結】

Jenkins其實部署在K8S上三種模式,不必定說只教會你們用Jenkins,其實別的東西也同樣。但這三種模式都離不開一點:都須要去了解K8s下面全部的基礎控制器、基礎資源怎麼去使用、怎麼去定義。當你把全部基礎控制器和資源都摸透以後,用Helm三、Helm2也好,網上去查Operator也好,都是能夠的。只有底子打好,知道哪一個東西是幹什麼的時候,才能知道它們的應用場景。

相關文章
相關標籤/搜索