GitOps:Kubernetes多叢集環境下的高效CICD實踐
為了解決傳統應用升級緩慢、架構臃腫、不能快速迭代、故障不能快速定位、問題無法快速解決等問題,雲原生這一概念橫空出世。雲原生可以改進應用開發的效率,改變企業的組織結構,甚至會在文化層面上直接影響一個公司的決策,可以說,雲時代的雲原生應用大勢已來。在容器領域內,Kubernetes已經成為了容器編排和管理的社群標準。它通過把應用服務抽象成多種資源型別,比如Deployment、Service等,提供了一個雲原生應用通用的可移植模型。在這樣的背景下,我們如何在雲原生的環境下實踐更高效的DevOps來達到更有生產力的表現就成為了一個新的課題和訴求。
與GitOps這個概念相比,大家可能對DevOps的概念已經耳熟能詳了。起初DevOps是為了打破開發測試、運營這些部門之間的壁壘,通過自動化的構建、程式化的指令碼,最低限度減少人工誤差,一定程度上提高應用版本的迭代效率;容器技術出現以後,輕量、標準化的能力使得DevOps技術才有了突飛猛進的發展。不管技術怎樣更新迭代,DevOps最主要的核心訴求是不變的,那就是提高應用迭代的頻率和降低成本。GitOps就是DevOps的邏輯擴充套件,它的核心目標是為了更加高效和安全的應用釋出。
首先我們提取出一些使用者在做devops的過程中遇到的痛點進行分析。第一個問題是如何自動化推進應用在環境棧中的無差別釋出.這裡我列舉了三種環境,測試環境、生產環境和預發環境,對於一個應用來說,我們通常的設定都是把不同分支部署到對應環境,比如master分支的原始碼對應的是線上環境,latest分支對應的是預發環境,其他開發分支對應地部署到測試環境;目前大多數的做法是建立不同的job,拉取不同的原始碼分支、部署到不同的環境,或者同一個job,通過新增不同的構建引數來決定進行怎樣的構建和釋出動作。 非常容易產生混亂和不便於管理。
第二個問題就是,生產環境的釋出許可權一般都是需要嚴格控制的,通常只有應用管理員或者運維管理員才有生產釋出許可權。我們在跟一些客戶的交流中發現,一種方式是在同一套cicd環境中建立不同的job,然後通過基於角色訪問控制策略來做job的隔離,只有管理員許可權的人員才能看到用於釋出生產的job; 更直接的一種做法就是再建一套cicd環境專門做生產環境的釋出, 但這樣既浪費資源又降低了應用迭代的頻率。
第三個問題是說我們想要提高應用迭代的頻率進而降低人力成本、時間成本、把精力放在新業務或創新業務的拓展上,但目前我們的開發測試人員在應用執行狀態或測試結果的同步與反饋上有一定的隔閡,另外一個是線上業務出現問題的時候,如何快速定位、復現和回滾,這是一個我們可以重點思考的地方。以上三點只是我列舉出來的我們使用者在實際使用cicd的過程中的一些痛點的子集,那接下來我們就帶著這些問題來看一下gitops模型的設計思路是怎樣的
我們在設計gitosp釋出模型的時候是有以下這些核心訴求的:第一個是版本管理,我們希望每一個釋出的應用的版本號都能跟git commit id關聯,這樣的好處就是每一個變更都有歷史記錄查詢、可以更快進行故障定位和修復,第二個是基線管理,這裡我們一會兒會講到分兩種型別的基線,第三個是怎麼做安全釋出,包括髮布許可權管理以及安全審批的內容;最後一個是如何讓開發測試人員快速獲取反饋
首先gitops的核心思想就是將應用系統的宣告性基礎架構和應用程式存放在Git版本庫中,所有對應用的操作變更都來源於Git倉庫的更新,這也是gitops這個名稱的由來。另外一個問題是,按照以往通用的做法,我們可能會把應用如何構建如何部署的指令碼以及配置檔案跟應用原始碼本身存放在同一個倉庫裡,這樣帶來的問題有兩個,一是開發人員可能還需要維護這個部署指令碼或配置檔案,不能把精力集中到產品開發上,另外一個問題是部署指令碼有時候會涉及環境敏感資訊,安全性不夠,所以我們這裡一定要把應用原始碼倉庫與構建倉庫分開管理。
接下來就是基線管理,基線管理分兩種,一種是環境棧基線,如圖所示,我們的設定是,生產環境只能部署master分支的程式碼,預發環境只能部署latest分支的程式碼,預覽環境用來部署其他開發分支,這裡有個名詞叫預覽環境,其實也就是測試環境,但我們會在開發分支通過測試、通過驗證成功合併到latest分支以後動態銷燬這個測試環境,當然這在kubernetes容器叢集下是非常容器做到的,在其他具體的場景下可以用不同的策略。這個基線我們可以把它稱為小基線,它是用來明確管理應用在預覽、預發、生產環境中的推進的。大基線是針對線上釋出版本的管理的,這能保證我們在線上出現故障的時候能快速回滾到上一個穩定的版本。這在生產釋出管理中是必不可少的,在gitops中我們還能快速定位故障精確到某個git commit。
然後是應用釋出的許可權管理和安全審批,gitops中的許可權管理是通過程式碼合併的控制來做的,在這個模型中,普通的開發人員沒有cicd環境比如jenkins的訪問許可權,更精確地說的話是隻有日誌檢視的許可權,在git這一端,普通開發者只有向開發測試分支推送程式碼的許可權,並可以申請向latest分支合併程式碼,即提交MR/PR的許可權,當普通開發者新建MR/PR後,就會觸發構建把應用部署到預覽環境,管理員通過檢視這個新分支的構建部署是否通過一系列測試和驗證來決定是否接受這個MR/PR, 只有管理員接受MR/PR的合併後,latest分支程式碼才會重新構建和部署到預發環境,這樣就通過MR/PR的接受和拒絕來達到應用釋出安全審批的目的。
最後是如何進行快速反饋和團隊成員間的互動,這包括兩部分內容:一個是普通開發測試人員在推送原始碼後,能通過郵件、釘釘、slack等工具實時地獲取構建結果,對自己的應用進行高效開發測試,;另一方面是能在MR/PR的頁面上檢視自動化測試的反饋結果、應用預覽連結、其他團隊成員的comment等。
下面是使用GitOps管理應用釋出到不同kubernetes叢集的架構圖和時序圖。首先是應用原始碼與構建原始碼分離。最上面有一條虛線,虛線上面是普通開發者能看到的,或者說是有許可權進行操作的部分,剩下其他的部分都是管理員才有許可權做的,綠色區域是Jenkins的流水線任務。普通開發者沒有Jenkins環境的建立Job和構建Job的許可權,他有的只是構建Job的日誌檢視許可權。這個普通應用是在Git倉庫裡,它有不同的
分支,有一定設定的關係,每次有構建的時候會從另外一個Git倉庫裡做,比如preview-plpeline、prod-plpeline,在這裡面可以存放一些資訊,只有應用管理員才能看到,普通開發者沒有許可權看到資訊。 然後我們需要設定應用釋出環境棧,這在個示例中我們有預覽環境、預發環境、生產環境的設定,應用在預發環境和生產環境中的釋出是需要經過管理員安全審批的。
最後是一個時序圖,開發人員提交新的feature,建立指向latest分支的MR,建立MR的動作會觸發preview-plpeline的構建,構建會拉取preview-plpeline的構建倉庫,構建倉庫存放的是構建指令碼以及要部署的環
境資訊。然後就是自動化的構建流程,首先會從應用原始碼倉庫把應用原始碼拉取下來做構建,靜態程式碼測試、單元測試,測試結果會反饋到MR上,然後打包容器映象並把映象推送到映象倉庫,最後會把應用通過檔案部署到Kubernetes的叢集裡並進行功能測試,測試結果反饋到MR上,部署之後會收集應用相關資訊,通過釘釘通知傳送到開發群裡。開發人員收到釘釘通知,可以直接點選連結檢視應用狀態,如果有問題,可以返回來自己重新開發,再重新進行提交,把前面的流程再走一遍,沒問題就可以請求管理員進行審批,把程式碼合併到latest分支。latest分支和master分支有更新時,就會觸發與前面的構建類似的流程把應用推進到預發環境和生產環境。
作者:流生
原文連結
本文為雲棲社群原創內容,未經