需要盡早知道的Kubernetes最佳實踐
我希望能早點知道的Kubernetes最佳實踐。從我在生產(chǎn)環(huán)境中使用Kubernetes的經(jīng)驗中學(xué)習(xí),并避免常見的陷阱。
譯自Kubernetes Best Practices I Wish I Had Known Before,作者 None。
Kubernetes 無可否認地改變了我們構(gòu)建、交付和運行應(yīng)用程序的方式。但說實話,開始使用 Kubernetes 感覺就像穿著人字拖攀登珠穆朗瑪峰一樣。
作為一名云原生開發(fā)者和 Kubernetes 愛好者,我通過艱難的經(jīng)驗學(xué)習(xí)到了一些“早知道就好了”的最佳實踐。這些實踐本來可以為我節(jié)省時間、金錢和麻煩。
圖片
“Kubernetes 很容易”的冰山一角 meme 是 Kubernetes 具有欺騙性復(fù)雜性的經(jīng)典示例
在這篇文章中,我將重點介紹一些重要的 Kubernetes 最佳實踐。這些實踐來自我在生產(chǎn)環(huán)境中使用 Kubernetes 多年的經(jīng)驗。您可以將此視為您從第一天起就希望擁有的精選“Kubernetes 速查表”。系好安全帶;這將是一次激動人心的旅程。
1. 不要吝嗇資源請求和限制
在 Kubernetes 中的第一個“啊哈!”時刻之一是意識到您可以定義容器請求(保證的資源)和限制(允許的最大值)的 CPU 和內(nèi)存數(shù)量。棘手的部分是:跳過這些設(shè)置可能會給您帶來麻煩。
- 資源請求(Requests):這基本上是您容器的基線。如果您的容器請求 200m CPU 和 512Mi 內(nèi)存,Kubernetes 調(diào)度程序?qū)涯?Pod 部署到至少具有這么多可用容量的節(jié)點上。
- 資源限制(Limits):這是上限。如果您的容器試圖超過限制,它可能會被限制(CPU)甚至被驅(qū)逐(內(nèi)存)。
專業(yè)提示:
- 從某個基線開始,也許是 100-200m CPU、128-512Mi 內(nèi)存,然后在收集更多數(shù)據(jù)時進行調(diào)整。
- 使用 Prometheus 或 Datadog 等監(jiān)控工具來分析實際使用情況并根據(jù)需要進行調(diào)整。
2. 像你的生命依賴它一樣使用命名空間
如果您將所有內(nèi)容都部署到默認命名空間中,哦,男孩,是時候進行干預(yù)了。命名空間是一種簡單而強大的機制,用于組織(和隔離)集群中的資源。
- 基于團隊的命名空間:開發(fā)、測試、生產(chǎn)或每個微服務(wù)(如果合適)。
- 訪問控制:將命名空間與 RBAC(基于角色的訪問控制)策略結(jié)合使用,以確保只有合適的人員(和服務(wù))才能訪問您的資源。
- 資源配額:您可以為每個命名空間設(shè)置配額(例如,CPU、內(nèi)存),防止一個流氓微服務(wù)占用所有資源。
退一步,設(shè)計您的命名空間策略;未來的您會感謝您的。
3. 除非必要,否則避免在一個 Pod 中運行多個容器
是的,一個 Pod 可以包含多個容器。但是應(yīng)該嗎?通常,只有當容器緊密耦合并且必須共享資源(如卷或網(wǎng)絡(luò)命名空間)(例如,用于日志記錄或安全代理的 sidecar 模式)時,您才需要在同一個 Pod 中使用多個容器。
為什么要避免多容器 Pod?
- 復(fù)雜性:對單個 Pod 中的多個容器進行故障排除可能很痛苦。
- 耦合:您失去了獨立擴展容器的優(yōu)勢。如果您需要擴展一個容器,您最終會擴展該 Pod 中的所有內(nèi)容。
遵循“每個 Pod 一個容器”的經(jīng)驗法則,除非您有令人信服的理由(例如 sidecar 模式)。
4. 使用包管理器管理您的 YAML 文件
手動處理跨多個微服務(wù)的數(shù)百個 YAML 文件,就像凌晨 3 點調(diào)試意大利面條代碼一樣有趣。這就是 Helm、Kustomize 或 Timoni 等工具的用武之地。
- Helm: Kubernetes 的“包管理器”。它使用您可以通過值自定義的 Chart(模板)。
- Kustomize: 一個原生 Kubernetes 工具,允許您在基本 YAML 清單上疊加更改。
- Timoni: Timoni 是一個 Kubernetes 包管理器,由 CUE 提供支持,并受 Helm 的啟發(fā)。
專業(yè)提示:如果您不熟悉 Helm,請從 Helm Hub 或 Artifact Hub 中的官方 Chart 開始。然后根據(jù)您的喜好進行自定義。您將避免 YAML 重復(fù)的困擾。
或者,試用Pulumi并使用真正的編程語言來管理您的 Kubernetes 基礎(chǔ)設(shè)施。
5. Ingress 和網(wǎng)絡(luò)最佳實踐
在 Kubernetes 中,網(wǎng)絡(luò)可能會很快變得復(fù)雜。在服務(wù)、Ingress 控制器和負載均衡器之間,很容易陷入困境。請記住以下幾點:
- 使用 Ingress 控制器/Gateway API(NGINX、Traefik、HAProxy、Istio Gateway 等)來管理外部訪問。
- 利用基于路徑和基于子域的路由來簡化您的網(wǎng)絡(luò)拓撲。
- TLS 終止:在您的入口層終止 SSL/TLS。您可以卸載證書管理(例如,通過 cert-manager)并保持集群流量的安全和高效。
- Ingress是Kubernetes中一個強大的概念,請花時間正確設(shè)置它。混亂的Ingress配置就像通往漂亮大宅的坑坑洼洼的車道。
圖片
6. 依靠存活性探針、就緒探針和啟動探針
Kubernetes有點像個人助理,但它需要清晰的指令。如果沒有正確配置存活性探針、就緒探針和啟動探針,您的集群將無法判斷容器的健康狀況。
- 存活性探針: 檢查您的容器是否存活。如果失敗,Kubernetes將重啟容器。
- 就緒探針: 檢查您的容器是否已準備好接收流量。在準備好之前,它不會接收流量。
- 啟動探針: 對于啟動需要一段時間才能完成的應(yīng)用程序非常有用。它可以防止容器在初始加載期間過早被終止。
專業(yè)提示:在存活性探針之前先使用就緒探針。您不希望您的容器僅僅因為尚未準備好就被終止。微調(diào)閾值、周期和超時參數(shù)。
7. 注意您的安全:RBAC、Pod安全性和密鑰
在Kubernetes中,安全不僅僅是錦上添花——它是至關(guān)重要的。如果您的集群遭到破壞,游戲就結(jié)束了。
1) RBAC(基于角色的訪問控制):
- 從第一天起就實施它。
- 使用最小權(quán)限原則。只為每個用戶、服務(wù)帳戶或應(yīng)用程序提供他們所需的訪問權(quán)限。
2)Pod安全:
- 使用Pod安全準入功能來執(zhí)行標準(例如,不允許特權(quán)容器)。
- 確保您不是在絕對必要的情況下才以root用戶身份運行容器。
3)正確管理密鑰:
- 不要在容器鏡像或環(huán)境變量中以純文本形式存儲憑據(jù)或API密鑰。
- 使用外部密鑰操作符或密鑰存儲CSI驅(qū)動程序?qū)⒚荑€存儲在外部密鑰存儲中,例如AWS密鑰管理器、Pulumi ESC或HashiCorp Vault。
8. 監(jiān)控一切(然后更多地監(jiān)控)
在Kubernetes中,監(jiān)控不是可選的——而是強制性的。隨著容器不斷出現(xiàn)和消失,您需要強大的可觀察性來了解幕后發(fā)生的事情。
Prometheus + Grafana:度量和儀表板的經(jīng)典組合。
- ELK / EFK /Grafana Loki堆棧:Elastic(或OpenSearch)用于日志,加上Kibana和Fluentd/Fluent Bit用于日志收集或Grafana Loki用于日志。
- Jaeger / Zipkin / Tempo:如果您有相互調(diào)用的微服務(wù),則用于分布式跟蹤。
盡早設(shè)置警報。您不希望您第一次遇到麻煩是午夜時分從憤怒的用戶那里得到“為什么應(yīng)用程序這么慢?”的消息。
9. 使用CI/CD自動化部署
Kubernetes最大的優(yōu)勢之一是它使自動化整個發(fā)布過程變得更容易。如果您仍在進行手動部署,那么現(xiàn)在是時候轉(zhuǎn)向CI/CD管道了。
- Jenkins、GitLab、GitHub Actions,您可以選擇。
- 擁抱GitOps:將所有清單存儲在Git中,并讓像Flux或Argo CD這樣的工具將它們同步到您的集群。
- 如果部署失敗,則自動回滾。
- 自動化不僅加快了交付速度,而且還大大減少了人為錯誤的空間。
10. 保持Kubernetes集群和組件更新
運行過時的Kubernetes版本就像在2025年使用運行iOS 6的手機一樣。不可取。
Kubernetes發(fā)布周期: 次要版本大約每三個月發(fā)布一次,補丁程序發(fā)布頻率更高。
升級策略:
- 首先在開發(fā)環(huán)境中進行測試。
- 備份您的etcd(鍵值存儲)。
- 升級控制平面,然后升級工作節(jié)點,或者使用為您處理部分此工作的托管服務(wù)(例如,EKS、GKE、AKS)。
保持您的依賴項更新(例如,容器運行時、CNI插件等),以從最新的安全性和性能改進中受益。
11. 明智地使用標簽和注釋
標簽(Labels)和注釋(Annotations)乍一看似乎微不足道,但它們對于組織良好的集群來說是改變游戲規(guī)則的關(guān)鍵。
- 標簽: 用于 Kubernetes 對象分組和選擇的鍵值對。例如,app=my-app、env=staging、team=payments。
- 注釋: 用于附加非標識元數(shù)據(jù)的鍵值對(例如,版本信息、聯(lián)系郵箱或上次部署時間戳)。一致的標簽策略有助于快速過濾資源并維護集群的清晰思維導(dǎo)圖。
12. 采用多環(huán)境方法
如果您的開發(fā)、登臺和生產(chǎn)環(huán)境共享一個集群,您就是在玩火。雖然可以這樣做,但最佳實踐是將生產(chǎn)工作負載與測試環(huán)境隔離。
- 獨立集群: 至少為開發(fā)/登臺環(huán)境和生產(chǎn)環(huán)境各準備一個集群。有一些工具,例如vCluster,可以在單個集群中創(chuàng)建虛擬集群。
- 命名空間隔離: 如果您必須在同一個集群中運行它們,請使用嚴格的基于命名空間的隔離和 RBAC 規(guī)則。 保持環(huán)境分離可以降低風險,并使在沙箱中測試新功能更容易。
13. 優(yōu)化您的容器鏡像
不要交付包含一半 Ubuntu 系統(tǒng)以及隨機殘留文件的龐大容器鏡像。這會導(dǎo)致部署緩慢和資源浪費。
- 使用輕量級基礎(chǔ)鏡像,例如distroless、alpine 或基于最小操作系統(tǒng)的鏡像。
- 清理 Dockerfile 中的臨時文件和依賴項。
- 使用諸如Trivy或Anchore之類的工具定期掃描您的鏡像是否存在漏洞。
14. 實施可靠的日志記錄策略
日志是您進行故障排除的首選工具,在 Kubernetes 中,您需要一個能夠處理短暫 Pod 的解決方案。
- 集中式日志記錄: 無論是 ELK/EFK、Splunk 還是托管服務(wù),請確保日志不會僅僅存儲在短暫的容器存儲中。
- 結(jié)構(gòu)化日志記錄: JSON 或其他結(jié)構(gòu)化格式有助于您的日志系統(tǒng)更有效地解析和過濾日志。
- 日志保留和輪換: 定義明確的策略以防止日志存儲膨脹。
相信我,您不希望在生產(chǎn)事故發(fā)生時四處尋找日志。
15. 將 Kubernetes 當作牲畜,而不是寵物
服務(wù)器的古老格言——將它們視為牲畜,而不是寵物——也適用于 Kubernetes。不要依賴手動修復(fù)或人工干預(yù)。盡可能爭取不變的基礎(chǔ)設(shè)施:
- 如果 Pod 出現(xiàn)問題,請在 YAML、Code或容器鏡像中修復(fù)它,重新部署,然后讓舊的 Pod 消失。
- 避免對正在運行的容器進行偷偷摸摸的“快速修復(fù)”——這些更改會在 Kubernetes 重新啟動 Pod 的那一刻消失。
- 擁抱短暫的環(huán)境和動態(tài)擴展。這就是 Kubernetes 最擅長的事情!
16. 對于復(fù)雜的部署,考慮更高級的方法
雖然原生 YAML 清單可以用于較小的 Kubernetes 部署,但隨著項目和團隊的增長,它們往往會變得難以管理。Pulumi為部署自動化提供了一個強大的替代方案,它提供:
- 真正的編程語言: 使用 TypeScript、JavaScript、Python、Go、Java 或 C#用于類型安全、可測試的基礎(chǔ)設(shè)施代碼。
- 跨云靈活性: 使用單個工具管理多個云提供商和 Kubernetes 中的資源。
- 可重用模塊: 將常見模式抽象為可重用組件,減少樣板代碼并防止漂移。
- 強大的工具和生態(tài)系統(tǒng): 從包管理器、IDE 集成和豐富的共享 Pulumi 組件庫中受益。
通過采用 Pulumi,您可以避免處理無數(shù) YAML 文件的復(fù)雜性,并為您的 Kubernetes 基礎(chǔ)設(shè)施獲得更精簡、更易于維護的工作流程。
Kubernetes 就像一把瑞士軍刀:功能強大、用途廣泛,但如果您不小心,也很容易誤用。通過采用這些最佳實踐、聲明式配置、合理的資源分配、強大的安全性、強大的可觀察性和自動部署,您可以使您的集群平穩(wěn)運行。
如果您已經(jīng)以艱難的方式吸取了一些教訓(xùn),那么您并不孤單。但是 Kubernetes 的好處在于,每一次挫折都會讓您獲得更多經(jīng)驗來微調(diào)您的方法。