背景與適用場景
在 Kubernetes 中,資源限制(Resource Limits)是 Pod 調(diào)度的核心依據(jù),也是保障集群穩(wěn)定性的關(guān)鍵配置。很多初學(xué)者接觸 Kubernetes 時(shí),最常踩的坑就是資源限制配錯(cuò)了——要么配太大導(dǎo)致資源浪費(fèi)和調(diào)度不均,要么配太小導(dǎo)致 OOMKill 或 CPU Throttling,嚴(yán)重影響業(yè)務(wù)可用性。
本篇聚焦于 CPU 和內(nèi)存的 Request 和 Limit 這兩個(gè)核心配置項(xiàng),解釋它們?cè)?Kubernetes 調(diào)度、QoS、OOMKill 機(jī)制中的具體作用,以及在實(shí)際業(yè)務(wù)中如何合理配置。
適用場景:
部署新應(yīng)用到 Kubernetes 集群,不確定 resource limits 怎么配
應(yīng)用頻繁出現(xiàn) OOMKilled 或 CPU Throttling,需要排查根因
需要優(yōu)化集群資源利用率,減少資源浪費(fèi)
理解 Kubernetes QoS 等級(jí)對(duì) Pod 調(diào)度和驅(qū)逐優(yōu)先級(jí)的影響
核心概念:Request vs Limit
在 Kubernetes 中,每個(gè)容器都可以設(shè)置 CPU 和內(nèi)存的 Request 和 Limit:
apiVersion:v1 kind:Pod spec: containers: -name:app image:nginx:1.24 resources: requests: memory:"256Mi" cpu:"250m" limits: memory:"512Mi" cpu:"500m"
Request:請(qǐng)求的資源量
Request 是容器最少需要的資源量。調(diào)度器(kube-scheduler)在決定把 Pod 調(diào)度到哪臺(tái) Node 時(shí),用的是 Request 值而非實(shí)際使用量。調(diào)度器會(huì)檢查 Node 上的"已分配 Request 總量 + 新 Pod 的 Request"是否超過 Node 的實(shí)際容量。
舉例:
Node 總內(nèi)存: 4GiB Node 上已調(diào)度 Pod 的 memory requests 總和: 3GiB 新 Pod 的 memory request: 512Mi 調(diào)度檢查: 3GiB + 512Mi = 3.512GiB <= 4GiB ?-> 可以調(diào)度
重要:Request 只影響調(diào)度,不影響實(shí)際資源使用。如果容器實(shí)際使用超過 Request,調(diào)度器仍然允許它運(yùn)行,只是 Node 上的"資源使用"會(huì)超過"資源請(qǐng)求"。
Limit:資源的上限
Limit 是容器可以使用的資源上限。當(dāng)容器嘗試使用超過 Limit 的資源時(shí):
內(nèi)存 Limit:容器會(huì)被 OOMKill(Out of Memory Kill),進(jìn)程被強(qiáng)制終止
CPU Limit:容器無法獲取超過 Limit 的 CPU 時(shí)間片,CPU 使用被節(jié)流(Throttling)
Request 和 Limit 的關(guān)系
Request <= Limit(可以相等) CPU: ?可以不相等(通常 Request = Limit,或者 Limit 是 Request 的整數(shù)倍) Memory: 強(qiáng)烈建議 Request = Limit(混用會(huì)導(dǎo)致奇怪的 OOMKill 行為,見后文)
CPU 的 Request 和 Limit
Kubernetes CPU 計(jì)量單位
CPU 的計(jì)量單位是 millicores(毫核),簡稱m。
1 CPU = 1000m 500m = 0.5 CPU 250m = 0.25 CPU 100m = 0.1 CPU
也可以直接寫小數(shù):0.5、1等,Kubernetes 會(huì)自動(dòng)轉(zhuǎn)換為 m。
CPU 是可壓縮資源
CPU 屬于"可壓縮資源"(compressible resources)。當(dāng) Node 上的 CPU 使用緊張時(shí),Kubernetes 可以通過降低容器的 CPU 時(shí)間片來"擠出"更多資源,不會(huì)殺掉容器。容器只是變慢,但不會(huì)停。
但 CPU 有一個(gè)機(jī)制叫CPU Throttling:如果容器達(dá)到了 CPU Limit,Kubernetes 會(huì)限制容器最多只能使用這么多 CPU,導(dǎo)致容器實(shí)際獲得的 CPU 時(shí)間少于它應(yīng)得的。這會(huì)讓容器性能下降。
CPU Throttling 詳解
CPU Throttling 是一個(gè)容易被忽視的性能問題。假設(shè)一個(gè)容器的 CPU Limit 是 500m(0.5 CPU):
Linux CFS(Completely Fair Scheduler)默認(rèn)以 100ms 為周期分配 CPU 時(shí)間片
如果 Limit 是 500m,意味著這個(gè)容器在每個(gè) 100ms 周期內(nèi)最多獲得 50ms 的 CPU 時(shí)間
超過 50ms 的 CPU 使用請(qǐng)求會(huì)被推遲到下一個(gè)周期
這意味著:即使容器"名義上"有 500m 的 CPU,但實(shí)際可能因?yàn)?Throttling 導(dǎo)致響應(yīng)延遲增加。對(duì)于延遲敏感型應(yīng)用(如 Java 服務(wù)),CPU Throttling 可能導(dǎo)致性能嚴(yán)重下降。
減少 CPU Throttling 的方法:
適當(dāng)提高 CPU Limit(如果內(nèi)存也夠用)
使用 Burstable QoS(Request < Limit),讓容器在突發(fā)時(shí)有更多 CPU 可用
調(diào)整 CFS 調(diào)度周期(--cpu-cfs-quota和--cpu-cfs-period),但這需要修改 kubelet 配置
# 查看當(dāng)前 kubelet 的 CPU CFS 配置 ps aux | grep kubelet | grep cpu
內(nèi)存的 Request 和 Limit
內(nèi)存是可壓縮資源嗎?
不是。內(nèi)存是"不可壓縮資源"(non-compressible resources)。一旦容器申請(qǐng)了內(nèi)存,Kubernetes 無法像壓縮 CPU 那樣"回收"內(nèi)存。如果容器試圖使用超過 Limit 的內(nèi)存,會(huì)觸發(fā) OOMKill——容器進(jìn)程被強(qiáng)制殺死。
OOMKill 的機(jī)制
當(dāng) Linux 系統(tǒng)內(nèi)存不足時(shí),OOM Killer 會(huì)根據(jù)進(jìn)程的 oom_score(由 oom_score_adj 和內(nèi)存使用量計(jì)算)選擇一個(gè)進(jìn)程殺掉。在 Kubernetes 環(huán)境中,kubelet 會(huì)為每個(gè)容器設(shè)置 oom_score_adj,具體值由 Pod 的 QoS 等級(jí)決定:
| QoS 等級(jí) | oom_score_adj |
|---|---|
| Guaranteed | -997 |
| Burstable | min(max(2, 1000 - (1000 * memoryRequest / nodeMemory)), 999) |
| BestEffort | 1000 |
數(shù)值越高,越容易被 OOMKill。Guaranteed 的 Pod 的進(jìn)程 oom_score_adj 最低(-997),最難被殺;BestEffort 最高(1000),最先被殺。
Request = Limit 對(duì)內(nèi)存的重要性
強(qiáng)烈建議將內(nèi)存的 Request 和 Limit 設(shè)置為相同的值。原因如下:
當(dāng) Request < Limit 時(shí),Pod 處于 Burstable QoS 等級(jí)。此時(shí)如果 Node 內(nèi)存不足,OOM Killer 會(huì)綜合考慮:
實(shí)際內(nèi)存使用量
Request 值(而非 Limit 值)計(jì)算出的 oom_score
這會(huì)導(dǎo)致一個(gè)反直覺的現(xiàn)象:實(shí)際使用內(nèi)存很少、但 Request 設(shè)置得很高的 Pod,反而更容易被 OOMKill。
例如:
# Pod A resources: requests: memory:"2Gi" limits: memory:"4Gi"# Request < Limit,Burstable # Pod B resources: ??requests: ? ??memory:?"512Mi" ??limits: ? ??memory:?"512Mi"??# Request = Limit,Guaranteed
假設(shè)兩臺(tái) Pod 實(shí)際都只用了 512Mi,Node 內(nèi)存緊張時(shí),Pod A(Burstable)的 oom_score 可能更高,更容易被 OOMKill——即使它的 Request 是 2Gi,它根本沒用那么多。
所以,對(duì)于內(nèi)存,最好讓 Request = Limit,使 Pod 處于 Guaranteed QoS,這樣 oom_score_adj 固定為 -997,最不容易被 OOMKill。
QoS 等級(jí)詳解
Kubernetes 為每個(gè) Pod 自動(dòng)分配一個(gè) QoS(Quality of Service)等級(jí):
| QoS 等級(jí) | 條件 | OOM 優(yōu)先級(jí) | 調(diào)度優(yōu)先級(jí) |
|---|---|---|---|
| Guaranteed | 所有容器都設(shè)置了 CPU 和內(nèi)存的 Request = Limit | 最低(最難殺) | 最高 |
| Burstable | 不滿足 Guaranteed,但至少有一個(gè)容器設(shè)置了 Request | 中等 | 中等 |
| BestEffort | 沒有任何容器設(shè)置 Request 和 Limit | 最高(最先殺) | 最低 |
Guaranteed 優(yōu)先級(jí)的實(shí)際意義
Guaranteed Pod 的調(diào)度優(yōu)先級(jí)最高,OOM 時(shí)最難被殺掉。但這不意味著 Guaranteed Pod 不會(huì)被驅(qū)逐(Eviction)。節(jié)點(diǎn)壓力過大時(shí),kubelet 仍然會(huì)根據(jù) Pod 的 eviction thresholds 驅(qū)逐 Pod,但 Guaranteed Pod 是最后被驅(qū)逐的。
如何查看 Pod 的 QoS 等級(jí)
kubectl get pod-o jsonpath='{.status.qosClass}' kubectl describe pod | grep -E"QoS|Memory|Limit|Request"
不同 QoS 下的 OOMKill 示例
舉一個(gè)實(shí)際場景幫助理解:
Node 有 4Gi 內(nèi)存,已分配給各個(gè) Pod 的 memory requests 總和為 3.8Gi Pod A (Guaranteed): requests: memory=1Gi, limits: memory=1Gi 實(shí)際使用: 800Mi Pod B (Burstable): requests: memory=512Mi, limits: memory=2Gi 實(shí)際使用: 1.5Gi Pod C (BestEffort): 沒有設(shè)置任何 resources 實(shí)際使用: 200Mi 當(dāng) Node 內(nèi)存真的不夠用了(3.8Gi requests + 實(shí)際使用 > 4Gi), OOM Killer 會(huì)優(yōu)先殺掉 Pod C,其次是 Pod B,Pod A 最安全。 但注意:Pod B 雖然請(qǐng)求了 512Mi 但用了 1.5Gi,如果它用了超過 2Gi 就會(huì)直接 OOMKill。
調(diào)度機(jī)制詳解
調(diào)度器如何用 Request 做決策
調(diào)度器調(diào)度 Pod 時(shí),按以下步驟選擇 Node:
過濾(Filtering):遍歷所有 Node,找出滿足 Pod 所有容器 Resource Requests 的 Node(不考慮 Limit)
打分(Scoring):對(duì)過濾通過的 Node 打分,選擇分?jǐn)?shù)最高的
綁定(Binding):將 Pod 綁定到選中的 Node
這意味著:Limit 不影響調(diào)度,只影響實(shí)際運(yùn)行時(shí)行為。
資源超售(Overcommit)
由于 Request < Limit 是常見做法(特別是 Burstable QoS),Node 上的"已分配 Requests 總和"通常會(huì)超過 Node 的實(shí)際容量。這叫"資源超售"。
例如:
Node: 4 CPU cores Pod A: requests.cpu=1, limits.cpu=2 Pod B: requests.cpu=1, limits.cpu=2 Pod C: requests.cpu=1, limits.cpu=2 已分配 requests.cpu = 3(不超過 4,調(diào)度器認(rèn)為 OK) 但如果三個(gè) Pod 都跑滿 CPU(各用 2),實(shí)際需要 6 CPU
資源超售本身不是問題,問題是當(dāng)超售的 Pod 全部需要用到 Limit 時(shí),Node 會(huì)過載。此時(shí) CPU Throttling 會(huì)發(fā)生,內(nèi)存壓力時(shí) OOMKill 也會(huì)發(fā)生。
常用場景的配置建議
場景一:Web 服務(wù)(Nginx、Apache)
apiVersion:apps/v1
kind:Deployment
metadata:
name:nginx-app
spec:
replicas:3
template:
spec:
containers:
-name:nginx
image:nginx:1.24
ports:
-containerPort:80
resources:
requests:
memory:"64Mi" # Nginx 本身內(nèi)存占用很小
cpu:"50m" # 基本只做轉(zhuǎn)發(fā)
limits:
memory:"128Mi" # 給點(diǎn)余量
cpu:"200m"
場景二:Java 應(yīng)用(Spring Boot、Tomcat)
Java 應(yīng)用的特點(diǎn)是啟動(dòng)時(shí)需要較多內(nèi)存(加載類、JIT 編譯),穩(wěn)定運(yùn)行時(shí)內(nèi)存相對(duì)穩(wěn)定,但峰值時(shí)可能需要更多。
apiVersion:apps/v1
kind:Deployment
metadata:
name:java-app
spec:
replicas:2
template:
spec:
containers:
-name:java-app
image:my-java-app:1.0.0
env:
-name:JAVA_OPTS
value:"-Xmx512m -Xms256m"# 明確 JVM 堆內(nèi)存,和 k8s limit 對(duì)應(yīng)
resources:
# Request = Limit,Guaranteed QoS
requests:
memory:"768Mi" # 覆蓋 JVM heap + overhead(類加載、native 等)
cpu:"500m"
limits:
memory:"768Mi"
cpu:"1000m" # CPU 可以適當(dāng)高于 memory
JVM 和容器內(nèi)存配合:JVM 的-Xmx應(yīng)該等于或略小于容器的 memory limit。建議-Xmx設(shè)置為容器 limit 的 75-80%,留出給 native 內(nèi)存、direct buffer、mmap 等非堆內(nèi)存使用。
場景三:Go 應(yīng)用
Go 運(yùn)行時(shí)管理自己的內(nèi)存(GC),對(duì)容器內(nèi)存限制配合較好,但也要注意:
apiVersion:apps/v1
kind:Deployment
metadata:
name:go-app
spec:
replicas:2
template:
spec:
containers:
-name:go-app
image:my-go-app:1.0.0
resources:
requests:
memory:"128Mi"
cpu:"100m"
limits:
# Go 的 GOGC=100 會(huì)在內(nèi)存達(dá)到 limit 時(shí)觸發(fā) GC
# 建議 Go 應(yīng)用的內(nèi)存 limit 足夠,避免頻繁 GC
memory:"512Mi"
cpu:"500m"
env:
# 告訴 Go 運(yùn)行時(shí)可以使用最多多少內(nèi)存
-name:GOMEMLIMIT
value:"400MiB"# GOMEMLIMIT 是 Go 1.19+ 的特性
場景四:數(shù)據(jù)庫(MySQL、PostgreSQL)
數(shù)據(jù)庫通常需要穩(wěn)定、專用的資源,強(qiáng)烈建議 Guaranteed QoS:
apiVersion:apps/v1
kind:StatefulSet
metadata:
name:mysql
spec:
serviceName:mysql
replicas:1
template:
spec:
containers:
-name:mysql
image:mysql:8.0
env:
-name:MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name:mysql-secret
key:root-password
resources:
requests:
memory:"2Gi"
cpu:"1000m"
limits:
# 數(shù)據(jù)庫強(qiáng)烈建議 Request = Limit
memory:"2Gi"
cpu:"2000m"
volumeMounts:
-name:data
mountPath:/var/lib/mysql
場景五:Redis
Redis 是內(nèi)存密集型,對(duì)內(nèi)存 Limit 非常敏感:
apiVersion:apps/v1
kind:StatefulSet
metadata:
name:redis
spec:
replicas:1
template:
spec:
containers:
-name:redis
image:redis:7-alpine
command:["redis-server","--maxmemory","1536mb","--maxmemory-policy","allkeys-lru"]
resources:
requests:
memory:"1536Mi"# 和 redis --maxmemory 對(duì)應(yīng)
cpu:"500m"
limits:
# maxmemory 設(shè)為容器 limit 的 90-95%,留余量給 Redis 自身 overhead
memory:"1536Mi"
cpu:"1000m"
Redis 和容器內(nèi)存 limit 的關(guān)系:如果容器 limit < Redis maxmemory,Redis 可能不知道自己實(shí)際能用多少內(nèi)存;如果容器 limit > Redis maxmemory,則浪費(fèi)了容器層的內(nèi)存隔離。建議兩者對(duì)齊。
監(jiān)控和排查命令
查看 Pod 資源使用情況
# 查看所有 Pod 的資源使用(需要 metrics-server) kubectl top pods --all-namespaces # 查看特定 Pod 的資源使用 kubectl top pod-n # 查看特定 Pod 內(nèi)所有容器的資源使用 kubectl top pod -n --containers
查看 Node 資源分配情況
# 查看 Node 的容量和已分配資源 kubectl describe node| grep -A 10"Allocated resources" # 查看所有 Node 的資源概況 kubectl describe nodes | grep -A 5"Resource" # 更詳細(xì)的 Node 資源視圖 kubectl get nodes -o json | jq'.items[] | {name: .metadata.name, allocatable: .status.allocatable, capacity: .status.capacity}'
檢查 Pod 的 QoS 等級(jí)
kubectl get pods -o custom-columns=NAME:.metadata.name,QOS:.status.qosClass,CPU_REQ:.spec.containers[0].resources.requests.cpu,MEM_REQ:.spec.containers[0].resources.requests.memory
檢查 OOMKill 事件
# 查看 Pod 的 OOMKill 事件 kubectl describe pod-n | grep -E"Last State|Exit Code|OOMKilled" # 查看 Node 級(jí)別的事件 kubectl get events -n --field-selector involvedObject.name= | grep -E"OOM|Kill" # 查看 Node 的 OOMKiller 日志(需要登錄 Node) ssh "dmesg | grep -i 'killed process'"
排查 CPU Throttling
# 查看容器 CPU Throttling 統(tǒng)計(jì)(需要登錄 Node) cat /sys/fs/cgroup/cpu/kubepods/burstable//cpu.stat # 查看某個(gè)容器的 CPU throttling cat /sys/fs/cgroup/cpu/kubepods.slice/ /cpu.stat # 關(guān)鍵指標(biāo):nr_throttled(被節(jié)流的周期數(shù))、throttled_time(被節(jié)流的總時(shí)間 ns)
常見問題與修復(fù)
問題一:Pod 一直處于 Pending 狀態(tài)
現(xiàn)象:kubectl get pods顯示 Pod 一直處于 Pending
原因:沒有任何 Node 的可用資源能滿足 Pod 的 Requests
排查:
kubectl describe pod| grep -A 10"Events:" # 通常會(huì)看到 "insufficient memory" 或 "insufficient cpu" # 檢查 Node 資源狀況 kubectl top nodes kubectl describe nodes | grep -A 5"Allocated resources"
解決:降低 Pod 的 Requests,或者擴(kuò)容 Node,或者清理一些低優(yōu)先級(jí)的 Pod。
問題二:Pod 不斷被 OOMKilled
現(xiàn)象:Pod 啟動(dòng)后一段時(shí)間就被殺掉,kubectl get pods顯示 OOMKilled
排查:
kubectl describe pod| grep"Last State" # 如果 Last State.terminated.reason 是 OOMKilled,說明是被 Linux OOM Killer 殺掉的 # 檢查實(shí)際內(nèi)存使用 kubectl top pod # 檢查 Pod 的 limits 配置 kubectl get pod -o jsonpath='{.spec.containers[0].resources}'
解決:
增加 memory limit(如果是正常業(yè)務(wù)增長)
檢查應(yīng)用是否有內(nèi)存泄漏
對(duì)于 Java 應(yīng)用,確保 JVM -Xmx 和容器 limit 匹配
考慮是否應(yīng)該將 Request 也相應(yīng)提高(但要注意 Request = Limit 的建議)
問題三:應(yīng)用響應(yīng)慢,但 CPU 和內(nèi)存都沒超 limit
可能原因:CPU Throttling
排查:
# 在 Node 上查看 Pod 的 CPU throttling cat /sys/fs/cgroup/cpu/kubepods/burstable//cpu.stat # 關(guān)鍵看 nr_throttled 和 throttled_time # 如果 throttled_time 很大,說明 CPU 被嚴(yán)重限制了
解決:適當(dāng)提高 CPU limit,或者將 CPU Request 和 Limit 設(shè)為相同值(Guaranteed QoS)。
問題四:內(nèi)存使用遠(yuǎn)低于 Request,但 OOMKilled 了
原因:配置了 Request < Limit,Pod 處于 Burstable QoS,OOM Killer 的打分機(jī)制導(dǎo)致這個(gè) Pod 反而更容易被選中殺掉
解決:將內(nèi)存的 Request 和 Limit 設(shè)為相同值,使 Pod 進(jìn)入 Guaranteed QoS。
問題五:多容器 Pod 的資源如何計(jì)算
一個(gè) Pod 可能有多個(gè)容器(sidecar 模式等):
spec: containers: -name:main-app resources: requests: memory:"512Mi" cpu:"250m" limits: memory:"1Gi" cpu:"500m" -name:sidecar resources: requests: memory:"64Mi" cpu:"50m" limits: memory:"128Mi" cpu:"100m"
Pod 的總 Request = 所有容器 Request 之和(512Mi + 64Mi = 576Mi) Pod 的總 Limit = 所有容器 Limit 之和(1Gi + 128Mi = 1.128Gi)
調(diào)度時(shí)按總 Request 分配,OOMKill 時(shí)按單個(gè)容器 Limit 判斷。
LimitRange:給 Namespace 設(shè)置默認(rèn)資源限制
可以在 Namespace 級(jí)別設(shè)置 LimitRange,為沒有設(shè)置資源限制的 Pod 自動(dòng)加上默認(rèn)值:
apiVersion:v1 kind:LimitRange metadata: name:default-limits namespace:my-app spec: limits: # 容器級(jí)別的默認(rèn)限制 -type:Container # 默認(rèn) requests default: cpu:"100m" memory:"128Mi" # 默認(rèn) limits defaultRequest: cpu:"100m" memory:"128Mi" # 最小允許的 requests min: cpu:"10m" memory:"16Mi" # 最大允許的 limits max: cpu:"4" memory:"8Gi" # 最大 limit / 最小 request 的比例(防止 limit 遠(yuǎn)大于 request) maxLimitRequestRatio: cpu:10 memory:10
這樣,部署到my-appnamespace 且沒有設(shè)置 resources 的 Pod,會(huì)自動(dòng)獲得 100m CPU 和 128Mi 內(nèi)存的默認(rèn)值。
ResourceQuota:限制 Namespace 的總資源
除了 LimitRange 限制單個(gè) Pod,還可以設(shè)置 ResourceQuota 限制整個(gè) Namespace 的總資源使用量:
apiVersion:v1 kind:ResourceQuota metadata: name:production-quota namespace:production spec: hard: # 整個(gè) namespace 的 requests 總和 requests.cpu:"10" requests.memory:"20Gi" # 整個(gè) namespace 的 limits 總和 limits.cpu:"20" limits.memory:"40Gi" # Pod 數(shù)量限制 pods:"50"
當(dāng) namespace 的資源使用達(dá)到 quota 后,新的 Pod 將無法創(chuàng)建。
風(fēng)險(xiǎn)提醒
不要不設(shè)置資源限制:沒有 resource limits 的 Pod 處于 BestEffort QoS,在 Node 資源緊張時(shí)會(huì)被最先驅(qū)逐和 OOMKill。
內(nèi)存 limit 不要過大:給一個(gè)實(shí)際只需要 256Mi 的應(yīng)用設(shè)置 4Gi 內(nèi)存 limit,會(huì)導(dǎo)致調(diào)度器認(rèn)為這臺(tái) Node 已經(jīng)被分配了很多內(nèi)存,但實(shí)際上那些內(nèi)存根本沒被用。這會(huì)造成調(diào)度不均和資源浪費(fèi)。
CPU limit 過小會(huì)導(dǎo)致 Throttling:對(duì)于延遲敏感型應(yīng)用,不要把 CPU limit 設(shè)置得太緊。建議先設(shè) Request = Limit,再根據(jù)實(shí)際監(jiān)控?cái)?shù)據(jù)調(diào)整。
混用 Request < Limit 要謹(jǐn)慎:內(nèi)存的 Request < Limit 會(huì)導(dǎo)致 OOMKill 優(yōu)先級(jí)異常。CPU 的 Request < Limit 是可以的(Burstable 場景),但要注意 CPU Throttling 對(duì)延遲敏感應(yīng)用的影響。
生產(chǎn)環(huán)境建議:用kubectl top pods和監(jiān)控工具(Prometheus + Grafana)建立資源使用基線,定期review Pod 的資源實(shí)際使用量,調(diào)整 Request/Limit 使其更準(zhǔn)確。
總結(jié)
Kubernetes 資源限制配置的核心要點(diǎn):
| 配置項(xiàng) | CPU | 內(nèi)存 |
|---|---|---|
| Request 用途 | 調(diào)度依據(jù) | 調(diào)度依據(jù) |
| Limit 用途 | CPU 時(shí)間片上限(超限 Throttling) | 內(nèi)存上限(超限 OOMKill) |
| 建議 | Request = Limit 或 Request < Limit(可壓縮) | 強(qiáng)烈建議 Request = Limit |
| QoS 影響 | Request = Limit → Guaranteed | Request = Limit → Guaranteed |
QoS 等級(jí)與 OOMKill 優(yōu)先級(jí)的對(duì)應(yīng)關(guān)系:
Guaranteed (最難殺) → Burstable → BestEffort (最先殺)
排查資源相關(guān)問題的順序:
1. kubectl top pod 查看實(shí)際使用量 2. 檢查 Pod 的 requests/limits 配置是否合理 3. 檢查 Pod 的 QoS 等級(jí)(Guaranteed/Burstable/BestEffort) 4. 登錄 Node 查看 cgroup 統(tǒng)計(jì)或 dmesg 看 OOM 事件 5. 調(diào)整 requests/limits 或擴(kuò)容
資源限制配置沒有一勞永逸的標(biāo)準(zhǔn)值,需要結(jié)合業(yè)務(wù)特點(diǎn)(計(jì)算密集型 vs 內(nèi)存密集型 vs IO 密集型)和實(shí)際監(jiān)控?cái)?shù)據(jù)來持續(xù)調(diào)整。監(jiān)控?cái)?shù)據(jù)是優(yōu)化資源限制的最終依據(jù)。
-
cpu
+關(guān)注
關(guān)注
68文章
11351瀏覽量
226169 -
內(nèi)存
+關(guān)注
關(guān)注
9文章
3244瀏覽量
76542 -
kubernetes
+關(guān)注
關(guān)注
0文章
279瀏覽量
9539
原文標(biāo)題:K8s 資源限制怎么配?CPU 和內(nèi)存 Limit 別亂寫
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
Kubernetes的Device Plugin設(shè)計(jì)解讀
Kubernetes之路 1 - Java應(yīng)用資源限制的迷思
Kubernetes之路 2 - 利用LXCFS提升容器資源可見性
阿里云容器Kubernetes監(jiān)控(一) - 資源監(jiān)控
阿里云容器Kubernetes監(jiān)控(一) - 資源監(jiān)控
阿里云容器Kubernetes監(jiān)控(一) - 資源監(jiān)控
再次升級(jí)!阿里云Kubernetes日志解決方案
Kubernetes API詳解
如何解決Kubernetes中部署故障及技巧
深入研究Kubernetes調(diào)度
Kubernetes是如何解決資源拓?fù)涓兄{(diào)度的呢
基于Kubernetes實(shí)現(xiàn)CI/CD配置的流程
配置Kubernetes中Pod使用代理的兩種常見方式
Kubernetes資源限制怎么配置
評(píng)論