在此以前您可能據說過「GitOps」,但並不知道它究竟是什麼,除了GitOps,您可能還據說過DevOps,或者AIOps、GOps等,是的,如今是「Ops」盛行的時代。nginx
GitOps是一種實現持續交付的模型,它的核心思想是將應用系統的聲明性基礎架構和應用程序存放在Git的版本控制庫中。Choerodon豬齒魚在構建持續交付流水線時參考了GitOps,並進行了實踐,俗話說「兵馬未動,理論先行」,在本文中,將重點闡述GitOps工做流程的原理和模式,以及將它們應用在生產和大規模運行Kubernetes中的一些實踐經驗。 在下一篇文章中,將介紹Choerodon豬齒魚是如何實踐和落地GitOps,從而構建了一個可重複且可靠的交付過程。git
GitOps,90%的最佳實踐,10%有意思的新東西須要咱們去構建。 —— 《 GitOps - Operations by Pull Request》來自: https://www.weave.works
這篇文章是根據Weave Cloud的幾篇關於GitOps的文章翻譯整理而來:github
GitOpsredis
GitOps: Operations by Pull Requestapi
The GitOps Pipeline - Part 2安全
GitOps - Part 3: Observability服務器
GitOps - Part 4: Application Delivery Compliance and Secure CICD網絡
主要內容:架構
什麼是GitOps?app
最佳實踐
GitOps是一種持續交付的方式。它的核心思想是將應用系統的聲明性基礎架構和應用程序存放在Git版本庫中。
將Git做爲交付流水線的核心,每一個開發人員均可以提交拉取請求(Pull Request)並使用Git來加速和簡化Kubernetes的應用程序部署和運維任務。經過使用像Git這樣的簡單熟悉工具,開發人員能夠更高效地將注意力集中在建立新功能而不是運維相關任務上(例如,應用系統安裝、配置、遷移等)。
GitOps: versioned CI/CD on top of declarative infrastructure. Stop scripting and start shipping. https://t.co/SgUlHgNrnY — Kelsey Hightower (@kelseyhightower) January 17, 2018
做爲一個有經驗項目管理者,或者產品負責人,你必定會思考一個問題:咱們項目組在開發過程當中應如何管理分支?不錯,分支管理將和項目組開發人員日夜伴隨,若是採用了一個不合適的分支管理模型,那麼能夠想象兄弟們得多麼的痛苦。
Okay,那麼就從分支管理模型開始......
經過GitOps,當使用Git提交基礎架構代碼更改時,自動化的交付流水線會將這些更改應用到應用程序的實際基礎架構上。可是GitOps的想法遠不止於此——它還會使用工具將整個應用程序的實際生產狀態與基礎架構源代碼進行比較,而後它會告訴集羣哪些基礎架構源代碼與實際環境不匹配。
經過應用GitOps最佳實踐,應用系統的基礎架構和應用程序代碼都有「真實來源」——實際上是將基礎架構和應用程序代碼都存放在gitlab、或者github等版本控制系統上。這使開發團隊能夠提升開發和部署速度並提升應用系統可靠性。
將GitOps理論方法應用在持續交付流水線上,有諸多優點和特色:
做爲CI / CD流水線的方案,GitOps被描述爲軟件開發過程的「聖盃」。 因爲沒有單一工具能夠完成流水線中所需的全部工做,所以能夠自由地爲流水線的不一樣部分選擇最佳工具。能夠從開源生態系統中選擇一組工具,也能夠從封閉源中選擇一組工具,或者根據使用狀況,甚至能夠將它們組合在一塊兒,其實,建立流水線最困難的部分是將全部部件粘合在一塊兒。
無論如何選擇構造本身的交付流水線,將基於Git(或者其餘版本控制工具)的GitOps最佳實踐應用在交付流水線中都是一個不二選擇,這將使構建持續交付流水線,以及後續的推廣變得更加容易,這不只從技術角度並且從文化角度來看都是如此。
固然,GitOps也不是萬能的,它也有相應的應用場景。
應用都須要運行在多臺機器上,它們被組織成不一樣的環境,例如開發環境、測試環境和生產環境等等。須要將相同的應用部署到不一樣的機器上。一般須要系統管理員確保全部的機器都處於相同的狀態。接着全部的修改、補丁、升級須要在全部的機器中進行。隨着時間的推移,很難再確保全部的機器處於相同的狀態,同時愈來愈容易出錯。這就是傳統的可變架構中常常出現的問題。這時咱們有了不可變架構,它將整個機器環境打包成一個單一的不可變單元,而不是傳統方式僅僅打包應用。這個單元包含了以前所說的整個環境棧和應用全部的修改、補丁和升級,這就解決了前面的問題。 —— 摘自InfoQ的《關於不可變架構以及爲何須要不可變架構》做者 百佔輝
「不可變基礎設施」這一律念不是剛剛冒出來的,它也不是必須須要容器技術。然而,經過容器,它變得更易於理解,更加實用,並引發了業內普遍注意。「不可變基礎設施」讓咱們以全新的方式理解和麪對應用系統,尤爲是使以微服務爲表明的分佈式系統在部署、運營等方面變得不那麼複雜,而有很好的可控性。
那麼,如何比較方便地在實際的生產過程當中應用「不可變基礎設施」,這給業界也提出了另一個問題。GitOps是在具體Kubernetes的應用實踐中出現的,GitOps須要依託於「不可變基礎架構」才能發揮其做用。在必定程度上說,「不可變基礎架構」爲GitOps的出現創造了必要的條件,反過來GitOps應用Kubernetes的容器編排能力,可以迅速的使用鏡像搭建出應用系統所需的組件。
Kubermetes做爲一個雲原生的工具,能夠把它的「聲明性」看做是「代碼」,聲明意味着配置由一組事實而不是一組指令組成,例如,「有十個redis服務器」,而不是「啓動十個redis服務器,告訴我它是否有效」。
藉助Kubermetes的聲明性特色,應用系統的整個配置文件集能夠在Git庫中進行版本控制。經過使用Git庫,應用程序更容易部署到Kubernetes中,以及進行版本回滾。更重要的是,當災難發生時,羣集的基礎架構能夠從Git庫中可靠且快速地恢復。
Kubernetes等雲原生工具的聲明性體如今能夠對實例、容器、網絡、存儲、CPU等配置經過一組代碼方便的表達出來,Kubernetes等雲原生工具能夠利用這些配置代碼運行出來一套基於容器的應用系統,例如YMAL,
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 1 template: metadata: labels: app: nginx spec: containers: - name: nginx image: registry.choerodon.com.cn/operation-choerodon-dev/nginx-demo:1.13.5-alpine ports: - containerPort: 80
GitOps充分利用了不可變基礎設施和聲明性容器編排,經過GitOps能夠輕鬆地管理多個部署。爲了最大限度地下降部署後的變動風險,不管是有意仍是偶然的「配置誤差」,GitOps構建了一個可重複且可靠的部署過程,在整個應用系統宕機或者損壞狀況下,爲快速且徹底恢復提供了所需條件。
如下是幾條在雲原生環境中,GitOps的原則:
經過使用Git做爲存儲聲明性基礎架構和應用程序代碼的存儲倉庫,能夠方便地監控集羣,以及檢查比較實際環境的狀態與代碼庫上的狀態是否一致。因此,咱們的目標是描述系統相關的全部內容:策略,代碼,配置,甚至監控事件和版本控制等,而且將這些內容所有存儲在版本庫中,在經過版本庫中的內容構建系統的基礎架構或者應用程序的時候,若是沒有成功,則能夠迅速的回滾,而且從新來過。
做爲通常規則,不提倡在命令行中直接使用kubectl命令操做執行部署基礎架構或應用程序到集羣中。還有一些開發者使用CI工具驅動應用程序的部署,但若是這樣作,可能會給生產環境帶來潛在不可預測的風險。
調用Kubernetes 的API的接口或者控制器應該遵循 Operator 模式(什麼是Operator 模式?),集羣的狀態和Git庫中的配置文件等要保持一致,而且查看分析它們之間的狀態差別。
Git是每一個開發人員工具包的一部分。學習起來感受天然並且不那麼使人生畏,並且工具自己也很是簡單。 經過使用Git做爲應用系統的事實來源,幾乎能夠操做全部東西。例如,版本控制,歷史記錄,評審和回滾都是經過Git進行的,而無需使用像kubectl這樣的工具。
因此,Git是GitOps造成的最基礎的內容,就像第一條原則「任何可以被描述的內容都必須存儲在Git庫中 」描述的那樣:經過使用Git做爲存儲聲明性基礎架構和應用程序代碼的存儲倉庫,能夠方便地監控集羣,以及檢查比較實際環境的狀態與代碼庫上的狀態是否一致。因此,咱們的目標是描述系統相關的全部內容:策略,代碼,配置,甚至監控事件和版本控制等,而且將這些內容所有存儲在版本庫中,在經過版本庫中的內容構建系統的基礎架構或者應用程序的時候,若是沒有成功,則能夠迅速的回滾,而且從新來過。
目前大多數CI / CD工具都使用基於推送的模型。基於推送的流水線意味着代碼從CI系統開始,經過一系列構建測試等最終生成鏡像,最後手動使用「kubectl」將任何更改推送到Kubernetes集羣。
不少開發人員不肯意在CI中啓動CD部署流程,或者使用命令行工具操做啓動CD部署流程的緣由多是這樣作會將集羣的用戶和密碼等公佈出去。雖然能夠有措施保護CI / CD 腳本和命令行,可是這些操做畢竟仍是在集羣外部非可信區工做的。因此,相似作法是不可取的,會給系統安全帶來潛在的風險。
具備集羣外讀/寫(R/W)權限的典型推送流水線:
在GitOps中,鏡像被拉出而且憑證保留在集羣中:
Git庫是拉式流水線模式的核心,它存儲應用程序和配置文件集。開發人員將更新的代碼推送到Git代碼庫; CI工具獲取更改並最終構建Docker鏡像。GitOps檢測到有鏡像,從存儲庫中提取新鏡像,而後在Git配置倉庫中更新其YAML。而後,GitOps會檢測到羣集已過時,並從配置庫中提取已更改的清單,並將新鏡像部署到羣集。
在上節中介紹了GitOps採用拉式模式構建交付流水線,本節將詳細地介紹在構建GitOps流水時須要注意哪些事情,有哪些最佳實踐。
這是一個新圖,顯示部署上游的全部內容都圍繞Git庫工做的。在「拉式流水線」中講過,開發人員將更新的代碼推送到Git代碼庫,CI工具獲取更改並最終構建Docker鏡像。GitOps的Config Update檢測到有鏡像,從存儲庫中提取新鏡像,而後在Git配置倉庫中更新其YAML。而後,GitOps的Deploy Operator會檢測到羣集已過時,並從配置庫中提取已更改的清單,並將新鏡像部署到羣集。
使用羣集內部的Deploy Operator,羣集憑據不會在生產環境以外公開。一旦將Deploy Operator安裝到集羣與Git倉庫創建鏈接,線上環境中的任何更改都將經過具備徹底回滾的Git pull請求以及Git提供的方便審計日誌完成。
因爲沒有單一工具能夠完成流水線中所需的全部工做,能夠從開源生態系統中選擇一組工具,也能夠從封閉源中選擇一組工具,或者根據使用狀況,甚至能夠將它們組合在一塊兒,其實,建立流水線最困難的部分是將全部部件粘合在一塊兒。要實現GitOps,必需要開發出新的組件,用於粘合這些工具,實現拉式交付流水線。
部署和發佈自動化是應用落實GitOps,並使交付流水線工做的基礎。GitOps不只要保證,當開發人員經過Git更新配置文件集的時候,GitOps流水線要自動根據最新的配置文件狀態更新線上環境,並且GitOps還要可以實時比對Git庫中配置文件集最新的狀態與線上環境最新的狀態保持一致。
在上節中提到了兩個名詞:Config Update 和 Deploy Operator,根據GitOps的實踐,Config Update 和 Deploy Operator是須要進行設計開發的,它們是實現GitOps流水線必須的關鍵組件。GitOps賦予了它們神奇的魔法,它們既是自動化容器升級和發佈到線上環境的工具,可能也要負責服務、部署、網絡策略甚至路由規則等任務。所以,Config Update 和 Deploy Operator是映射代碼,服務和運行集羣之間全部關係的「粘合劑」。
固然,您能夠根據具體的設計,賦予各類其餘的功能,可是自動同步是必定須要的,確保若是對存儲庫進行任何更改,這些更改將自動部署到線上環境中。
GitOps建議不直接將應用程序部署到線上環境中,而是將應用程序和相關配置打包成鏡像,並存儲到鏡像庫中,最後,經過鏡像的方式生成容器,並部署到線上環境中。
容器爲何如此重要?在GitOps模型中,咱們使用不可變基礎架構模式。一旦代碼在Git中提交,GitOps就不但願任何其餘內容發生變化,這樣能夠最大限度地下降系統潛在不肯定性、不一致性風險。例如,須要將相同的應用部署到不一樣的機器上。一般須要系統管理員確保全部的機器都處於相同的狀態。接着全部的修改、補丁、升級須要在全部的機器中進行。隨着時間的推移,很難再確保全部的機器處於相同的狀態,同時愈來愈容易出錯。然而,容器是比較完美地解決了這個問題,固然,使用虛擬機是能夠的,顯然使用容器更加方便。
「可觀察性就像生產中的驅動測試同樣。若是你不知道如何肯定它是否正常工做,請勿接受 pull request。@mipsytipsy 「 - Adriano Bastos
在GitOps中,使用Git庫來存儲應用系統的配置文集和應用程序,它確保開發人員將全部對於應用系統的配置和程序的新增、修改等都經過Git庫進行版本控制,使Git成爲配置和程序的惟一真實來源。而GitOps的可觀察性則是確保線上環境的真實狀態與Git庫中的保持一致性。本章節將給你們介紹GitOps的可觀察性。
在GitOps中,咱們使用Git做爲系統所需狀態的真實來源。例如,若是應用系統宕機,GitOps能夠回滾到以前正確狀態。而可觀察性是系統實際運行狀態的真實來源,系統開發人員或者運維人員能夠監控系統的狀態。這是一張顯示流程的圖片。
若是你們使用Kubernetes做爲雲原生環境和容器編排工具,相信你們會有這樣的感觸,雖然Kubernetes是一個很是棒的編排容器平臺,可是隨之而來的缺少友好的可視化管理界面給開發人員或者運維人員帶來諸多不便。例如:
你們可能會想到經過監控服務器的CPU、內存、網絡等,以及應用的日誌,甚至微服務的調用鏈等來解決問題。是的,這個沒有錯,可以獲得一些反饋信息,可是使用過相似監控的開發人員或者運維人員也會感受,這些監控儀表盤給咱們大量冗繁的信息,須要認真地甄別,並且有不少信息在這些儀表盤中是得到不到的。這意味着須要建立新的儀表盤,用於監控新的指標和內容。
可觀察性可被視爲Kubernetes 持續交付週期的主要驅動因素之一,由於它描述了在任何給定時間系統的實際運行狀態。觀察運行系統以便理解和控制它。新功能和修復程序被推送到git並觸發部署管道,當準備好發佈時,能夠實時查看正在運行的集羣。此時,開發人員能夠根據此反饋返回到管道的開頭,或者將映像部署並釋放到生產集羣。
在這裏GitOps引入一個新的工具:Diffs,用來監控對比系統狀態。即:
在文章前面講過,在Git庫中存儲的其實是「聲明性基礎設施」,例如Kubernetes的YAML文件,用以構建應用系統所需的各類組件、域名、網絡等配置信息。Diffs須要讀取Git庫中配置信息,同時,經過API等讀取集羣的相應信息,並進行比對。
例如,Kubernetes集羣:所需的Kubernetes狀態多是「有4個redis服務器」。Diffs按期檢查羣集,並在數量從4變化時發出警報。通常而言,Diffs將YAML文件轉換爲運行狀態查詢。
GitOps是面向發佈的操做模型,請參見下圖。交付速度取決於團隊在此週期中繞過各個階段的速度。
因爲以安全的方式跟蹤和記錄更改,所以合規性和審計變得微不足道。使用Diffs等比較工具還能夠將Git庫中定義的集羣狀態與實際運行的集羣進行比較,從而確保更改與實際狀況相符。
經過上面文章的敘述,開發人員或者運維人員經過Git操做系統配置和應用程序的新建和更新等。經過Git客戶端git commit /git merge的全部操做都會Git庫記錄下來,審計員能夠查看Git,看看誰作了任何更改,什麼時候以及爲什麼以及如何影響正在運行的系統部署。固然,能夠根據自身的需求定製不一樣的交付合規性。相較於直接進入服務器操做或者經過Kubctl操做集羣,Git記錄了每個操做步驟,這些能夠爲合規性和審計提供完整的操做日誌。
幾乎全部的Git庫都提供角色和權限控制,與開發和運維無關的人員沒有權限操做Git庫。而不是直接把服務器或者集羣的操做權限散發出去,這樣特別容易引發安全泄露。
藉助GitOps的最佳實踐,開發人員可使用熟悉的Git工具,便捷地將應用程序和其對應的配置文件集持續部署到Kubernetes等雲原生環境,提升業務的敏捷度,快速地相應用戶的需求,有助於增長企業市場的競爭力。
藉助GitOps,能夠實現一個完整的端到端的交付流水線。不只能夠實現拉式的持續集成流水線和持續部署流水線,並且系統的運維操做能夠經過Git來完成。
更強大的安全保證
幾乎全部的Git庫都提供角色和權限控制,與開發和運維無關的人員沒有權限操做Git庫。而不是直接把服務器或者集羣的操做權限散發出去,這樣特別容易引發安全泄露。
因爲以安全的方式跟蹤和記錄更改,所以合規性和審計變得微不足道。使用Diffs等比較工具還能夠將集羣狀態的可信定義與實際運行的集羣進行比較,從而確保跟蹤和可審計的更改與實際狀況相符。
Choerodon 豬齒魚做爲開源多雲應用敏捷全鏈路技術平臺,是基於開源技術Kubernetes,Istio,knative,Gitlab,Spring Cloud來實現本地和雲端環境的集成,實現企業多雲/混合雲應用環境的一致性。平臺經過提供精益敏捷、持續交付、容器環境、微服務、DevOps等能力來幫助組織團隊來完成軟件的生命週期管理,從而更快、更頻繁地交付更穩定的軟件。
更加詳細的內容,請參閱Release Notes和官網。
你們也能夠經過如下社區途徑瞭解豬齒魚的最新動態、產品特性,以及參與社區貢獻:
歡迎加入Choerodon豬齒魚社區,共同爲企業數字化服務打造一個開放的生態平臺。
本篇文章出自 Choerodon豬齒魚社區甘閃閃。