避雷指南:11個常見 Kubernetes 誤區(qū)詳解
共 6478字,需瀏覽 13分鐘
·
2024-07-29 07:33
鏈接:https://www.cnblogs.com/sealio/p/18119643
簡介
Kubernetes 是一套功能強(qiáng)大的工具,可用于管理自動可擴(kuò)展、高可用性的分布式云原生應(yīng)用程序,但很多人都會犯一些常見錯誤。
在本文中,我們將探討使用 Kubernetes 時最常見的一些誤區(qū),并提供如何避免這些誤區(qū)的提示。
不設(shè)置資源請求
這絕對是最值得關(guān)注的問題之一。CPU 請求通常要么未設(shè)置,要么設(shè)置得很低(這樣我們就能在每個節(jié)點(diǎn)上安裝大量 pod),從而導(dǎo)致節(jié)點(diǎn)超負(fù)荷運(yùn)行。在需求量大的時候,節(jié)點(diǎn)的 CPU 會被充分利用,而我們的工作負(fù)載只能獲得 “它所要求的”,因此 CPU 會被節(jié)流,導(dǎo)致應(yīng)用程序延遲增加、超時等。
以下是一些示例情況,請不要輕易嘗試:
BestEffort
resources: {}
CPU 性能極低
resources:
requests:
cpu: "1m"
另一方面,即使節(jié)點(diǎn)的 CPU 沒有被充分利用,CPU 限制也會不必要地限制 pod 的運(yùn)行,這同樣會導(dǎo)致延遲增加。
關(guān)于 Linux 內(nèi)核中的 CPU CFS 配額和基于 CPU 設(shè)置的 CPU 節(jié)流以及關(guān)閉 CFS 配額的問題,有一個公開的討論, 即 CPU 限制可能導(dǎo)致更多問題,而不是解決問題。
因此,不要過度占用內(nèi)存,并使用保證 QoS(服務(wù)質(zhì)量)將內(nèi)存請求設(shè)置為等于限制,就像下面的例子一樣。
Burstable(更有可能經(jīng)常被 OOMkilled)
resources:
requests:
memory: "128Mi"
cpu: "500m"
limits:
memory: "256Mi"
cpu: 2
Guaranteed
resources:
requests:
memory: "128Mi"
cpu: 2
limits:
memory: "128Mi"
cpu: 2
那么,在設(shè)置資源時,有什么可以幫助您呢?
您可以使用 metrics-server,查看 pod(以及其中的容器)當(dāng)前的 CPU 和內(nèi)存使用情況。您很可能已經(jīng)在運(yùn)行它了。只需運(yùn)行以下命令即可:
kubectl top pods
kubectl top pods --containers
kubectl top nodes
不過,這些顯示的只是當(dāng)前的使用情況。雖然可以大致了解數(shù)字,但您最終還是希望及時看到這些使用指標(biāo)(比如助于解決以下問題:在高峰期、昨天早上等時間段的 CPU 使用率是多少)。為此,您可以使用 Prometheus、DataDog 和其他許多工具。它們只需從指標(biāo)服務(wù)器攝取指標(biāo)并存儲起來,然后就可以查詢和繪制圖表了。
VerticalPodAutoscaler 可以幫助您將這一手動過程自動化——及時查看 CPU/內(nèi)存使用情況,并根據(jù)這些情況重新設(shè)置新的請求和限制。
省略健康檢查
將服務(wù)部署到 Kubernetes 時,健康檢查在維護(hù)服務(wù)方面發(fā)揮著重要作用。在 Kubernetes 環(huán)境中,健康檢查的利用率非常低。通過健康檢查,您可以密切關(guān)注 pod 及其容器的健康狀況。
Kubernetes 有三種主要工具可用于健康檢查:
配置存活檢查(Liveness Check)允許 Kubernetes 檢查應(yīng)用程序是否存活。每個節(jié)點(diǎn)上運(yùn)行的 Kubelet 代理都會使用存活探針來確保容器按預(yù)期運(yùn)行。
就緒檢查 (Readiness Checks) 在容器的整個生命周期內(nèi)運(yùn)行。Kubernetes 使用該探針了解容器何時準(zhǔn)備好接受流量。
啟動探針(Startup Probe)確定容器應(yīng)用何時成功啟動。如果啟動檢查失敗,就會重新啟動 pod。
使用 latest 標(biāo)簽
latest 標(biāo)簽普遍沒有說明性,難以使用。關(guān)于在生產(chǎn)環(huán)境中使用 docker 鏡像:latest 標(biāo)簽,Kubernetes 文檔說得很清楚:
在生產(chǎn)環(huán)境中部署容器時,應(yīng)避免使用 :latest 標(biāo)簽,因?yàn)樗茈y跟蹤運(yùn)行的是哪個版本的鏡像,也很難回滾。
我覺得最近我們已經(jīng)很少看到這種情況了,因?yàn)槲覀冎械暮芏嗳硕冀?jīng)歷過這種情況很多次,所以我們不再使用 :latest 了,每個人都開始有了固定版本。
權(quán)限過高的容器
過度授權(quán)的容器是指被賦予過多權(quán)限的容器,如訪問普通容器無法訪問的資源。這是開發(fā)人員在使用 Kubernetes 時常犯的錯誤,而且會帶來安全風(fēng)險。
例如,在 Docker 容器內(nèi)運(yùn)行 Docker 守護(hù)進(jìn)程就是特權(quán)容器的一個例子,它不一定安全。為了避免這種情況,建議避免為容器賦予 CAP_SYS_ADMIN 能力,因?yàn)樗妓袃?nèi)核漏洞的 25% 以上。
此外,避免賦予容器完全權(quán)限和賦予容器的主機(jī)文件系統(tǒng)權(quán)限也很重要。這意味著可以利用容器替換惡意二進(jìn)制文件,從而入侵整個主機(jī)。
為防止容器權(quán)限過高,必須仔細(xì)配置權(quán)限設(shè)置,切勿以高于所需的權(quán)限運(yùn)行進(jìn)程。并且,使用監(jiān)控和日志來檢測和解決問題也很重要。
缺乏監(jiān)控和日志記錄
Kubernetes 環(huán)境中缺乏監(jiān)控和日志記錄會對其安全性和整體性能造成損害。日志記錄和監(jiān)控不足會給事件調(diào)查和響應(yīng)工作帶來挑戰(zhàn),從而難以有效地發(fā)現(xiàn)和解決問題。
一個常見的陷阱是,由于缺乏相關(guān)日志或指標(biāo),無法找到 Kubernetes 平臺和應(yīng)用程序中的故障點(diǎn)。
要解決這個問題,必須設(shè)置適當(dāng)?shù)谋O(jiān)控和日志工具,如 Prometheus、Grafana、Fluentd 和 Jaeger,以收集、分析和可視化指標(biāo)、日志和跟蹤,深入了解 Kubernetes 環(huán)境的性能和健康狀況。
通過實(shí)施強(qiáng)大的監(jiān)控和日志記錄實(shí)踐,企業(yè)可以有效地關(guān)聯(lián)信息,獲得更深入的見解,并克服與 Kubernetes 環(huán)境的動態(tài)和復(fù)雜性相關(guān)的挑戰(zhàn)。
有對象的默認(rèn)命名空間
對 Kubernetes 中的所有對象使用默認(rèn)命名空間會帶來組織和管理方面的挑戰(zhàn)。default 命名空間是默認(rèn)創(chuàng)建服務(wù)和應(yīng)用程序的地方,除非明確指定,否則它也是活動命名空間。
完全依賴默認(rèn)命名空間會導(dǎo)致集群內(nèi)的不同組件或團(tuán)隊(duì)缺乏隔離和組織。這會導(dǎo)致資源管理、訪問控制和可見性方面的困難。為避免這種情況,建議為不同項(xiàng)目、團(tuán)隊(duì)或應(yīng)用程序創(chuàng)建自定義命名空間,以便在 Kubernetes 集群內(nèi)實(shí)現(xiàn)更好的組織、資源分配和訪問控制。
通過利用多個命名空間,用戶可以有效地劃分和管理資源,提高 Kubernetes 環(huán)境的整體運(yùn)行效率和安全性。
缺少安全配置
部署應(yīng)用程序時,應(yīng)始終牢記安全性。那么,在安全方面有哪些最重要的事項(xiàng)需要考慮呢?例如,使用集群外部可訪問的端點(diǎn)、不保護(hù)機(jī)密、不考慮如何安全運(yùn)行有權(quán)限的容器等。
Kubernetes 安全是任何 Kubernetes 部署不可或缺的一部分。安全挑戰(zhàn)包括:
授權(quán):身份驗(yàn)證和授權(quán)對于控制 Kubernetes 集群中的資源訪問至關(guān)重要。
網(wǎng)絡(luò):Kubernetes 網(wǎng)絡(luò)涉及管理覆蓋網(wǎng)絡(luò)和服務(wù)端點(diǎn),以確保容器之間的流量在集群內(nèi)安全路由。
存儲:集群中存儲的安全包括確保數(shù)據(jù)不會被未經(jīng)授權(quán)的用戶或進(jìn)程訪問,并確保數(shù)據(jù)安全。
Kubernetes API 服務(wù)器有一個 REST 接口,可訪問存儲的所有信息。這意味著,用戶只需向 API 發(fā)送 HTTP 請求,即可訪問 API 中存儲的任何信息。為防止未經(jīng)身份驗(yàn)證的用戶訪問這些數(shù)據(jù),您需要使用用戶名/密碼或基于令牌的身份驗(yàn)證等支持的方法為 API 服務(wù)器配置身份驗(yàn)證。
這不僅關(guān)系到集群本身的安全,還關(guān)系到集群上的機(jī)密和配置的安全。為了保護(hù)集群免受漏洞攻擊,您需要在集群上配置一套安全控制。
使用基于角色的訪問控制(RBAC)來保護(hù) Kubernetes 集群就是這樣一種強(qiáng)大的安全控制:基于角色的訪問控制可用于保護(hù) Kubernetes 集群的安全,方法是根據(jù)分配給用戶的角色限制對資源的訪問。這些角色可以配置為 “管理員”或 “操作員”。
管理員角色擁有完整的訪問權(quán)限,而操作員角色對集群內(nèi)的資源擁有有限的權(quán)限。通過這種方式,我們可以控制和管理訪問集群的任何人。
缺少 poddisruptionbudget
您在 kubernetes 上運(yùn)行生產(chǎn)工作負(fù)載。您的節(jié)點(diǎn)和集群時常需要升級或退役。PodDisruptionBudget (pdb) 是集群管理員和集群用戶之間的服務(wù)保證 API。
請務(wù)必創(chuàng)建 pdb,以避免因節(jié)點(diǎn)耗盡而造成不必要的服務(wù)中斷。
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: db-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: database
這樣, 作為集群用戶,您可以告訴集群管理員,無論您要做什么都希望至少有兩個副本始終可用。
pod 的自我防癱瘓功能
例如,當(dāng)運(yùn)行某個部署的 3 個 pod 副本時,節(jié)點(diǎn)宕機(jī),所有副本也會隨之宕機(jī)。為什么?
這是因?yàn)?,您不能指?Kubernetes 調(diào)度器為您的 pod 強(qiáng)制執(zhí)行 anti-affinite。您必須明確定義它們。
......
labels:
app: db
......
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "app"
operator: In
values:
- db
topologyKey: "kubernetes.io/hostname"
就是這樣。這將確保 pod 被調(diào)度到不同的節(jié)點(diǎn)上(僅在調(diào)度時檢查,而不是在執(zhí)行時,因此 requiredDuringSchedulingIgnoredDuringExecution)。
我們說的是不同節(jié)點(diǎn)名稱上的 podAntiAffinity 而不是不同的可用性區(qū)域,即 topologyKey:"kubernetes.io/hostname。如果您真的需要適當(dāng)?shù)?HA,請深入了解這一主題。
每個 HTTP 服務(wù)的負(fù)載均衡
您的集群中可能有更多的 HTTP 服務(wù),而您希望將這些服務(wù)對外公開。
如果您將 kubernetes 服務(wù)作為 type:LoadBalancer 公開,其控制器(特定于供應(yīng)商)將提供并調(diào)節(jié)外部 LoadBalancer,而這些資源可能會變得昂貴(外部靜態(tài) IPv4 地址、按秒計價......),因?yàn)槟枰獎?chuàng)建很多這樣的資源。
在這種情況下,共享一個外部負(fù)載均衡可能更有意義,您可以將您的服務(wù)作為 type:NodePort 公開?;蛘撸渴痤愃?nbsp;nginx-ingress-controller(或 traefik 或 Istio)的東西,將其作為暴露給外部負(fù)載平衡器的單一 NodePort 端點(diǎn),并根據(jù) kubernetes ingress 資源在集群中路由流量。
集群內(nèi)其他相互對話的(微)服務(wù)可通過 ClusterIP 服務(wù)和開箱即用的 DNS 服務(wù)發(fā)現(xiàn)進(jìn)行對話。
注意:不要使用他們的公共 DNS/IP,因?yàn)檫@可能會影響他們的延遲和云成本。
未感知集群自動擴(kuò)展
在集群中添加和移除節(jié)點(diǎn)時,不應(yīng)考慮一些簡單的指標(biāo),如這些節(jié)點(diǎn)的 CPU 利用率。在調(diào)度 pod 時,您需要根據(jù)大量調(diào)度約束條件(如 pod 和節(jié)點(diǎn)親和性、污點(diǎn)和容忍度、資源請求、QoS 等)來做出決定。如果外部自動調(diào)度器不了解這些約束條件,可能會造成麻煩。
試想一下,有一個新的 pod 需要調(diào)度,但所有可用的 CPU 都被請求了,該 pod 被卡在待定狀態(tài)。外部自動調(diào)節(jié)器會看到當(dāng)前使用的 CPU 平均值(未請求),因此不會擴(kuò)展(不會添加另一個節(jié)點(diǎn))。pod 無法調(diào)度。
向內(nèi)擴(kuò)展(從集群中移除一個節(jié)點(diǎn))總是比較困難。假設(shè)您有一個有狀態(tài)的 pod(附加了持久卷),由于持久卷通常是屬于特定可用性區(qū)域的資源,不會在區(qū)域內(nèi)復(fù)制,因此您自定義的 autoscaler 會移除帶有此 pod 的節(jié)點(diǎn),而調(diào)度器無法將其調(diào)度到其他節(jié)點(diǎn)上,因?yàn)樗艿轿ㄒ粠в谐志么疟P的可用性區(qū)域的限制。pod 再次卡在待處理狀態(tài)。
總結(jié)
總之,Kubernetes 是管理容器化應(yīng)用程序的強(qiáng)大工具,但它也有自己的一系列挑戰(zhàn)。要避免常見錯誤和陷阱,必須密切關(guān)注與 Kubernetes 的交互,并了解它與已部署服務(wù)的交互方式之間的差異。
不要指望一切都能自動運(yùn)行,要投入一些時間讓您的應(yīng)用程序成為云原生的。通過避免這些錯誤,您可以高效地進(jìn)行 Kubernetes 部署,并提高 Kubernetes 環(huán)境的穩(wěn)定性、性能和安全性。
秋招已經(jīng)開始啦,大家如果不做好充足準(zhǔn)備的話,秋招很難找到好工作。
送大家一份就業(yè)大禮包,大家可以突擊一下春招,找個好工作!
