CICD 流水線是指一系列自動化的構建、測試和部署步驟,用于將應用程序從開發(fā)到生產環(huán)境的過程。在 CICD 流水線中,每個步驟都是自動化的,并且在完成后會觸發(fā)下一個步驟的執(zhí)行。
CICD 的價值
CICD 流水線可以幫助團隊更快地交付產品,減少手動錯誤,并提高軟件質量。通過自動化構建、測試和部署過程,團隊可以更快地檢測和修復錯誤,并更快地將新功能推向市場。
CICD 工具鏈
通常由8個部分組成
- 源代碼管理:用于存儲和管理應用程序代碼的工具,代碼管理是 CICD 工具鏈的基礎,提供了代碼的版本控制、協(xié)作和管理功能,例如 GitLab、GitHub、Bitbucket 等。
- 構建工具:將源代碼編譯成可執(zhí)行文件或軟件包的工具,例如 Maven、Gradle、Webpack 等。
- 測試工具:自動化執(zhí)行測試用例并生成測試報告的工具,例如 JUnit、Selenium 等。
- 鏡像構建:構建和管理容器鏡像的工具,例如 Docker、Kaniko 等。
- 制品管理:存放業(yè)務鏡像的倉庫,在應用部署時需要拉取。例如:Harbor、Registry、云廠商私有倉庫等。
- 監(jiān)控工具:用于監(jiān)控流水線運行過程中的狀態(tài),如資源占用、負載情況,為流水線性能優(yōu)化提供數(shù)據(jù)基礎。例如:Prometheus、Grafana、EFK 。
- 部署工具:用于將代碼構建完成的制品發(fā)布到目標環(huán)境中,例如 Jenkins、GitLab CI、Travis CI 等。
- 自動化工具:用于代替分散腳本執(zhí)行各種自動化類操作,使執(zhí)行流程更加清晰有序。例如:Ansible、Puppet 等。
CICD 的演進歷史
從CI/CD發(fā)展歷史來說可以大致分為以下幾個階段:
1、人工發(fā)布階段:開發(fā)或運維人員通常需要手動構建和部署應用程序。這種方法非常耗時且容易出錯,因為它需要手動執(zhí)行多個步驟,并且容易遺漏某些步驟。
2、腳本發(fā)布階段:我們稱之為“半自動化”階段,人工手動操作的步驟嚴重困擾了開發(fā)和運維人員,過于耗時耗力以及手動執(zhí)行具有一定的不可靠性存在。于是開始尋求用腳本來替代一部分人工操作,如 shell、python 腳本,但長此以往依然消耗開發(fā)運維人員大量時間成本,發(fā)布不夠規(guī)范依然在持續(xù)
3、自動化發(fā)布階段:?為了進一步規(guī)范發(fā)布流程,規(guī)避人為操作所帶來的風險,提高發(fā)布效率,多數(shù)公司開始構建自己的 CI/CD 發(fā)布系統(tǒng),這樣的好處是無需人工介入,腳本內容不易被篡改。
4、智能化發(fā)布階段:人工智能大數(shù)據(jù)時代,一些優(yōu)秀的公司已經開啟智能化 CI/CD 系統(tǒng),通過引入數(shù)據(jù)分析、智能預測手段,進一步優(yōu)化發(fā)布流程、提高發(fā)布效率。
在這四個階段中,每個階段都是在前一個階段的基礎上發(fā)展而來的,并且每個階段都可以提供更高效、更可靠和更安全的軟件交付過程。
進入自動化時代以后,CI/CD 效率雖得到了大幅提升,但架構的維護過程中依然會遇到各種各樣的問題需要解決,下面我將介紹大多數(shù)企業(yè)在整個維護過程中可能會遇到的流水線問題以及優(yōu)化方案。
企業(yè)CICD流水線可能會遇到的問題
Jenkins 當屬業(yè)內持續(xù)集成老大哥,有著豐富的插件,適用于大型流水線方案的建設以及大多數(shù)場景,受到不少企業(yè)用戶的追捧,所以本文主要基于 Jenkins 建設的流水線方案為核心從運維角度來講述可能存在的瓶頸及優(yōu)化點。
1、Jenkins Master 與 Worker 共用宿主機帶來的失聯(lián)問題
有些企業(yè)為了方便部署以及盡可能的節(jié)省服務器資源選擇 Jenkins Master 與 Worker 共用宿主機,當流水線數(shù)量較少或 stage 耗費資源較少時無明顯感知。隨著項目越來越多,流水線數(shù)量的也隨之增多,這種架構開始出現(xiàn)瓶頸,多個 Job 并行構建占用資源較多導致系統(tǒng)負載增高,Master 與Worker 之間的通信也會受到干擾,重連超時導致 Job 最終失敗。
建議優(yōu)化方案:
- Jenkins Master 與 Worker 分離部署,可以允許Worker有短暫的高負載波動,不至于拖垮所有流水線
- Jenkins Master 優(yōu)化連接時間相關參數(shù)
- Worker 主機負載高優(yōu)化
- kubelet 配置系統(tǒng)資源預留,保障系統(tǒng)進程的穩(wěn)定性
- kubelet 限制 maxPods 來硬性控制并行構建數(shù),超出限制會進入隊列等待
- Jenkinsfile 中 PodTemplate 部分容器增加 resourceLimitCpu 參數(shù)限制最大使用CPU額度
- 這一點是防止某個Pod無限制使用資源導致卡死
2、代碼依賴緩存拉取的問題
默認走官方源拉取依賴多多少少會遇到網絡穩(wěn)定性問題,導致Job的構建成功率降低,影響產品交付效率。
推薦優(yōu)化方案:
- maven
- 推薦 nexus 私服
- npm
- 使用淘寶源
- 使用阿里云私有倉庫,可以有效解決私有包的權限問題
- 緩存目錄映射宿主機實現(xiàn)持久化,減少每次拉取的網絡消耗
3、Docker 構建業(yè)務鏡像體積大,耗時長
對于小型項目優(yōu)化的必要性不大,大型項目的弊端較明顯。
建議優(yōu)化方案:
- 養(yǎng)成良好編寫 Dockerfile 的習慣,合并多 RUN 步驟,減少 layer 層級
- 注意 ADD/COPY 的用法,禁止使用先 COPY 后解壓操作,對于大型碎文件目錄建議歸檔為 tar 包后使用 ADD 上傳(大量碎文件會影響性能)
- Dockerfile 使用多階段構建,最終鏡像打包只引用構建產物
- 使用 .dockerignore 來忽略 docker build 時不需要加載的文件或目錄,節(jié)省構建時間
- 基礎鏡像的選型很重要,根據(jù)所屬項目依賴來確定滿足需求最小基礎鏡像
4、鏡像推送拉取慢
包含運行時鏡像、打包基礎鏡像、業(yè)務鏡像等
建議優(yōu)化方案:
- 無論是公共鏡像還是私有鏡像盡量都使用私有倉庫走內網傳輸,避免使用官方倉庫。
- 常見私有倉庫:
- 阿里云云效私有倉庫
- AWS ECR
- Harbor
- Registry
- 等…
- 常見私有倉庫:
- 流水線宿主機本地長期保留常用鏡像
5、代碼打 Tag 后 Jenkins 拉取版本有誤
開發(fā)打 Tag 后觸發(fā) Jenkins 流水線,流水線訪問倉儲獲取 Tag 代碼,但偶爾會遇到流水線獲取到的Tag與預期不符,引發(fā)網站訪問報錯
建議優(yōu)化方案:
- 這可能是一個 bug,偶然出現(xiàn)
- 可以使用獨立部署 webhook 服務來主動觸發(fā) Jenkins 的方式徹底解決
6、Jenkinsfile 文件多,管理難
一般 Jenkinsfile、Dockerfile 等文件都會存在在業(yè)務倉儲內,如果企業(yè)倉儲較多,而 Jenkinsfile 又不能共用的情況下就會面臨統(tǒng)一管理的問題。
建議優(yōu)化方案:
- 簡化版
- 只需要將各倉儲相關文件轉移至統(tǒng)一倉儲,Jenkins 先拉取管理倉儲,再在 stage 中拉取業(yè)務代碼來實現(xiàn),不必合并所有Jenkins的內容
- 優(yōu)勢:
- 不依賴額外插件,屬于輕量型
- 與業(yè)務解耦
- 劣勢:
- 統(tǒng)一修改較耗時
- 復雜版(推薦,但不建議代碼邏輯過于復雜化)
- 基于 Global Pipeline Libraries 插件做代碼整合,通用部分提取到單獨文件復用
- 官方文檔:?https://www.jenkins.io/doc/book/pipeline/shared-libraries/?
- 優(yōu)勢:
- 復用部分一處修改生效全局,減少代碼量
- 節(jié)省一定的時間成本
- 劣勢:
- 復用部分的修改需要慎重,盡量使用判斷
- 需要一定的 Groovy 代碼基礎
- 基于 Global Pipeline Libraries 插件做代碼整合,通用部分提取到單獨文件復用
7、多條流水線并行構建的問題
當 Worker 節(jié)點為固定時,資源少會導致流水線排隊,整體效率低,資源多可以滿足高峰期的并行構建需求,但空閑時間又會浪費成本。
建議優(yōu)化方案:
- 使用云廠商的 Serverless 產品按需付費,只對Pod資源限制
- 使用云廠商的 Autoscheduling 功能來實現(xiàn)主機級別的擴縮容(需要依賴云廠商K8S產品)
- 編寫工具根據(jù)業(yè)務實際場景實現(xiàn)動態(tài)調整Worker節(jié)點的配置大小
8、流水線擁堵問題,與第7條不沖突
上一條提到的并行構建指的是正常的構建需求,是建立在流水線擁堵優(yōu)化之后的結論之上,如:單個 CD Job 的并行構建顯然是不合理的,卻需要多耗費幾倍的資源。
建議優(yōu)化方案:
- CD 流水線開啟「不允許并行構建」以及「Abort previous builds」,每個Job只保留最新的構建進程
- CI 流水線需要測試每個 PR 的代碼,所以可以開啟「不允許并行構建」,無需開啟「Abort previous builds」
- 當系統(tǒng)資源較充足時, CI 可以關閉 「不允許并行構建」,但需要注意的是共用緩存映射所帶來的潛在沖突問題
- 主機負載高可能導致 Job Pod 運行狀態(tài)失聯(lián),未及時被 K8S 回收,建議設置定時檢測腳本來按需清理
9、Jenkins Master磁盤占用率高、運行緩慢卡頓
大概有幾方面原因:構建日志保留過多、服務日志未定時清理、主機資源匱乏、JVM 限制參數(shù)不合理等。
建議優(yōu)化方案:
- 按構建天數(shù)或個數(shù)進行日志保留
- 服務日志設置定時清理或調整日志級別
- 根據(jù)監(jiān)控判斷資源合理需求
- JVM 參數(shù)配置調整測試,得出合理值
- 對于分支構建的 Job 關閉 Tag 拉取,以及開啟淺克隆
10、Jenkins 批量新增、修改 Job 信息麻煩
少量的流水線直接通過界面編輯即可,幾十上百條甚至更多以后修改配置會很麻煩。
建議優(yōu)化方案:
- 使用 Python、Go 等語言編寫統(tǒng)一管理工具
- 合并可能通用的流水線,如:單條流水線發(fā)布多個項目,是一對多的關系
總結:文章來源:http://www.zghlxwxcb.cn/news/detail-691003.html
以上分享的是較常見可能影響流水線交付效率的因素以及建議解決方案,PingCode?DevOps 團隊充分借鑒了以上部分方案進行專項優(yōu)化,流水線交付效率得到了質的提升。CICD 流水線優(yōu)化是一個經久不衰的話題,我相信流水線的高效穩(wěn)定和便于管理是每個企業(yè)共同追求的目標,實現(xiàn)形式可以是多種多樣,適合自身場景的方案就是好的方案,現(xiàn)階段我們依然在為進一步優(yōu)化流水線做努力,追求極致,沒有最好,只有更好!文章來源地址http://www.zghlxwxcb.cn/news/detail-691003.html
到了這里,關于PingCode DevOps 團隊:企業(yè)CICD流水線可能會遇到的問題及解法的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!