“生產(chǎn)就緒”是什么意思?如果你希望生產(chǎn)工作負(fù)載出現(xiàn)的問(wèn)題最少,那么這是應(yīng)該回答的第一個(gè)問(wèn)題。
這個(gè)問(wèn)題的答案可以從多個(gè)角度來(lái)討論:安全性、可維護(hù)性、測(cè)試、可配置性、穩(wěn)定性、可升級(jí)性、文檔等。筆者認(rèn)為生產(chǎn)就緒的應(yīng)用程序應(yīng)該具備上述所有元素。
在生產(chǎn)中部署Kubernetes工作負(fù)載時(shí),Kubernetes用戶往往選擇開(kāi)源項(xiàng)目Helm。很容易理解為什么:Helm擴(kuò)展了部署的適應(yīng)性和可定制性,簡(jiǎn)化了測(cè)試過(guò)程,允許歷史記錄和回滾管理等。
兩年多來(lái),筆者為這個(gè)項(xiàng)目做出了貢獻(xiàn),擴(kuò)展了可用目錄,提供了各種各樣的基礎(chǔ)設(shè)施應(yīng)用程序,并審查了pull請(qǐng)求、添加了功能和處理了支持案例。根據(jù)筆者的經(jīng)驗(yàn),如果開(kāi)發(fā)人員想要?jiǎng)?chuàng)建可以在生產(chǎn)環(huán)境中部署的chart,那么應(yīng)該注意五個(gè)要素。
1)通過(guò)限制容器操作確保安全:運(yùn)行非根容器
要部署容器化應(yīng)用,必須將允許的操作數(shù)限制為所需的最小值。要確保這一點(diǎn),請(qǐng)使用與根用戶不同的隨機(jī)用戶啟動(dòng)容器。這些容器稱為非根容器。這是一些基于Kubernetes的平臺(tái)(比如紅帽的OpenShift)的強(qiáng)制要求。在穩(wěn)定存儲(chǔ)庫(kù)中大約有一半的chart已經(jīng)使用非根容器,并且這個(gè)數(shù)目還在增加。如果應(yīng)用程序允許,你可以更進(jìn)一步,使用完整的只讀文件系統(tǒng)或“scratch”容器(這些容器沒(méi)有任何底層的基本操作系統(tǒng))。
2)限制對(duì)集群的訪問(wèn):實(shí)施基于角色的訪問(wèn)控制策略(RBAC)
Kubernetes集群的核心是它的API服務(wù)器(kube-apiserver)。通過(guò)訪問(wèn)它,你可以獲得集群的當(dāng)前狀態(tài)和部署在集群上的工作負(fù)載的詳細(xì)信息。開(kāi)發(fā)人員正在采用這種方法:目前,有許多感知Kubernetes的應(yīng)用程序可以訪問(wèn)API服務(wù)器進(jìn)行自我發(fā)現(xiàn)等操作。但是,對(duì)Kubernetes API服務(wù)器具有完全訪問(wèn)權(quán)限的容器可能會(huì)損害集群。為了降低這種風(fēng)險(xiǎn),你必須確保pod中的進(jìn)程只能訪問(wèn)所需的最小數(shù)據(jù)集。
這就是基于角色的訪問(wèn)控制策略發(fā)揮作用的地方。例如,如果部署的基礎(chǔ)設(shè)施應(yīng)用程序使用kube-apiserver在命名空間“test”中進(jìn)行自我發(fā)現(xiàn),則可能只需要允許對(duì)該特定命名空間中的pod對(duì)象執(zhí)行“get”和“list”操作。在過(guò)去,用戶向Helm client Tiller這樣的應(yīng)用程序授予集群管理權(quán)限(即執(zhí)行集群內(nèi)所有操作的權(quán)限)。這種做法會(huì)導(dǎo)致災(zāi)難。
不要忘記確保使用chart部署的應(yīng)用程序具有盡可能小的RBAC權(quán)限集。
3)完成適當(dāng)?shù)臏y(cè)試,特別是關(guān)于升級(jí)
更新Statefulset中的標(biāo)簽可能導(dǎo)致中斷helm upgrade命令。要處理這種情況,在管道中包括升級(jí)測(cè)試是一項(xiàng)優(yōu)先級(jí)很高的任務(wù)。顯然,你不能假設(shè)主要版本之間的升級(jí)會(huì)在沒(méi)有手動(dòng)干預(yù)的情況下實(shí)現(xiàn)。但是,確保非主要版本之間的升級(jí)順利是可行的。
在chart中添加默認(rèn)禁用的功能是另一個(gè)常見(jiàn)問(wèn)題。由于這些功能在默認(rèn)情況下是禁用的,正常的helm install測(cè)試可能不會(huì)檢測(cè)到任何問(wèn)題。
這種情況的一個(gè)例子是入口規(guī)則。這些參數(shù)在默認(rèn)情況下是禁用的,因此你在日常測(cè)試中很容易忘記它們??梢灶A(yù)見(jiàn),當(dāng)大多數(shù)Ingress API Object使用的API Group擴(kuò)展/v1beta在Kubernetes 1.20中被棄用時(shí),穩(wěn)定存儲(chǔ)庫(kù)中的數(shù)個(gè)chart會(huì)出現(xiàn)問(wèn)題??梢酝ㄟ^(guò)使用多個(gè)values.yaml文件來(lái)增加chart的測(cè)試覆蓋率來(lái)防止這一問(wèn)題。為了幫助解決這個(gè)問(wèn)題,像kubeval這樣的解決方案可以派上用場(chǎng)。
4)不惜一切代價(jià)避免滾動(dòng)標(biāo)簽
你可能已經(jīng)熟悉了容器鏡像,并且可能已經(jīng)執(zhí)行了至少一次docker pull bitnami/redis:latest這樣的命令。這個(gè)“latest”是滾動(dòng)標(biāo)簽的一個(gè)例子(即隨著時(shí)間的推移指向不同鏡像的標(biāo)簽)。
想象一下下面的場(chǎng)景:你希望使用最新版本的Redis部署“bitnami/redis”chart。為此,你使用“laest”標(biāo)簽,以便知道集群中將運(yùn)行Redis 5.0.5。部署chart時(shí),一切都可以無(wú)縫工作。現(xiàn)在進(jìn)一步想象一下,如果將來(lái)有一天,你需要用新的pod來(lái)擴(kuò)展Redis集群(將下載“bitnami/redis:latest”鏡像)。如果現(xiàn)在最新的Redis是5.0.8呢?你將擁有運(yùn)行不同版本Redis的同一Redis集群的pod。更糟糕的是,如果Redis6.0.0發(fā)布了呢?Redis集群肯定會(huì)崩潰。
如果你希望能夠維護(hù)和控制部署,請(qǐng)確保chart使用不可變的鏡像(例如:“bitnami/redis:5.0.5-debian-9-r10”)。通過(guò)這種方法,每次部署或擴(kuò)展時(shí),你都知道正在使用什么鏡像。另外,你還可以保證已部署的鏡像已使用該chart的特定版本進(jìn)行了測(cè)試,這是使用滾動(dòng)標(biāo)簽時(shí)無(wú)法保證的。
5)監(jiān)控部署
這個(gè)技巧很簡(jiǎn)單:如果你想讓工作負(fù)載準(zhǔn)備好,你需要對(duì)它們進(jìn)行監(jiān)控。大多數(shù)生產(chǎn)就緒的chart都支持指標(biāo)導(dǎo)出器,因此應(yīng)用程序狀態(tài)可以通過(guò)Prometheus和Wavefront之類的工具或BKPR之類的套件來(lái)觀察。此外,確保工作負(fù)載與ELK之類的日志堆棧集成對(duì)于提高容器化應(yīng)用的可觀察性也是很重要的。其優(yōu)點(diǎn)不計(jì)其數(shù):早期故障預(yù)防、審計(jì)、趨勢(shì)檢測(cè)、性能分析或調(diào)試等。
通過(guò)遵循上面的提示,你將涵蓋Kubernetes生產(chǎn)就緒的所有基礎(chǔ)知識(shí)。但是還有很多領(lǐng)域需要你去探索,比如穩(wěn)定性、性能、網(wǎng)絡(luò)、自動(dòng)伸縮等。
原文鏈接:
https://thenewstack.io/5-tips-to-deploy-production-ready-applications-in-kubernetes/