一文詳解 kubernetes 5種常見發佈模式如何選擇

Kubernetes面向通用場景提供了非常靈活的應用管理和運維方式,而作爲雲效CI/CD平臺的開發同學,在日常和用戶交流過程中,我們經常會被用戶問到關於發佈的問題,比如不同職能團隊之間應該如何配合、發佈的最佳實踐應該是什麼樣子的等等。

今天我們就來聊聊Kubernetes下應用發佈方式的選擇,每種發佈模式適合什麼樣的場景,以及如何在雲效上高效落地。

Kubernetes應用

首先我們來看看一般情況下Kubernetes是如何管理應用的。 Kubernetes通過聲明式的API,並提供了一系列的資源來滿足各種各樣的應用運維場景:

• 從應用的角度我們會關注應用容器(Pod),應用配置(ConfigMap/Secret),應用需要持久化的信息(Volume),應用與應用之間的服務發現(Service),以及如何將應用服務暴露給集羣外的用戶(Ingress)等。

• 從集羣運維的角度看,由於應用運行在集羣中我們需要控制應用在集羣中的權限(
ServiceAccount/ClusterRole/Role)使得應用能夠以最小所需權限原則在集羣中運行,同時運維要管理和配置集羣的存儲資源(PV/PVC),同時對於資源有限的情況我們還需要管理和控制應用本身的資源暫用以及配額(quata)等等等。

而在實際場景中由於應用使用的框架(Doubbo/Spring Cloud)的不同,應用對外提供的服務場景不同(後端或者前端),不同的應用可能只需要關注其中的一小部分資源
比如當你採用了像Spring Cloud或者Doubbo這類自帶了服務發現的應用開發框架,你可能並不關心Kubernetes所提供的服務發現能力(Service),只需要通過Deployment來部署和管理這些應用實例。 又比如說如果你採用了單獨的配置管理中心,那ConfigMap/Secret這些可能也不會出現在你的Kubernetes資源清單中。
又比如說,如果是一個面向用戶前端應用,在應用部署是除了Deployment實例以外,你還要關係如何將這個服務暴露給外部用戶,這是就需要相應的Ingress以及Service的資源來描述。

同時在單個應用在整個系統中所處的位置不同又會導致我們對於發佈的驗證方式也會產生差異,比如一個後端微服務的發佈,我們可能只需要確保發佈過程系統不中斷即可,而對於前端應用我們可能希望發佈能夠現在一小部分用戶上進行驗證,在線上流量充分測試後,再完成整個版本升級。

如上所示,對於應用而言採用的技術架構不同,提供的服務的方式不同,對發佈驗證方式要求的不同都會導致Kubernetes的使用上產生各種各樣的差異,而云效爲了能夠支持這些不同的差異提供了多種多樣的發佈模式,接下來我們就來看看雲效下常用的這些發佈模式,以及他們所適用的場景。

Kubernetes發佈模式

最原生:YAML發佈

顧名思義,這是我們在使用Kubernetes時最直接的應用部署方式,而在持續交付流水線中我們一般將這些用於描述Kubernetes資源的YAML文件通過Git進行統一版本管理,通過雲效CI/CD平臺監聽代碼庫的變更事件,並通過流水線將這些YAML變更同步到集羣當中。這種方式也被稱爲GitOps模式。

在雲效當中,我們除了支持直接同步YAML到Kubernetes集羣以外,還擴展了基本的模板能力,你可以通過在YAML文件中定義變量佔位符如${IMAGE},通過流水線運行是通過Docker鏡像構建或者阿里雲鏡像倉庫觸發器(幫助文檔:阿里雲鏡像倉庫觸發器觸發流水線),動態產生要發佈的鏡像版本

如下所示:

YAML發佈支持任意資源類型,因此適用於如下場景:

1、開發自運維,團隊並充分理解和掌握Kubernetes原生的發佈策略,希望通過YAML完成應用的升級與發佈以及回滾,一般來說應用Git庫會包含應用源碼,Dockerfile以及部署應用所需的所有YAML文件(在某些情況下,YAML可能是由單獨的Git倉庫進行管理,以進行細粒度的權限控制)。

2、基礎設施運維:運維團隊通過Git管理集羣的所有基礎設施配置,並通過流水線完成集羣的統一管理以及配置的同步

更多詳細使用介紹請參考:雲效Kubernetes YAML發佈

最簡單:鏡像升級

在和一些雲效用戶的交流場景中,在也會有用戶希望開發團隊能夠儘可能少的理解Kubernetes相關概念,在這種情況下由專職的運維團隊負責完成應用環境的部署和初始化。而開發團隊只負責完成代碼開發,並通過流水線自動化完成應用鏡像構建,並使用該鏡像對集羣中已有的應用進行升級。開發團隊只關心應用的工作負載實例資源。

如下圖所示,在雲效流水線中我們監聽應用代碼庫的變化,並構建出相應的Docker鏡像,而發佈階段只需要指定對集羣中實例並關聯前序任務產生的鏡像即可完成應用的升級發佈:

如上所述,該場景適用於:

• 開發和運維分離:運維團隊充分理解Kubernetes的原生髮布策略,開發團隊只負責產出代碼以及應用鏡像,由運維團隊負責集羣中應用的實際運維管理。

關於如何在雲效中使用鏡像升級能力,請參考:雲效Kubernetes鏡像升級

過程可控:分批發布

在前面兩個小結中,我們都強調用戶需要充分理解Kubernetes的原生髮布策略,Kubernetes原生的發佈策略主要是指RollingUpdate模式,用戶通過聲明升級策略,如maxSurge和maxUnavailable控制Pod的啓動策略以及最大不可用Pod數,來確保即使應用發佈出現異常的情況,也能保證服務的基本可用。

除此,由於應用啓動往往有一定的耗時,如果使用了Kubernetes的服務發現機制,我們還需要配置如liveness以及readiness探針,來避免應用還在啓動過程中就有不在計劃內的流量進入到正在啓動的實例當中。同時整個發佈過程是不可逆的,假如認定當前發佈出現了異常我們只能通過重新發布的方式來使應用回到可用狀態。

而在雲效的分批發布中,我們以Service爲最小發布單元,在發佈開始階段我們將基於新版鏡像創建出應用的版本V2,並根據當前應用的副本總數以及分批數量,對新舊兩個版本的應用實例分別進行縮容和擴容,來控制實際進入到新版應用的流量比例,從而可以實現小規模的發佈驗證,在對發佈進行充分驗證後再逐步完全下線老版應用。

同時批次之間支持暫停和手動恢復讓用戶可以充分對針對發佈過程進行控制。

該模式適用於:採用Kubernetes原生的服務發現機制,並希望獲得相比於原生Kubernetes發佈更好過程控制性以及安全性的用戶。

更多詳細使用介紹,請參考幫助文檔:雲效Kubernetes分批發布

外部流量可控:Ingress灰度發佈

相比於分批發布灰度發佈更強調更加可控和安全的線上驗證。而灰度發佈在Kubernetes中由於應用的部署模式的不同大致分爲兩種,我們首先來說第一種,基於Ingress的灰度發佈,如下所示,我們通過Ingress將集羣內的服務暴露給外部用戶:

在發佈過程中我們希望能夠通過cookie或者header的方式使得特定的用戶或者開發人員,能夠在線上對新版本引用進行驗證,經過小部分可控的線上流量驗證後,我們的發佈可靠性更好,如果出現預期外的問題,也可以快速回滾,並且整個灰度驗證過程對非灰度用戶完全不可感知。

在雲效流水線的Ingress灰度發佈中,我們以Ingress作爲發佈單元,當觸發部署後,將會根據當前Ingress以及其關聯的Service/Deployment資源,基於新版鏡像創建出V2版本的Service/Deployment。 並通過Nginx Ingress的Annoation完成對流量規則聲明,從而確保只有滿足特定特徵的流量才能進入到V2版本中,當處於灰度狀態時,流水線將會等待人工驗證,以觸發發佈或者或者回滾操作。

關於如何在雲效流水線中使用灰度發佈請參考幫助文檔:雲效Nginx Ingress灰度發佈

該模式適用於:採用Ingress對外暴露應用服務,並且希望能夠通過灰度的方式對發佈進行驗證

內部流量可控:Istio/ASM灰度發佈

而在微服務的場景中,並不是所有的服務都需要直接暴露給外部用戶,如下所示:

當採用微服務架構,我們大部分的後端服務是隻暴露與集羣內,微服務之間通過Kubernetes Service進行相互訪問,在這種情況下,當採用灰度發佈模式時,我們需要在Service級別進行流量控制,已確保指定的流量才進入到灰度的鏈路而不對正常用戶產生影響。

不過由於Kubernetes原生在Service級別並不支持任何的流量控制規則,因此我們需要在集羣中部署Istio或者採用阿里雲ServiceMesh來對服務之間的流量進行細粒度的控制。

如下圖所示,當使用Kubernetes藍綠髮布模式時,可以設置灰度流量規則,從而只有當請求中包含指定的Cookie配置的請求轉發到灰度版本當中:

該模式適用於:採用Istio或者阿里雲ServiceMesh的Kubernetes用戶,並且希望能夠通過灰度的方式對發佈進行驗證。

小結

在本文中,我們主要介紹了Kubernetes實際中的各種發佈模式以及相關的適用場景,希望能夠幫助用戶快速找到適合自己的發佈模式,當然如果你還有更多更好的交付實踐,也可以在留言中進行分享。

作者:鄭雲龍,阿里云云效技術專家

原文鏈接

本文爲阿里雲原創內容,未經允許不得轉載。

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