kubernetes cpu限制参数说明

 

 

 

 

 

 

docker CPU限制参数

Option

Description

--cpus=<value>

Specify how much of the available CPU resources a container can use. For instance, if the host machine has two CPUs and you set --cpus="1.5", the container is guaranteed at most one and a half of the CPUs. This is the equivalent of setting --cpu-period="100000" and --cpu-quota="150000". Available in Docker 1.13 and higher.

--cpu-period=<value>

Specify the CPU CFS scheduler period, which is used alongside--cpu-quota. Defaults to 100 micro-seconds. Most users do not change this from the default. If you use Docker 1.13 or higher, use --cpusinstead.

--cpu-quota=<value>

Impose a CPU CFS quota on the container. The number of microseconds per --cpu-period that the container is limited to before throttled. As such acting as the effective ceiling. If you use Docker 1.13 or higher, use --cpus instead.

--cpuset-cpus

Limit the specific CPUs or cores a container can use. A comma-separated list or hyphen-separated range of CPUs a container can use, if you have more than one CPU. The first CPU is numbered 0. A valid value might be 0-3 (to use the first, second, third, and fourth CPU) or 1,3 (to use the second and fourth CPU).

--cpu-shares

Set this flag to a value greater or less than the default of 1024 to increase or reduce the container’s weight, and give it access to a greater or lesser proportion of the host machine’s CPU cycles. This is only enforced when CPU cycles are constrained. When plenty of CPU cycles are available, all containers use as much CPU as they need. In that way, this is a soft limit. --cpu-shares does not prevent containers from being scheduled in swarm mode. It prioritizes container CPU resources for the available CPU cycles. It does not guarantee or reserve any specific CPU access.

①   --cpus指示容器可以使用的CPU数量。改参数指定的是百分比,并不是具体的个数。比如:主机有4个逻辑CPU,限制容器—cpus=2,那么该容器最多可以使用的CPU时间是200%,但是4个CPU分配的时间可能是每个CPU各50%,而不一定是有其中2个CPU使用100%,而另2个CPU使用0%。

--cpus是docker 1.13之后才出来的参数,目的是替代--cpu-period和--cpu-quota两个参数,从而使配置更简单。

②   --cpu-period表示的是设置CPU时间周期,默认值是100000,单位是us,即0.1s。

③   --cpu-quota指示容器可以使用的最大的CPU时间,配合--cpu-period值使用。如果—cpu-quota=200000,即0.2s。那就是说在0.1s周期内改容器可以使用0.2s的CPU时间,显然1个CPU是无法满足要求的,需要至少2个CPU才能满足。

④   --cpuset-cpus设置容器具体可以使用哪些个CPU。如--cpuset-cpus=”0,1,2”或者--cpuset-cpus=”0-2”,则容器会使用第0-2个CPU。

⑤   --cpu-shares,容器使用CPU的权重,默认值是1024,数值越大权重越大。该参数仅当有多个容器竞争同一个CPU时生效。对于单核CPU,如果容器A设置为--cpu-shares=2048,容器B设置为--cpus-shres=1024,仅当两个容器需要使用的CPU时间超过整个CPU周期的时候,容器A会被分配66%的CPU时间,容器B被分配33%的CPU时间,大约是2:1;对于多核CPU,仅当多个容器竞争同一个CPU的时候该值生效。

kubernetes对CPU限制

第一种:资源对象LimitRange限制POD和Container的资源

apiVersion: v1
kind: LimitRange
metadata:
  name: mylimits
spec:
  limits:
  - max:
      cpu: "2"
      memory: 1Gi
    min:
      cpu: 200m
      memory: 6Mi
    type: Pod

  - default:
      cpu: 300m
      memory: 200Mi
    defaultRequest:
      cpu: 200m
      memory: 100Mi
    max:
      cpu: "2"
      memory: 1Gi
    min:
      cpu: 100m
      memory: 3Mi
type: Container

第二种:定义pod时候限制资源

spec:
  containers:
  - image: gcr.io/google_containers/serve_hostname
   imagePullPolicy: Always
   name: kubernetes-serve-hostname
   resources:
     limits:
       cpu: "1"
       memory: 512Mi
     requests:
       cpu: "1"
       memory: 512Mi

如果两者都配置?

先匹配pod里的,再匹配namespace里。

有些时候, 我们大部分容器遵循一个规则就好, 但有一小部分有特殊需求, 这个时候, 小部分的就需要单独在容器的配置文件中指定. 这里有一点要注意的是, 单独在容器中配置的参数是不能大于指定的k8s资源限制, 否则会报错, 容器无法启动

PS: 对于一些java项目, 必须设置java虚拟机的参数, 而且这个参数不能大于容器设置的限定值, 否则容器会因为内存过大不停的重启

 

其中:

limits.cpu  <==>  --cpu-quota         # docker inspect中的CpuQuota值

requests.cpu  <==>  --cpu-shares     # docker inspect中的CpuShares值

实验对比

测试工具stress介绍

root@ustress-77b658748b-7856l:/# stress --help

`stress' imposes certain types of compute stress on your system

 

Usage: stress [OPTION [ARG]] ...

 -?, --help         show this help statement

     --version      show version statement

 -v, --verbose      be verbose

 -q, --quiet        be quiet

 -n, --dry-run      show what would have been done

 -t, --timeout N    timeout after N seconds

     --backoff N    wait factor of N microseconds before work starts

 -c, --cpu N        spawn N workers spinning on sqrt()  #启动N个进程,每个进程最多占满一个CPU

 -i, --io N         spawn N workers spinning on sync()

 -m, --vm N         spawn N workers spinning on malloc()/free()

     --vm-bytes B   malloc B bytes per vm worker (default is 256MB)

     --vm-stride B  touch a byte every B bytes (default is 4096)

     --vm-hang N    sleep N secs before free (default none, 0 is inf)

     --vm-keep      redirty memory instead of freeing and reallocating

 -d, --hdd N        spawn N workers spinning on write()/unlink()

     --hdd-bytes B  write B bytes per hdd worker (default is 1GB)

 

Example: stress --cpu 8 --io 4 --vm 2 --vm-bytes 128M --timeout 10s

 

Note: Numbers may be suffixed with s,m,h,d,y (time) or B,K,M,G (size).

创建一个测试镜像

FROM ubuntu:latest

RUN apt-get update && \

        apt-get install stress

 

docker build -t reg.99bill.com/99bill/ustress .

创建一个kubernetes中deployment对象

apiVersion: apps/v1

kind: Deployment

metadata:

  labels:

    appname: ustress

    version: 0.0.6

  name: ustress

  namespace: default

spec:

  replicas: 1

  selector:

    matchLabels:

      appname: ustress

  template:

    metadata:

      labels:

        appname: ustress

        version: 0.0.6

    spec:

      containers:

      - image: reg.99bill.com/99bill/u-stress:latest

        name: ustress

        command: ['sh', '-c', 'stress -c 4']

        resources:

          limits:

            cpu: 2   #实验修改值

            memory: 1G

          requests:

            cpu: 1   #实验修改值

            memory: 500M

      terminationGracePeriodSeconds: 0

      nodeName: 192.168.112.10

      nodeSelector:

注:

①   command: ['sh', '-c', 'stress -c 4'] 表示开启4个占用CPU的stress进程

②   limits.cpu: 2 对应docker中"CpuQuota": 200000,  "CpuPeriod": 100000默认值

③   requests.cpu:1对应docker中"CpuShares": 1024,

测试一:

limits.cpu: 4

requests.cpu: 0.5

 

结果验证:

1. 查看docker容器参数值:

docker inspect e22896246184

 

512 = 0.5 * 1024

400000 = 4 * 100000

2. docker stats查看容器CPU使用率

由于设置了CPUQuota是CpuPeriod的4倍,所以容器可以使用400% CPU

3. 使用top查看进程与CPU

使用top命令查看4个stress进程,每个占用100% CPU,总400%,可以看到有4个CPU被跑满。

实验二:

limits.cpu: 6

requests.cpu: 0.5

1. 查看docker容器参数值:

 

512 = 0.5 * 1024

600000 = 6 * 100000

2. docker stats查看容器CPU使用率

容器可以使用600%的CPU,现在只用400%

3. 使用top查看进程与CPU

实验三:

limits.cpu: 1

requests.cpu: 0.5

1. 查看docker容器参数值:

docker inspect e22896246184

 

512 = 0.5 * 1024

100000 = 1 * 100000

2. docker stats查看容器CPU使用率

使用时间等于CpuPeriod,占用100%

3. 使用top查看进程与CPU

从下图可以看到,有4个CPU分别使用25%,加起来是100%。所以limits.cpu:1并不一定表示容器只会占用1个CPU,而表示的是容器最多可以使用的CPU时间的比例。

实验四:

limits.cpu: 0.5

requests.cpu: 0.5

1. 查看docker容器参数值

2. docker stats查看容器CPU使用率

3. 使用top查看进程与CPU

 

转载于:https://www.cnblogs.com/yehaifeng/p/9596399.html

<think>我们正在为Spring Boot应用配置Kubernetes资源参数(requests和limits),重点在于内存和CPU的优化配置。参考之前的讨论,我们需要考虑JVM内存管理特性(特别是堆内存)与Kubernetes资源管理的协同。 关键点: 1. JVM堆内存设置(-Xms和-Xmx)必须与容器内存限制(limits)协调,避免OOMKill。 2. 需要预留非堆内存(元空间、线程栈、直接内存等)和JVM自身开销。 3. CPU requests和limits的设置会影响JVM的垃圾回收和线程调度。 步骤: 一、内存配置优化 根据之前的公式: 容器总内存 = 堆内存 + 非堆内存 + JVM开销 建议: 1. 设置堆内存(-Xmx)为容器内存limits的70%~80%,例如limits为4Gi,则-Xmx设为3Gi(即3072m)。 2. 预留非堆内存: - 元空间(-XX:MaxMetaspaceSize):通常设置为256m~512m(根据应用类加载情况调整) - 线程栈(-Xss):每个线程约1MB,根据最大线程数估算(比如200个线程则需200MB) - 直接内存(-XX:MaxDirectMemorySize):如果使用NIO,需要单独设置,通常与堆大小相当或更小 - JVM开销:一般预留堆内存的10%~20% 3. 容器内存requests应至少为:-Xmx + MaxMetaspaceSize + (线程数 * Xss) + 缓冲(建议20%) 二、CPU配置优化 1. CPU requests:设置一个保证值,确保Pod有足够的CPU资源启动和基本运行。对于Spring Boot应用,通常0.5~1个核(500m~1000m)是合理的起点。 2. CPU limits:设置一个上限,防止应用占用过多CPU。注意:设置过低的limits可能导致应用性能下降(例如GC线程被限制)。建议根据压力测试结果调整。 三、配置示例 假设一个中等规模的Spring Boot应用: - 预期最大堆内存:2Gi - 线程数:200(每个线程1MB,共200MB) - 元空间:300MB - JVM开销:堆内存的15%(约300MB) - 总内存需求:2Gi + 0.3Gi + 0.2Gi + 0.3Gi = 2.8Gi(加上缓冲,取3Gi) 则Kubernetes配置如下: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: spring-boot-app spec: template: spec: containers: - name: app image: spring-boot-app:latest env: - name: JAVA_OPTS value: "-Xms2g -Xmx2g -XX:MaxMetaspaceSize=300m -XX:MaxDirectMemorySize=1g -Xss1m" resources: requests: memory: "3Gi" cpu: "1000m" # 1核 limits: memory: "4Gi" # 比实际需求多1Gi缓冲,防止突发或监控不全 cpu: "2000m" # 2核 readinessProbe: # 就绪探针 httpGet: path: /actuator/health port: 8080 initialDelaySeconds: 20 periodSeconds: 5 livenessProbe: # 存活探针 httpGet: path: /actuator/health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 ``` 注意: - 使用`-XX:+UseContainerSupport`(JDK 8u191+默认开启)让JVM自动适应容器内存限制[^1]。 - 通过Spring Boot Actuator提供健康检查端点(/actuator/health)[^4]。 四、调优工具与监控 1. 使用JVM内置工具(如jcmd, jstat)监控堆内存和GC情况。 2. 通过Prometheus+Grafana监控容器资源使用情况(如内存、CPU)和JVM指标(如GC时间、堆使用率)。 3. 定期压力测试,调整参数。 五、常见问题规避 - OOMKill:确保容器内存limits大于JVM总内存需求(包括堆外内存)。 - CPU Throttling:如果GC时间变长,检查CPU limits是否足够(垃圾收集是CPU密集型操作)。 - 启动缓慢:如果应用启动时加载类较多,可以适当增加CPU requests,避免启动阶段被限制。 六、进阶建议 - 使用Vertical Pod Autoscaler(VPA)自动调整requests和limits,但注意VPA在更新时会导致Pod重启。 - 对于内存敏感型应用,考虑使用ZGC或Shenandoah垃圾收集器以减少停顿时间。 相关问题: 1. 如何监控Spring Boot应用在Kubernetes中的垃圾回收行为? 2. 如何为Spring Boot应用配置合适的Kubernetes存活探针和就绪探针? 3. Spring Boot应用在Kubernetes中如何优雅关闭? 4. 如何通过JVM参数优化Spring Boot应用在容器中的启动速度? 通过以上配置,可以显著降低Spring Boot应用在Kubernetes中因资源问题导致的故障率[^2][^4]。</think>### 为 Spring Boot 应用配置 Kubernetes 资源参数的最佳实践 结合 JVM 特性和 Kubernetes 资源管理机制,以下是经过生产验证的配置策略: --- #### 一、内存配置核心公式 **容器总内存需求**: $$ \text{requests} = \text{堆内存}(-Xmx) + \text{非堆内存} + \text{安全缓冲} $$ $$ \text{limits} = \text{requests} \times 1.3 $$ **关键参数关系**: ```yaml -Xmx = limits × 0.7 # 堆内存占 limits 的 70% requests = -Xmx + 300Mi # 增加非堆内存预留 limits = requests × 1.3 # 允许 30% 突发缓冲 ``` > **示例计算**: > 若目标堆内存 `-Xmx=2Gi`,则: > - `requests = 2Gi + 300Mi = 2.3Gi` > - `limits = 2.3Gi × 1.3 ≈ 3Gi` --- #### 二、完整配置模板 ```yaml # deployment.yaml apiVersion: apps/v1 kind: Deployment spec: template: spec: containers: - name: spring-boot-app image: your-image:latest env: - name: JAVA_TOOL_OPTIONS # 关键 JVM 参数 value: > -Xms1.5g -Xmx2g -XX:MaxMetaspaceSize=256m -XX:ReservedCodeCacheSize=128m -XX:+UseContainerSupport # 必须启用[^1] -XX:MaxRAMPercentage=70.0 resources: requests: memory: "2.3Gi" # -Xmx(2G) + 元空间(256M) + 缓冲(44M) cpu: "500m" # 初始 0.5 核 limits: memory: "3Gi" # 允许短暂超限 cpu: "2000m" # 突发至 2 核 livenessProbe: # 健康检查[^4] httpGet: path: /actuator/health/liveness port: 8080 initialDelaySeconds: 45 readinessProbe: httpGet: path: /actuator/health/readiness port: 8080 ``` --- #### 三、配置原则详解 1. **堆内存** (`-Xmx`) - 设置为 `limits` 的 60-70%,避免超过容器限制触发 OOMKill - 初始堆 (`-Xms`) 设为 `-Xmx` 的 75%,减少动态扩容开销 2. **非堆内存预留** | 组件 | 推荐值 | Kubernetes 对应 | |---------------------|-------------|-----------------| | 元空间 (Metaspace) | 256-512 MiB | 包含在 requests | | 线程栈 (Xss) | 1MB/线程 | 按最大线程预留 | | 代码缓存 (CodeCache)| 128-256 MiB | 包含在 requests | | JVM 自身开销 | 100-200 MiB | 安全缓冲 | 3. **CPU 设置** - `requests.cpu`: 保证基本吞吐量 (建议 0.5-1 核) - `limits.cpu`: 允许突发性能 (建议 2-4 核),避免 GC 线程被限制 --- #### 四、调优诊断工具 1. **内存分析**: ```bash # 查看堆内存分布 kubectl exec <pod> -- jcmd 1 GC.heap_info # 监控元空间 kubectl exec <pod> -- jstat -gcmetacapacity 1 ``` 2. **OOM 预防检查**: - 当容器内存 > `limits` → 触发 **OOMKill** - 当堆内存 > `-Xmx` → 触发 **Heap OOM** - 当元空间 > `MaxMetaspaceSize` → 触发 **Metaspace OOM** 3. **监控方案**: - 通过 [Prometheus JMX Exporter](https://github.com/prometheus/jmx_exporter) 采集指标 - Grafana 仪表盘监控:堆内存、GC 时间、线程数、CPU 利用率 --- #### 五、生产环境经验 1. **启动参数优化**: ```bash # JDK 11+ 推荐 -XX:+UseZGC -XX:ZCollectionInterval=5 # 低延迟 GC -XX:+AlwaysPreTouch # 启动时预分配内存 ``` 2. **滚动更新策略**: ```yaml strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 0 # 保证零宕机更新 ``` 3. **资源自动伸缩**: ```yaml # 配合 HPA (基于 CPU/Memory) metrics: - type: Resource resource: name: memory target: type: Utilization averageUtilization: 70 ``` --- ### 典型问题规避 | 故障现象 | 原因 | 解决方案 | |------------------------|-------------------------------|------------------------------| | 容器反复重启 | 内存 limits 接近实际使用峰值 | 增加 limits 缓冲 (×1.3) | | Full GC 时间过长 | CPU limits 限制 GC 线程 | 提高 CPU limits 或切 ZGC | | 应用启动失败 | requests 内存不足加载类 | 增加 requests 至 -Xms × 1.2 | | 线程创建失败 | 未预留足够线程栈空间 | 预留 `最大线程数 × 1.5MB` | > 最佳实践:通过 **压力测试** (如 JMeter) 确定 `-Xmx` 基线,再按公式推导资源参数[^2]。 --- ### 相关问题 1. 如何为 Spring Boot Actuator 配置 Kubernetes 存活探针和就绪探针?[^4] 2. 在 Kubernetes 中如何优雅关闭 Spring Boot 应用? 3. Spring Boot 应用如何通过 ConfigMap 管理不同环境的配置?[^1] 4. 如何选择 Spring Cloud 与 Kubernetes 原生服务治理方案?[^3][^5]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值