徐公子 發表於 2025-5-25 13:18:00

K8s新手系列之为Pod中的容器分配内存和CPU资源

<h2 id="概述">概述</h2>
<p>官方文档:</p>
<ul>
<li>为容器和 Pod 分配内存资源</li>
<li>为容器和 Pods 分配 CPU 资源</li>
<li>分配 Pod 级别 CPU 和内存资源</li>
</ul>
<p>在生产环境中,我们创建Pod时需要限制其相关的资源,核心目的是实现资源的合理管理、隔离和保障,具体原因如下:</p>
<ul>
<li>
<p>资源隔离与稳定性保障</p>
<ul>
<li>
<p>防止资源竞争:多个容器或 Pod 共享节点资源时,若不限制资源使用,可能导致 “资源抢占” 问题。例如:<br>
1、某个高负载容器占用节点全部 CPU,导致其他容器因资源不足而卡顿或崩溃。<br>
2、内存使用无限制可能引发节点 OOM(Out of Memory),导致 K8s 强制杀死进程甚至节点宕机。</p>
</li>
<li>
<p>确保服务可用性:通过设置资源下限(Request),保证关键应用至少获得必要的资源(如最低 CPU 和内存),避免因资源不足导致服务中断。</p>
</li>
</ul>
</li>
<li>
<p>性能优化与可预测性</p>
<ul>
<li>限制资源上限(Limit):为高负载容器设置 CPU / 内存上限,避免其无节制消耗资源,影响节点上的其他服务(如 K8s 系统组件)。</li>
<li>资源可预测性:明确资源配额后,可通过监控和自动扩缩容(如 HPA)提前规划资源,确保应用在流量波动时保持稳定性能。</li>
</ul>
</li>
<li>
<p>集群资源高效利用</p>
<ul>
<li>调度优化:K8s 调度器(Scheduler)根据 Pod 的资源请求(Request)进行节点选择,确保资源均衡分配,避免节点过载或闲置。</li>
</ul>
</li>
</ul>
<h2 id="k8s资源分配的核心概念">K8s资源分配的核心概念</h2>
<p>K8s 通过<code>资源请求(Request)和资源限制(Limit)</code>管理 Pod或容器的资源使用,两者的区别如下:</p>
<ul>
<li>Request:容器正常运行所需的最小资源,用于调度时的节点资源匹配。</li>
<li>limit:容器允许使用的最大资源,超过时会被 K8s 限制(CPU)或强制终止(内存)。</li>
</ul>
<p>说明:</p>
<ul>
<li>CPU 单位:以核心(Core)为单位,支持小数(如0.5表示半个核心)或毫核(m,如100m=0.1 核心)。</li>
<li>内存单位:支持字节(Byte)或常见单位(如1Gi=1024^3 字节,1Mi=1024^2 字节,注意与 GB/MB 的区别)。</li>
</ul>
<h2 id="实战案例-为pod的容器设置内存和cpu">实战案例-为Pod的容器设置内存和CPU</h2>
<p>示例:</p>
<pre><code># 定义资源清单文件
# cat cpu-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
    app: nginx
spec:
containers:
- name: nginx-container
    image: nginx:latest
    resources:
      requests:
      # 容器启动时请求的最小内存
      memory: "100Mi"
      # 容器启动时请求的最小 CPU (0.5 核心)
      cpu: "300m"
      #也可以这样
      #cpu: "0.5"
      limits:
      # 容器允许使用的最大内存
      memory: "200Mi"
      # 容器允许使用的最大 CPU (0.5 核心)
      cpu: "500m
# kubectl apply -f cpu-pod.yaml
pod/nginx-pod created
# 查看pod
# kubectl get po nginx-pod -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP                NODE   NOMINATED NODE   READINESS GATES
nginx-pod   1/1   Running   0          12s   100.117.144.170   node01   &lt;none&gt;         &lt;none&gt;
</code></pre>
<p>查看一下Pod的资源分配</p>
<pre><code># 查看详细信息
# kubectl describe po nginx-pod | grep -A 2 -E 'Limits|Requests'
    Limits:
      cpu:   500m
      memory:200Mi
    Requests:
      cpu:      300m
      memory:   100Mi
</code></pre>
<h2 id="当pod创建时请求的资源负载超出节点资源会发生什么">当Pod创建时请求的资源负载超出节点资源,会发生什么?</h2>
<p>重新创建一个Pod:</p>
<pre><code># cat cpu-pod-01.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod-01
labels:
    app: nginx
spec:
containers:
- name: nginx-container
    image: nginx:latest
    resources:
      requests:
      # 容器启动时请求的最小内存,设置为50G
      memory: "50Gi"
      # 容器启动时请求的最小 CPU,设置为50核心
      cpu: "50"
      #也可以这样
      #cpu: "0.5"
      limits:
      # 容器允许使用的最大内存,设置为50G
      memory: "200Gi"
      # 容器允许使用的最大 CPU,设置为50核心
      cpu: "50"

# kubectl apply -f cpu-pod-01.yaml
pod/nginx-pod-01 created

# 查看Pod,发现处于Pending状态
# kubectl get po nginx-pod-01 -o wide
NAME         READY   STATUS    RESTARTS   AGE   IP       NODE   NOMINATED NODE   READINESS GATES
nginx-pod-01   0/1   Pending   0          11s   &lt;none&gt;   &lt;none&gt;   &lt;none&gt;         &lt;none&gt;
</code></pre>
<p>经过上述的验证,发现当Pod的资源请求超出节点的资源时,Pod会处于Pending状态</p>
<pre><code># 查看详细信息
# kubectl describe po nginx-pod-01
Name:             nginx-pod-01
#...
Status:         Pending
IP:
IPs:            &lt;none&gt;
Containers:
nginx-container:
    Image:      nginx:latest
    Port:       &lt;none&gt;
    Host Port:&lt;none&gt;
    Limits:
      cpu:   50
      memory:200Gi
    Requests:
      cpu:      50
      memory:   50Gi
# ... 省略万字
Events:
Type   Reason            Age    From               Message
----   ------            ----   ----               -------
WarningFailedScheduling2m42sdefault-scheduler0/3 nodes are available: 1 Insufficient cpu, 1 Insufficient memory, 1 node(s) had untolerated taint {app: }, 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }. preemption: 0/3 nodes are available: 1 No preemption victims found for incoming pod, 2 Preemption is not helpful for scheduling..
</code></pre>
<h2 id="如何修改指定pod的资源限制">如何修改指定Pod的资源限制</h2>
<h3 id="方式一直接修改其资源清单文件">方式一:直接修改其资源清单文件</h3>
<p>编辑对应的资源文件,重新应用即可</p>
<h3 id="方式二使用kubectl-edit命令进行修改">方式二:使用<code>kubectl edit</code>命令进行修改</h3>
<p>直接使用<code>kubectl edit</code>命令进行修改</p>
<h2 id="注意事项">注意事项</h2>
<ul>
<li>
<p>如果为Pod设置了CPU和内存限制,当Pod运行中的资源负载超出了限制,那么Pod的状态会发生OOM,kubelet会重启当前的Pod</p>
</li>
<li>
<p>如果你为容器指定了 CPU 限制值但未为其设置 CPU 请求,Kubernetes 会自动为其 设置与 CPU 限制相同的 CPU 请求值。</p>
</li>
<li>
<p>如果你为容器指定了 memory 限制值但未为其设置 memory 请求,Kubernetes 会自动为其 设置与 memory 限制相同的 memory 请求值。</p>
</li>
<li>
<p>如果没有为Pod设置 CPU 和 memory 限制,那么Pod极有可能会占满节点的资源</p>
</li>
</ul>


</div>
<div id="MySignature" role="contentinfo">
    <p>本文来自博客园,作者:huangSir-devops,转载请注明原文链接:https://www.cnblogs.com/huangSir-devops/p/18859112,微信Vac6666666,欢迎交流</p><br><br>
来源:https://www.cnblogs.com/huangSir-devops/p/18859112
頁: [1]
查看完整版本: K8s新手系列之为Pod中的容器分配内存和CPU资源