如何基於Kubernetes構建完整的DevOps流水線

前言

關於DevOps是一個很大的話題,它可能既涉及到公司的技術文化構建,也包括開發者技術能力的支持,這次技術乾貨分享主要是側重於技術方面,就是如何用Kubernetes來服務好DevOps的流水線。本文從4個方面介紹:

  1. 什麼是Kubernetes?爲什麼Kubernetes比較適合用來構建DevOps的流水線?
  2. 如何基於Kubernetes來構建DevOps流水線?
  3. 如何在Azure上面利用AKS去構建DevOps流水線?
  4. DevOps中常見的一些挑戰。

1. 什麼是Kubernetes?爲什麼Kubernetes比較適合用來構建DevOps的流水線?

Kubernetes是目前最爲廣泛且流行的容器編排調度系統,它也是現在用來構建雲原生應用編排的最佳平臺。目前所有云原生應用基本上都會基於Kubernetes  API去構建

Kubernetes給開發者帶來了很多實用的特性,比如一致性、可擴展性、自我修復的功能。一致性是指在Kubernetes上構建的應用可以無縫的遷移到任何環境裏,不論公有云、私有云還是跨雲。可擴展性是指把Kubernetes的插件機制運用到任何環境裏,通過Kubernetes這些插件都可以實現自定義化。Kubernetes的自我修復功能,包括健康檢查、故障的自動恢復、自動擴展等機制,這些對於系統運行至關重要。

Kubernetes的架構比較簡單,分爲Master和Node兩部分。

  • Master主要負責集羣的狀態維護,也給集羣提供一個對外訪問的入口;

  • Node負責運行容器,爲容器提供一些必要的環境,比如存儲、網絡等。

Kubernetes在Master上必備的組件只有四個,在Node上必備的組件,除了Kubelet、Kube-proxy,還有Docker等。而其他所有的一切都是通過擴展的方式部署到集羣裏,比如在部署一個集羣時,DNS是一個必需的功能,但這個功能是以一個容器的方式部署到集羣裏。

由於Kubernetes架構非常簡單。因此它有一些特別的好處,就是可以運用到DevOps流水線裏面來。以持續集成爲例,在版本升級測試新的特性時,在Kubernetes之前可能要通過IPM包管理這些軟件,當升級IPM包時,有可能產生衝突。而在Kubernetes中,通過把IPM包放到每一個容器裏,避免軟件包的衝突問題。如果把每個應用程序所依賴的東西都放到了容器裏面,應用程序在不同環境裏就可以很容易保持一致。

在DevOps裏監控系統很關鍵,而在Kubernetes中,通過一個Pod的方式運行容器,應用程序可以部署在Pod的一個容器裏,其他的容器可以用在監控裏。

在DevOps中經常需要頻繁地發佈、變更系統,發現問題時需要回滾,而在頻繁的發佈和回滾時,需要有一個系統去管理這些發佈的歷史生命週期,在發現問題時纔可以回滾回來。對於系統來說,要求它發佈的過程中不能影響應用程序對外正常訪問。在Kubernetes中已經有了原生的機制,比如用Service和Deployment來完成這個功能,Service可以提供一個對外訪問的入口,自動做好負載均衡;Deployment負責管理好這些副本。如果需要升級,通過滾動升級的方式去部署。

2. 基於Kubernetes的DevOps

DevOps是把人員流程、產品進行結合,給用戶提供持續價格的一個過程,這個過程既涉及到人員、過程,也涉及到產品。DevOps最終目的是給客戶提供持續交付的價值,流程包括:產品的規劃跟蹤、軟件開發、構建測試、產品部署、運維、監控和優化,並通過一個流水線的方式串聯起來。因此通常把DevOps這些流程合併起來稱爲一個DevOps的流水線。這個流水線的核心目標,就是持續給用戶交付有價值的產品。

Kubernetes如何服務好DevOps流水線?Kubernetes的好處就是可以把不同的產品、工具串聯起來。以CI/CD裏最常用的Jenkins爲例:現在有一個Jenkins-x項目,實現了與Kubernetes的集成,利用Kubernetes的CI/CD實現了自定義的兌現,有了這些資源兌現,就可以通過Kubernetes的API來定義CI/CD的過程。

另外如果使用Kubernetes構建整個流水線,在監控的時候就可以同樣選擇Kubernetes生態之中的項目,比如可以直接從Prometheus裏獲得很多指標,去構建想要的監控告警,以及後續的對整個產品的優化依據。基於這些工具,就可以構建一個DevOps的流水線。

一個比較典型的DevOps的流水線過程是:項目開始開發時,用VS  Code開發代碼,然後把代碼推送到GitLab裏存儲,通過GitLab的hook使Jenkins執行一些CI的過程,比如做一些單元測試,構建Docker  image,再把這個Docker  image調用helm部署到開發環境或測試環境中。在測試環境裏通過Jenkins觸發一個集成測試的功能,完成後就可以把它部署到生產環境裏,通過Kubernetes addon的方式,把Prometheus、Grafana等監控組件部署到集羣裏,就實現了一整套從CI到CD的監控過程。

3. 基於AKS的Devops

AKS是Azure提供的一個託管的Kubernetes服務,因爲很多人在接觸Kubernetes時發現它最大的痛點是Kubernetes的安裝部署和維護太麻煩。Kubernetes發佈特別快,在升級的過程中很容易出現各種問題,而AKS的出現可以解決這些問題。

需要注意的是,AKS只是提供了一個託管的Kubernetes服務,也就是它只提供了一個K8s的集羣,而爲了運行這個集羣,還需要其他東西,比如要考慮Docker  image要存在哪裏的問題。ACI提供了跨地域自動複製的功能,因此Docker  image只要存到ACI裏,就可以在不同的Image裏使用。

另外在DevOps的流水線裏執行任務時,這些任務都類似Kubernetes的一個Job,比如在持續集成裏做一個單元測試,這個單元測試可能運行很短時間就結束了,但如果用AKS,或者通過其他產品的Kubernetes集羣來管理這套DevOps流程,要優先保證最大的Job數量時,它才能夠正常的運行。但是這會造成一定的資源浪費。

ACI是一種無服務器化的容器解決方案,用戶無需管理底層服務器,只需要調用它的API把一個容器運行起來即可。另外如果運行的程序還有一些數據要存儲,如果要訪問數據庫,就需要用cosmosDB等服務,而它們已經跟AKS、Kubernetes有了很好的集成,這些服務可以很方便地在Azure上使用。

如何構建一套比較完善的DevOps流水線呢?

首先要創建項目,選擇最合適的產品來管理進度,用Azure  DevOps把產品後面的代碼開發、單元測試和集成測試、持續部署等串聯起來。Azure  DevOps提供了Backlog等工具來管理應用程序。

開發項目時,需要一套Git存儲倉庫,Azure  DevOps也提供了這個功能。而項目開發完成之後,需要的本地測試可以使用Draft,它的好處就是可以把進項打包,再通過Helm部署到開發環境裏,並且可以自動設置好應用程序的遠程調試。也就是讓應用程序以容器的方式運行在一個Kubernetes的環境中,但是可以通過VS Code在線調試程序。

如果應用程序在本地測試通過了,就需要推送到代碼倉庫裏持續集成,然後需要部署到測試環境裏做相應的測試,最終再把它部署到生產環境裏。當這一切做完了以後,應用程序就已經在線上跑了,但這個時候DevOps流程並沒有結束,因爲還需要運維和監控這個應用程序。這個時候就可以Azure monitor監控這個程序的狀態。

4. DevOps的挑戰

DevOps的挑戰,首先就是自動化的測試不足。DevOps流水線由於測試的投入不足,新發布的功能沒有測試到,這個時候發佈到生產環境就容易出現各種各樣的問題。比如應用程序部署之後,可用性降低了,資源使用率突然升的很高等。對於這個問題實際上可以通過一定的組織文化建設去解決。一個比較簡便的方式就是對這些過程提供適當的測試覆蓋率的要求。例如一個新的產品發佈時,要求測試覆蓋率不能降低了,但是測試覆蓋率是比較難以控制的,可能要從組織文化上來解決。

第二個問題就是DevOps的工具鏈缺少鏈接,沒有鏈接就沒有辦法做到高度的自動化。比較推薦的做法是選用Kubernetes生態中的這些工具鏈,利用Kubernetes  API把應用程序更好地串聯起來,形成完整的DevOps的流水線。

第三個問題就是很難量化成果,以及很難協調團隊之間的合作。比如用戶抱怨網站訪問速度慢了,由於當下並不知道慢的問題在哪裏,所以要到各個產品裏去檢查。如果沒有一套完善的監控系統,就很難定位這個產品到底是該由誰去負責。針對這個問題可以使用Kubernetes,在不改變應用程序的情況下,跟蹤整個應用程序的調用鏈,比如可以使用ServiceMesh監控這些應用程序,這樣可以減少發現問題之後沒法具體定位產品的瓶頸。

最後一個問題就是在DevOps之中,雖然使用了Kubernetes的生態鏈工具,如果沒有遵循一些Kubernetes/DevOps的最佳實踐,會導致在實際操作中出現預想不到的問題。比如一個最簡單的問題,在升級的過程中可以用Kubernetes的Deployment來做滾動更新。按照正常的預期,在滾動更新的過程中,原來的副本還在正常運行着,新副本也是逐步去創建着,Service負載均衡也是正常運行的。但問題是,Service每次升級時總會時不時的斷一下,其可能用性在每次部署時,總會降低那麼一點。產生這個問題就是因爲沒有遵循Kubernetes最基本的最佳實踐,沒有給應用程序部署健康檢查。對於最佳實踐的問題,實際上需要整個團隊,不只是DevOps流水線的構建團隊,還需要應用程序的團隊共同把這些最佳實踐運用到流水線和應用程序的管理中。比如會出現Job的失敗率非常高的問題,這時不僅要對應用程序進行資源的限制,另外對DevOps流水線裏面的這些Job也要進行一定的資源控制,不要把資源全部耗光。

經驗之談

在Kubernetes中,不建議大家直接去管理一個Pod,你之前創建了一個Pod,而沒有使用控制器去管理它。在Kubernetes中,建議每一個Pod都有一個控制器來管理,比如你可以用Deployment來管理,或者使用副本控制器來管理。所有這些控制器都是用來保證Pod在預期的狀態。也可以使用自己的控制器去管理這些Pod,通過開發一個API去管理生命週期。這樣容器最終在運行狀態時,總是有一個控制器來管理,就不會出現一個容器在一直在運行,卻不知道是誰在管理的問題。


嘉賓簡介

倪朋飛,就職於微軟Azure,主要關注Kubernetes與微服務,同時也是Kubernetes開源社區SIG Azure Tech Lead。作爲Kubernetes項目維護者,同時負責維護開源書籍《Kubernetes指南》。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章