一次偶然设置虚拟内存由于设置过大导致系统重启后蓝屏,进入无限系统修复界面,但怎么修复都无法正常进入系统,修复过程如下:
首先得有个Ghost 系统U盘,制作方法百度。
然后开机进入U盘引导,进入Ghost系统
① 桌面→更多工具→设置虚拟内存→初始大小500最大值设置成和物理内存一致即可
② 桌面→修复系统引导
③ 重启进入系统,重点:然后再重新设置一下虚拟内存。
Pod资源限制
备注:CPU单位换算:100m CPU,100 milliCPU 和 0.1 CPU 都相同;精度不能超过 1m。1000m CPU = 1 CPU。
官网地址:
1 https://kubernetes.io/zh/docs/tasks/configure-pod-container/assign-cpu-resource/2 https://kubernetes.io/zh/docs/tasks/configure-pod-container/assign-memory-resource/
Kubernetes对资源的限制实际上是通过cgroup来控制的,cgroup是容器的一组用来控制内核如何运行进程的相关属性集合。针对内存、CPU和各种设备都有对应的cgroup。
默认情况下,Pod运行没有CPU和内存的限额。这意味着系统中的任何Pod将能够像执行Pod所在节点机器一样,可以消耗足够多的CPU和内存。一般会针对某些应用的Pod资源进行资源限制,这个资源限制是通过resources的requests【要分配的资源】和limits【最大使用资源】来实现的。
CPU资源限制示例
1 # cat cpu-request-limit.yaml 2 apiVersion: v1 3 kind: Pod 4 metadata: 5 name: cpu-demo 6 namespace: cpu-example 7 spec: 8 containers: 9 - name: cpu-demo-ctr10 image: vish/stress11 resources:12 limits:13 cpu: "1"14 requests:15 cpu: "0.5"16 args:17 - -cpus18 - "2"
配置文件的 args 部分提供了容器启动时的参数。-cpus “2”参数告诉容器尝试使用 2 个 CPU。
内存资源限制示例
1 # memory-request-limit.yaml 2 apiVersion: v1 3 kind: Pod 4 metadata: 5 name: memory-demo 6 namespace: mem-example 7 spec: 8 containers: 9 - name: memory-demo-ctr10 image: polinux/stress11 resources:12 limits:13 memory: "200Mi"14 requests:15 memory: "100Mi"16 command: ["stress"]17 args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
配置文件的 args 部分提供了容器启动时的参数。 "--vm-bytes", "150M" 参数告知容器尝试分配 150 MiB 内存。不允许args中的启动内存大于limits限制内存。
namespace资源限制
备注:CPU单位换算:100m CPU,100 milliCPU 和 0.1 CPU 都相同;精度不能超过 1m。1000m CPU = 1 CPU。
官网地址:
https://kubernetes.io/zh/docs/tasks/administer-cluster/manage-resources/
为命名空间配置内存和 CPU 配额
怎么为命名空间设置容器可用的内存和 CPU 总量。你可以通过 ResourceQuota 对象设置配额,使用 ResourceQuota 限制命名空间中所有容器的内存请求总量、内存限制总量、CPU 请求总量和CPU 限制总量。
如果你想对单个容器而不是所有容器进行限制,就请使用 LimitRange。
示例:
1 # cat quota-mem-cpu.yaml 2 apiVersion: v1 3 kind: ResourceQuota 4 metadata: 5 name: mem-cpu-demo 6 spec: 7 hard: 8 requests.cpu: "1" 9 requests.memory: 1Gi10 limits.cpu: "2"11 limits.memory: 2Gi
应用如下【命名空间quota-mem-cpu-example已提前创建完毕】:
kubectl create -f quota-mem-cpu.yaml --namespace=quota-mem-cpu-example
查看 ResourceQuota 详情:
kubectl get resourcequota mem-cpu-demo --namespace=quota-mem-cpu-example --output=yaml
输出部分结果如下:
1 spec: 2 hard: 3 limits.cpu: "2" 4 limits.memory: 2Gi 5 requests.cpu: "1" 6 requests.memory: 1Gi 7 status: 8 hard: 9 limits.cpu: "2"10 limits.memory: 2Gi11 requests.cpu: "1"12 requests.memory: 1Gi13 used:14 limits.cpu: "0"15 limits.memory: "0"16 requests.cpu: "0"17 requests.memory: "0"
ResourceQuota 在 quota-mem-cpu-example 命名空间中设置了如下要求:
- 每个容器必须有内存请求和限制,以及 CPU 请求和限制。
- 所有容器的内存请求总和不能超过1 GiB。
- 所有容器的内存限制总和不能超过2 GiB。
- 所有容器的 CPU 请求总和不能超过1 cpu。
- 所有容器的 CPU 限制总和不能超过2 cpu。
为命名空间配置默认的内存请求和限制
示例:
1 # cat memory-defaults.yaml 2 apiVersion: v1 3 kind: LimitRange 4 metadata: 5 name: mem-limit-range 6 spec: 7 limits: 8 - default: 9 memory: 512Mi10 defaultRequest:11 memory: 256Mi12 type: Container
default类似于之前的limit;defaultRequest类似于之前的request。
应用如下:
kubectl create -f memory-defaults.yaml --namespace=default-mem-example
命名空间default-mem-example已提前创建完毕
现在,如果在 default-mem-example 命名空间创建容器,并且该容器没有声明自己的内存请求和限制值,那么它将被指定一个默认的内存请求256 MiB和一个默认的内存限制512 Mib。
为命名空间配置默认的CPU请求和限制
示例:
1 # cpu-defaults.yaml 2 apiVersion: v1 3 kind: LimitRange 4 metadata: 5 name: cpu-limit-range 6 spec: 7 limits: 8 - default: 9 cpu: 110 defaultRequest:11 cpu: 0.512 type: Container
应用如下:
kubectl create -f cpu-defaults.yaml --namespace=default-cpu-example
其中default-cpu-example名称空间已被提前创建
现在如果在 default-cpu-example 命名空间创建一个容器,该容器没有声明自己的 CPU 请求和限制时,那么将会给它指定默认的 CPU 请求0.5和默认的 CPU 限制值1。
配置命名空间的最小和最大内存约束
示例:
1 # cat memory-constraints.yaml 2 apiVersion: v1 3 kind: LimitRange 4 metadata: 5 name: mem-min-max-demo-lr 6 spec: 7 limits: 8 - max: 9 memory: 1Gi10 min:11 memory: 500Mi12 type: Container
应用如下:
kubectl create -f memory-constraints.yaml --namespace=constraints-mem-example
其中constraints-mem-example名称空间已被提前创建
查看 LimitRange 的详情:
kubectl get limitrange mem-min-max-demo-lr --namespace=constraints-mem-example --output=yaml
输出显示预期的最小和最大内存约束。但请注意,即使您没有在 LimitRange 的配置文件中指定默认值,默认值也会被自动创建。
1 limits: 2 - default: 3 memory: 1Gi 4 defaultRequest: 5 memory: 1Gi 6 max: 7 memory: 1Gi 8 min: 9 memory: 500Mi10 type: Container
现在,只要在 constraints-mem-example 命名空间中创建容器,Kubernetes 就会执行下面的步骤:
- 如果 Container 未指定自己的内存请求和限制,将为它指定默认的内存请求和限制。
- 验证 Container 的内存请求是否大于或等于500 MiB【超出范围容器创建失败】。
- 验证 Container 的内存限制是否小于或等于1 GiB【超出范围容器创建失败】。
配置命名空间的最小和最大CPU约束
示例:
1 # cpu-constraints.yaml 2 apiVersion: v1 3 kind: LimitRange 4 metadata: 5 name: cpu-min-max-demo-lr 6 spec: 7 limits: 8 - max: 9 cpu: "800m"10 min:11 cpu: "200m"12 type: Container
应用如下:
kubectl create -f cpu-constraints.yaml --namespace=constraints-cpu-example
其中constraints-cpu-example名称空间已被提前创建
查看 LimitRange 详情:
kubectl get limitrange cpu-min-max-demo-lr --output=yaml --namespace=constraints-cpu-example
输出结果显示 CPU 的最小和最大限制符合预期。但需要注意的是,尽管你在 LimitRange 的配置文件中你没有声明默认值,默认值也会被自动创建。
1 limits: 2 - default: 3 cpu: 800m 4 defaultRequest: 5 cpu: 800m 6 max: 7 cpu: 800m 8 min: 9 cpu: 200m10 type: Container
现在不管什么时候在 constraints-cpu-example 命名空间中创建容器,Kubernetes 都会执行下面这些步骤:
- 如果容器没有声明自己的 CPU 请求和限制,将为容器指定默认 CPU 请求和限制。
- 核查容器声明的 CPU 请求确保其大于或者等于200 millicpu。
- 核查容器声明的 CPU 限制确保其小于或者等于800 millicpu。
配置命名空间下pod总数
示例:
1 # cat quota-pod.yaml2 apiVersion: v13 kind: ResourceQuota4 metadata:5 name: pod-demo6 spec:7 hard:8 pods: "2"
应用如下【命名空间quota-pod-example已提前创建完毕】:
kubectl apply -f quota-pod.yaml --namespace=quota-pod-example
查看资源配额的详细信息:
kubectl get resourcequota pod-demo --namespace=quota-pod-example --output=yaml
从输出的信息我们可以看到,该命名空间下pod的配额是2个,目前创建的pods数为0,配额使用率为0。
1 spec:2 hard:3 pods: "2"4 status:5 hard:6 pods: "2"7 used:8 pods: "0"
相关阅读
1、官网:Pod的CPU资源分配限制
2、官网:Pod的内存资源分配限制
3、官网:管理内存、CPU 和 API 资源
完毕!
来自:zhuanlan.zhihu.com/p/162699218 | 责编:乐乐
正文
前言
在使用容器时(未被Kubernetes进行管理的情况下),我们单台主机上可能会跑几十个容器,容器虽然都相互隔离,但是用的却是与宿主机相同的内核,CPU、内存、磁盘等硬件资源。注:容器没有内核。默认情况下,容器没有资源限制,可以使用主机内核调度程序允许的尽可能多的给定资源;如果不对容器资源进行限制,容器之间就会相互影响,一些占用硬件资源较高的容器会吞噬掉所有的硬件资源,从而导致其它容器无硬件资源可用,发生停服状态。Docker提供了限制内存,CPU或磁盘IO的方法, 可以对容器所占用的硬件资源大小以及多少进行限制,我们在使用docker create创建一个容器或者docker run运行一个容器的时候就可以来对此容器的硬件资源做限制。
Docker核心
Docker分别使用Namespace和CGroup实现了对容器的资源隔离和资源限制,本文将会讲到怎么使用内核来调用CGroup对容器资源做限制。
OOM介绍
out of memorty
OOM:out of memorty的简称,称之为内存溢出
1.如果内存耗尽,内存将无法给予内存空间,内核检测到没有足够的内存来执行重要的系统功能,它会抛出OOM或Out of Memory异常,内存将会溢出,随之会有选择性的杀死相应的进程。2.内存属于不可压缩性资源,如果执行这个进程的内存不够使用,这个进程它就会一直申请内存资源,直到内存溢出。3.CPU属于可压缩性资源,所以CPU并不会出现这种情况,例如一个进程占用了一个核心100%的CPU,那么原本这个进程是需要占用200%的CPU资源,如果其它进程所占用的CPU核心并不需要多高的CPU频率,那么此进程就会占用掉空闲的CPU,如果其它进程也需要他自己核心的CPU频率,那么此进程就只能使用对它自己所使用CPU核心100%,因此叫做可压缩。4.内存的有选择性:为什么不是杀死占用内存最高的进程呢?举个例子:例如我们运行了一个MySQL和一个Tomcat;这个MySQL原本是需要占用2G的内存资源,但他占用了1.9G;而Tomcat原本是需要占用500M的内存空间,可他占用了1G内存空间,这个时候当内存报异常OOM的时候,就会选择Tomcat进程进行发送kill -9的信号,进行杀死以释放内存。5.当我们的一个重要的进程占用的内存超标而导致内存OOM的情况下,我们不希望内核来Kill掉我们这个进程,怎么办?我们可以调整内存OOM后kill进程的优先级,优先级越高越优先杀死,则反之 为此,Docker特地调整了docker daemon的OOM优先级,以免它被内核的杀死,但容器的优先级并未被调整
导致内存OOM
1.加载对象过大;2.相应资源过多,来不及加载;3.应用运行时间较长未重启,从而一点一点占用内存资源,长期积累导致占用内存空间较多;4.代码存在内存泄漏bug。搜索公众号程序员小乐回复关键字“Java”,获取Java面试题和答案。
解决OOM办法
1.内存引用上做一些处理,常用的有软引用;2.内存中加载图片直接在内存中做处理,(如边界压缩);3.动态回收内存;4.优化Delivk虚拟机的堆内存分配;5.自定义堆内存大小;6.定期重启应用以释放内存。
压测工具stress
下载stress
docker pull lorel/docker-stress-ng:latestlatest:Pullingfrom lorel/docker-stress-ngc52e3ed763ff:Pull complete a3ed95caeb02:Pull complete 7f831269c70e:Pull complete Digest: sha256:c8776b750869e274b340f8e8eb9a7d8fb2472edd5b25ff5b7d55728bca681322Status:Downloaded newer image for lorel/docker-stress-ng:latest
使用方法
docker run --name stress -it --rm lorel/docker-stress-ng:latest stress --help--name 指定lorel/docker-stress-ng:latest所启动的测试得容器名称为stress--it:打开一个伪终端,并提供交互式--rm:容器停止即删除lorel/docker-stress-ng:latest:压测stress工具镜像名称stress:lorel/docker-stress-ng:latest镜像内所内置的命令,必须使用此命令来指定--help支持的选项
stress常用选项
--cpu N:启动几个子进程来做压测,默认一个进程使用一个CPU核心,选项可简写为-c Ndocker run --name stress -it --rm lorel/docker-stress-ng:latest stress --help | grep "cpu N"-c N,--cpu N start N workers spinning on sqrt(rand())--vm N:启动几个进程来做匿名页压测,选项可简写为-m Ndocker run --name stress -it --rm lorel/docker-stress-ng:latest stress --help | grep "vm N"-m N,--vm N start N workers spinning on anonymous mmap--vm-bytes N:为--vm N指定的进程提供内存分配,每个进程可以分配到的内存数量,默认为256Mdocker run --name stress -it --rm lorel/docker-stress-ng:latest stress --help | grep "vm-bytes N"--vm-bytes N allocate N bytes per vm worker (default256MB)
Docker内存限制
限制内存注意事项
1.为需要限制容器内的应用提前做好压测,例如Nginx容器自身所占内存空间,以及预算业务量大小所需占用的内存空间,进行压测后,才能进入生产环境使用;2.保证宿主机内存资源充足,监控及时上报容器内的内存使用情况,一旦容器所占用的内存不足,立刻对容器内存限制做调整或者打包此容器为镜像到其它内存充足的机器上进行启动;3.如果物理内存充足,尽量不要使用swap交换内存,swap会导致内存计算复杂。
设置内存选项
注意:可限制的内存单位:b、k、m、g;分别对应bytes、KB、MB、GB
-m or --memory=:容器能使用的最大内存大小,最小值为4M--memory-swap=:容器能够使用swap内存的大小,使用—memory-swap选项必须要使用—memory选项,否则—memory-swap不生效--memory-swappiness:默认情况下,主机可以把容器使用的匿名页swap出来,你可以设置一个0-100之间的值,代表swap出来的比例,如果此值设置为0,容器就会先使用物理内存,能不用就不用swap空间,如果设置为100,则反之,能用swap就会用,哪怕有一丝可以用到swap空间的可能性就会使用swap空间--memory-reservation:预留的一个内存空间,设置一个内存使用soft limit,如果docker发现主机内存不足,会执行OOM操作,这个值必须小于—memory设置的值--kernel-memory:容器能够使用kernel memory大小,最小值为4M--oom-kill-disable:是否运行OOM的时候杀死容器,只有设置了-m或者-memory,才可以设置此值,值为flase或者true,设置为false之后当此容器的内存溢出的时候就会对此容器执行kill操作,否则容器会耗尽主机内存,而且导致主机应用被杀死,如果这个容器运行的应用非常重要,就把—oom-kill-disable设置为true,就是禁止被oom杀掉
--memory-swap详解: swap:交换内存 ram:物理内存
查看内存大小:
限制容器内存
使用docker的--memory选项来限制容器能够使用物理内存的大小,使用stress命令的选项--vm指定启动几个占用内存的进程和每个占用内存进程所占用的内存空间大小 我们指定了容器最多使用物理内存512M,启动两个占用内存的进程,每个进程分别占用512M的空间,那么两个进程理论上需要占用1024的空间,我们只给了1024的空间,显然是不够的:
docker run --name stress-memory -it --rm -m 512M lorel/docker-stress-ng:latest stress --vm 2--vm-bytes 512Mstress-ng: info:[1] defaulting to a 86400 second run per stressorstress-ng: info:[1] dispatching hogs:2 vm
使用docker stats命令来查看容器硬件资源的使用情况 可以看到我们的stress-memory容器的总内存为512M,使用了500多点,但为超过521M,内存占用的百分比为99.3%:
使用htop命令来查看资源情况:
限制容器swap内存
设置oom时是否杀掉进程
Docker CPU限制
查看CPU核心数以及编码:
设置CPU选项
--cpu-shares:共享式CPU资源,是按比例切分CPU资源;比如当前系统上一共运行了两个容器,第一个容器上权重是1024,第二个容器权重是512, 第二个容器启动之后没有运行任何进程,自己身上的512都没有用完,而第一台容器的进程有很多,这个时候它完全可以占用容器二的CPU空闲资源,这就是共享式CPU资源;如果容器二也跑了进程,那么就会把自己的512给要回来,按照正常权重1024:512划分,为自己的进程提供CPU资源。如果容器二不用CPU资源,那容器一就能够给容器二的CPU资源所占用,如果容器二也需要CPU资源,那么就按照比例划分,这就是CPU共享式,也证明了CPU为可压缩性资源。--cpus:限制容器运行的核数;从docker1.13版本之后,docker提供了--cpus参数可以限定容器能使用的CPU核数。这个功能可以让我们更精确地设置容器CPU使用量,是一种更容易理解也常用的手段。-cpuset-cpus:限制容器运行在指定的CPU核心;运行容器运行在哪个CPU核心上,例如主机有4个CPU核心,CPU核心标识为0-3,我启动一台容器,只想让这台容器运行在标识0和3的两个CPU核心上,可以使用cpuset来指定。搜索公众号程序员小乐回复关键字“offer”,获取算法面试题和答案。
限制CPU Share
启动stress压测工具,并使用stress命令加--cpu选项来启动四个进程,默认一个进程占用一颗CPU核心:
docker run --name stress-share -it --rm --cpu-shares 512 lorel/docker-stress-ng:latest stress -c 2stress-ng: info:[1] defaulting to a 86400 second run per stressorstress-ng: info:[1] dispatching hogs:2 cpu
压测工具会吃掉俩个核心的所有CPU资源 再次打开一个窗口,使用htop命令来查看硬件资源损耗情况 我们一共开了两个进程,默认会占用两个cpu核心,每个核心的资源为100%,两个也就是为200%,由于没有指定限制在某个CPU核心上,所以它是动态的跑在四核CPU核心数,但是stress占用CPU的资源不会超出200%:
再次打开一个窗口,使用docker top container也可以查看到两个进程一共消耗了多少cpu资源:
限制CPU核数
我们使用docker的--cpus选项来限制cpu运行的核心数,使用stress命令的选项--cpu来限制启动的进程数 显示cpu只运行两个核心数,也就是只能运行200%CPU资源,启动4个进程,也就是讲这4个进程只能跑在200%的cpu资源上:
docker run --name stress-cpus -it --rm --cpus 2 lorel/docker-stress-ng:latest stress -c 4stress-ng: info:[1] defaulting to a 86400 second run per stressorstress-ng: info:[1] dispatching hogs:4 cpu
使用htop命令查看cpu占用资源 可以看到四个进程,但是跑在了四颗cpu上面,但是每颗cpu只运行了50%左右的资源,4*50也就是200%左右的cpu资源:
使用docker top container也可以查看到四个进程一共消耗了多少cpu资源:
限制容器运行在指定核心
我们使用docker的--cpuset-cpus选项来指定cpu运行在哪个核心上,使用stress的选项--cpu来指定启动的进程数 我们指定4个进程运行在编号为0和2的cpu上:
docker run --name stress-cpuset -it --rm --cpuset-cpus=0,2 lorel/docker-stress-ng:latest stress -c 4stress-ng: info:[1] defaulting to a 86400 second run per stressorstress-ng: info:[1] dispatching hogs:4 cpu
使用htop查看系统硬件占用资源 可以看到和预期一样,占用了第一颗和第三颗cpu,每个进程占用cpu资源为50%,总资源为200%,两颗cpu的量:
每天为客官甄选的文章,客官可还满意?除了程序员领域,我们还为Python领域的学习者们提供文章的精选服务。如果您希望看更多Python相关的内容,可以关注我们的Python公众号【Python程序员】,每天给您带来Python领域最优质的文章和资源!快快扫码关注吧~
Python程序员
一次偶然设置虚拟内存由于设置过大导致系统重启后蓝屏,进入无限系统修复界面,但怎么修复都无法正常进入系统,修复过程如下:
首先得有个Ghost 系统U盘,制作方法百度。
然后开机进入U盘引导,进入Ghost系统
① 桌面→更多工具→设置虚拟内存→初始大小500最大值设置成和物理内存一致即可
② 桌面→修复系统引导
③ 重启进入系统,重点:然后再重新设置一下虚拟内存。
转载于:https://blog.51cto.com/11182927/1980313
拉丁的传说
1. 堆大小设置 JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制。32位系统下,一般限制在1.5G~2G;64为操作系统对内存无限制。我在Windows Server 2003 系统,3.5G物理内存,JDK5.0下测试,最大可设置为1478m。 典型设置: o java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -Xmx3550m:设置JVM最大可用内存为3550M。 -Xms3550m:设置JVM促使内存为3550m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。 -Xmn2g:设置年轻代大小为2G。整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。 -Xss128k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。 o java -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0 -XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5 -XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6 -XX:MaxPermSize=16m:设置持久代大小为16m。 -XX:MaxTenuringThreshold=0:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。 2. 回收器选择 JVM给了三种选择:串行收集器、并行收集器、并发收集器,但是串行收集器只适用于小数据量的情况,所以这里的选择主要针对并行收集器和并发收集器。默认情况下,JDK5.0以前都是使用串行收集器,如果想使用其他收集器需要在启动时加入相应参数。JDK5.0以后,JVM会根据当前系统配置 进行判断。