系列目录

当你编排一个pod的时候,你也可以可选地指定每个容器需要多少CPU和多少内存(RAM).当容器请求特定的资源时,调度器可以更好地根据资源请求来确定把pod调度到哪个节点上.当容器请求限制特定资源时,特定节点会以指定方式对容器的资源进行限制.

对于资源请求和资源限制的区别,可以查看QoS

资源类型

CPU和RAM都是资源类型,资源类型有一个基本单位.CPU资源通过单位核数来指定,内存通过单位字节来指定.它们和api资源不同.api资源,例如pod和service是kubernetes api server可以读取和修改的对象.

pod和容器的资源请求与资源限制

pod里的每一个容器都可以指一个或多个以下内容:

  • spec.containers[].resources.limits.cpu

  • spec.containers[].resources.limits.memory

  • spec.containers[].resources.requests.cpu

  • spec.containers[].resources.requests.memory

尽管请求和限制只能通过单个的容器来指定,但是我们通常说pod的资源请求和资源限制,这样更方便.Pod对于某一特定资源的请求(或限制)是pod里单个容器请求资源的和.

CPU的意义

对cpu资源的请求和限制用单位cpu来衡量,一个cpu在kubernetes里和以下任意一个是等价的:

  • 1 AWS vCPU

  • 1 GCP Core

  • 1 Azure vCore

  • 1 IBM vCPU

  • 在祼机因特尔超线程处理器上一个超线程

带小数的请求也是允许的.一个指定spec.containers[].resources.requests.cpu值为0.5的容器会被确保分配1个cpu的一半资源.值0.1和100m是等价的,可以读作100 millicpu,也有人读作100 millicores,实际上意义是一样的.请求资源的值为0.1将会被api转换为100m,请求的精度比1m更小是不允许的,因此100m一个较优的选择.CPU资源的请求总是绝对量,永远不会是一个相对值,值是0.1时对于单核cpu,双核cpu或者甚至48核cpu都是一样的.

内存的意义

对内存资源的请求/限制用字节来衡量.你可以使用一个纯整数或者定点整数带上E, P, T, G, M, K这些后缀,你也可以使用2的幂次方的:Ei, Pi, Ti, Gi, Mi, Ki来表示,比如以下表示的量相等

128974848, 129e6, 129M, 123Mi

以下定义的pod包含两个容器,每一个都请求0.25cpu和64MiB (226 字节)的内存.每一个都限制0.5cpu和128MIB内存.你可以说pod请求0.5cpu和128MiB内存,限制1cpu和256MiB内存

前面说过,pod的资源请求/限制是pod里的容器资源请求/限制的和

apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: db
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
- name: wp
image: wordpress
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"

kubernetes如何调度有资源请求的pod

当你创建一个pod,kubernetes会选择一个节点来运行.对于每种资源类型,不论是cpu还是内存,节点可以提供给pod的都是有上限的.对于每种资源,调度器都会确保被调度的pod的请求的总和小于节点的承载能力.请注意即便节点上的cpu或者内存的使用率非常低,但是如果容量检测失败,调度器仍然可能拒绝把某一pod放到指定节点上.这确保后来资源使用增多时不会出现资源短缺的情况.

有资源限制的pod如何运行

当kubelete启动了pod的容器,它会把cpu和内存的限制传入到容器的runtime里

当使用的是docker时:

  • spec.containers[].resources.requests.cpu的值被转换为核数值,它也可能是小数,乘1024.这个值和2两者较大的一个会被作为--cpu-shares标识的值传入docker run命令

  • spec.containers[].resources.limits.cpu被转换为millicore值并且乘以100.结果值是容器每100毫秒可用的cpu时间的总和.

注意默认的时间段配额是100毫秒,最小配额是1毫秒.

  • spec.containers[].resources.limits.memory被转换为整数,然后作为--momory标识的值传入docker run命令.

如果一个容器超过了它的资源限制,则它可能会被终止.如果它是可重启的(根据pod编排时重启策略),则kubelete会重启它,就像对待其它运行时错误一样.

一个容器可能会被允许或者不被允许超过超过它的cpu限制.但是超过cpu资源限制时它不会被杀掉.

问题处理

pod挂起,event消息是:failedScheduling

如果调度器找不到任何可以放置pod的节点,pod一直是未调度状态找到一个合适的节点.调度器每当找不到合适节点来放置pod,就会产生一个事件,信息如下

kubectl describe pod frontend | grep -A 3 Events

Events:
FirstSeen LastSeen Count From Subobject PathReason Message
36s 5s 6 {scheduler } FailedScheduling Failed for reason PodExceedsFreeCPU and possibly others

上面的示例中,由于节点的cpu资源不足,名称为frontend的pod调度失败.类似的错误提示也可能是由于内存资源不足(PodExceedsFreeMemory).一般地,如果类似这样的消息出现,可以进行以下尝试:

  • 集群中添加更多节点

  • 终止一些非必须进程来为挂起的pod腾出资源

  • 检测确保pod小于node,比如节点的容量是cpu:1,如果pod请求的是cpu:1.1将永远不会被调度.

你可以通过kubectl describe nodes命令来查看节点的容量以及可分配的量:

kubectl describe nodes e2e-test-minion-group-4lw4
Name:            e2e-test-minion-group-4lw4
[ ... lines removed for clarity ...]
Capacity:
cpu: 2
memory: 7679792Ki
pods: 110
Allocatable:
cpu: 1800m
memory: 7474992Ki
pods: 110
[ ... lines removed for clarity ...]
Non-terminated Pods: (5 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits
--------- ---- ------------ ---------- --------------- -------------
kube-system fluentd-gcp-v1.38-28bv1 100m (5%) 0 (0%) 200Mi (2%) 200Mi (2%)
kube-system kube-dns-3297075139-61lj3 260m (13%) 0 (0%) 100Mi (1%) 170Mi (2%)
kube-system kube-proxy-e2e-test-... 100m (5%) 0 (0%) 0 (0%) 0 (0%)
kube-system monitoring-influxdb-grafana-v4-z1m12 200m (10%) 200m (10%) 600Mi (8%) 600Mi (8%)
kube-system node-problem-detector-v0.1-fj7m3 20m (1%) 200m (10%) 20Mi (0%) 100Mi (1%)
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
CPU Requests CPU Limits Memory Requests Memory Limits
------------ ---------- --------------- -------------
680m (34%) 400m (20%) 920Mi (12%) 1070Mi (14%)

通过上面的输出,你可以看到如果有一个pod请求或者 6.23Gi 内存,则它不适合调度到此节点上.

通过查看pods部分,你可以看到你可以看到哪些pod在本节点上占用了资源

可供pod使用的资源数量小于节点的实际容量,这是因为系统守护进程按比例使用可用资源.allocatable字段里的数量是pod实际可用的资源数量,详情请查看可用资源

容器终止

pod可能由于资源不足被终止,你可以使用kubectl describe pod来检测pod是否由于资源达到上限被杀死

kubectl describe pod simmemleak-hra99
Name:                           simmemleak-hra99
Namespace: default
Image(s): saadali/simmemleak
Node: kubernetes-node-tf0f/10.240.216.66
Labels: name=simmemleak
Status: Running
Reason:
Message:
IP: 10.244.2.75
Replication Controllers: simmemleak (1/1 replicas created)
Containers:
simmemleak:
Image: saadali/simmemleak
Limits:
cpu: 100m
memory: 50Mi
State: Running
Started: Tue, 07 Jul 2015 12:54:41 -0700
Last Termination State: Terminated
Exit Code: 1
Started: Fri, 07 Jul 2015 12:54:30 -0700
Finished: Fri, 07 Jul 2015 12:54:33 -0700
Ready: False
Restart Count: 5
Conditions:
Type Status
Ready False
Events:
FirstSeen LastSeen Count From SubobjectPath Reason Message
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {scheduler } scheduled Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD pulled Pod container image "k8s.gcr.io/pause:0.8.0" already present on machine
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD created Created with docker id 6a41280f516d
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD started Started with docker id 6a41280f516d
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} spec.containers{simmemleak} created Created with docker id 87348f12526a

上面的例子中,Restart Count:5表示simmemleak容器中止并且被重启了五次.

你可以通过kubectl get pod加上-o go-template=...选项来获取上次终止的容器的状态

kubectl get pod -o go-template='{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}'  simmemleak-hra99
Container Name: simmemleak
LastState: map[terminated:map[exitCode:137 reason:OOM Killed startedAt:2015-07-07T20:58:43Z finishedAt:2015-07-07T20:58:43Z containerID:docker://0e4095bba1feccdfe7ef9fb6ebffe972b4b14285d5acdec6f0d3ae8a22fad8b2]]

你可以看到容器由于reason:OOM Killed错误被中止,OOM表示out of memory(内存溢出)

Local ephemeral storage(本地暂存容量)

此功能在1.14版本中为beta状态

Kubernetes在1.8的版本中引入了一种类似于CPU,内存的新的资源模式:ephemeral-storage,并且在1.10的版本在kubelet中默认打开了这个特性。ephemeral-storage是为了管理和调度Kubernetes中运行的应用的短暂存储。在每个Kubernetes的节点上,kubelet的根目录(默认是/var/lib/kubelet)和日志目录(/var/log)保存在节点的主分区上,这个分区同时也会被Pod的EmptyDir类型的volume、容器日志、镜像的层、容器的可写层所占用。ephemeral-storage便是对这块主分区进行管理,通过应用定义的需求(requests)和约束(limits)来调度和管理节点上的应用对主分区的消耗。

在节点上的kubelet启动的时候,kubelet会统计当前节点的主分区的可分配的磁盘资源,或者你可以覆盖节点上kubelet的配置来自定义可分配的资源。在创建Pod时会根据存储需求调度到满足存储的节点,在Pod使用超过限制的存储时会对其做驱逐的处理来保证不会耗尽节点上的磁盘空间。

如果运行时指定了别的独立的分区,比如修改了docker的镜像层和容器可写层的存储位置(默认是/var/lib/docker)所在的分区,将不再将其计入ephemeral-storage的消耗。

对Local ephemeral storage的请求/限制

所有的container可以指定以下一个或多个选项

  • spec.containers[].resources.limits.ephemeral-storage

  • spec.containers[].resources.requests.ephemeral-storage

ephemeral-storage资源的请求/限制通过字节来衡量.同上面内存的请求/限制方式一样,这里不再细述.

比如以下pod包含两个容器,每一个都对Local ephemeral storage的请求为2GiB,限制为4GiB.此时,整个pod对资源的请求为4GiB,对资源的限制为8GiB

apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: db
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
resources:
requests:
ephemeral-storage: "2Gi"
limits:
ephemeral-storage: "4Gi"
- name: wp
image: wordpress
resources:
requests:
ephemeral-storage: "2Gi"
limits:
ephemeral-storage: "4Gi"

对有ephemeral-storage请求的pod如何调度

当你创建一个pod,kubernetes调度器选择一个节点来运行它.每个节点都有可供pod使用的最大Local ephemeral storage最大量,详细信息请查看Node Allocatable

调度器保证被调度的容器资源总和小于节点的容量

带有Local ephemeral storage的pod如何运行

对于容器级别的隔离,如果容器的可写层( writable layer)和日志(log)超出了容量限制,容器所在的pod将会被驱离;对于pod级别的隔离,如果pod里所有容器使用的总Local ephemeral storage和pod的emptydir存储卷超过限制,pod将会被驱离.

示例

apiVersion: v1
kind: Pod
metadata:
name: teststorage
labels:
app: teststorage
spec:
containers:
- name: busybox
image: busybox
command: ["bash", "-c", "while true; do dd if=/dev/zero of=$(date '+%s').out count=1 bs=10MB; sleep 1; done"] # 持续写入文件到容器的rootfs中
resources:
limits:
ephemeral-storage: 100Mi #定义存储的限制为100M
requests:
ephemeral-storage: 100Mi

测试这个Pod就能发现在容器写入超过存储限制时就会被驱逐掉了:

 /tmp kubectl apply -f pod.yaml
pod "teststorage" created
/tmp kubectl get pod -w
NAME READY STATUS RESTARTS AGE
teststorage 0/1 ContainerCreating 0 3s
teststorage 1/1 Running 0 7s
teststorage 0/1 Evicted 0 1m

查看kubernetes的pod的事件也能看到它是由于超过了限制的ephemeral-storage被驱逐掉:

Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m default-scheduler Successfully assigned teststorage to minikube
Normal SuccessfulMountVolume 2m kubelet, minikube MountVolume.SetUp succeeded for volume "default-token-l7wp9"
Normal Pulling 2m kubelet, minikube pulling image "busybox"
Normal Pulled 2m kubelet, minikube Successfully pulled image "busybox"
Normal Created 2m kubelet, minikube Created container
Normal Started 2m kubelet, minikube Started container
Warning Evicted 1m kubelet, minikube pod ephemeral local storage usage exceeds the total limit of containers {{104857600 0} {<nil>} 100Mi BinarySI}
Normal Killing 1m kubelet, minikube Killing container with id docker://busybox:Need to kill Pod

kubernetes之计算机资源管理的更多相关文章

  1. 第18 章 : Kubernetes 调度和资源管理

    Kubernetes 调度和资源管理 这节课主要讲三部分的内容: Kubernetes 的调度过程: Kubernetes 的基础调度能力(资源调度.关系调度): Kubernetes 高级调度能力( ...

  2. kubernetes实战(二十八):Kubernetes一键式资源管理平台Ratel安装及使用

    1. Ratel是什么? Ratel是一个Kubernetes资源平台,基于管理Kubernetes的资源开发,可以管理Kubernetes的Deployment.DaemonSet.Stateful ...

  3. 从零开始入门 K8s | Kubernetes 调度和资源管理

    作者 | 子誉  蚂蚁金服高级技术专家 关注"阿里巴巴云原生"公众号,回复关键词"入门",即可下载从零入门 K8s 系列文章 PPT. Kubernetes 调 ...

  4. 6.kubernetes的GUI资源管理插件-dashboard

    目录 1.准备dashboard镜像 2.创建资源配置清单 3.应用资源配置清单 4.查看创建的资源 5.解析域名 6.浏览器访问 7.令牌命令行获取方式 准备dashboard镜像 [root@hd ...

  5. 基于jenkins,tekton等工具打造kubernetes devops平台

    本贴为目录贴,将不断更新 目录 1.Docker在centos下安装以及常见错误解决 2.使用kubernetes 官网工具kubeadm部署kubernetes(使用阿里云镜像) 3.无法访问gcr ...

  6. 如何掌握 Kubernetes ?系统学习 k8s 的大纲一份

    深度剖析 Kubernetes 深度剖析 k8s 如何学习 Kubernetes ?如何入门 Kubernetes? 为了帮帮初学者,2018 年 InfoQ 旗下(就是你知道的那个 InfoQ 哇) ...

  7. 一线工程师带你深入学习和使用Kubernetes

    http://page.factj.com/tor/xoxaHR0cDovL2RvY2tvbmUuaW8vYXJ0aWNsZS8yMzM0 Kubernetes是Google开源的容器集群管理系统,它 ...

  8. Kubernetes+Jenkins+Nexus+Gitlab进行CI/CD集成

    前面已经完成了 二进制部署Kubernetes集群,下面进行CI/CD集成. 一.流程说明 应用构建和发布流程说明: 1.用户向Gitlab提交代码,代码中必须包含Dockerfile: 2.将代码提 ...

  9. 美团点评Kubernetes集群管理实践

    背景 作为国内领先的生活服务平台,美团点评很多业务都具有非常显著.规律的”高峰“和”低谷“特征.尤其遇到节假日或促销活动,流量还会在短时间内出现爆发式的增长.这对集群中心的资源弹性和可用性有非常高的要 ...

随机推荐

  1. 【bzoj3207】花神的嘲讽计划Ⅰ Hash+STL-map+莫队算法

    题目描述 背景 花神是神,一大癖好就是嘲讽大J,举例如下: “哎你傻不傻的![hqz:大笨J]” “这道题又被J屎过了!!” “J这程序怎么跑这么快!J要逆袭了!” …… 描述 这一天DJ在给吾等众蒟 ...

  2. python学习笔记--python编程基础

    一.一个隆重的仪式 我们在学习语言的时候,第一个写的程序肯定都是hello world.来写第一个程序吧,其实很简单,python的语法就是简单.优雅,一个print就搞定. 1 print('hel ...

  3. HDU——1019Least Common Multiple(多个数的最小公倍数)

    Least Common Multiple Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Ot ...

  4. UVa——1593Alignment of Code(string重定向+vector数组)

    UVA - 1593 Alignment of Code Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & ...

  5. HDU——1397Goldbach's Conjecture(二分查找+素数打表)

    Goldbach's Conjecture Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Ot ...

  6. [AtCoderContest075F]Mirrored

    [AtCoderContest075F]Mirrored 试题描述 For a positive integer \(n\), we denote the integer obtained by re ...

  7. BZOJ 3786 星系探索 ——Splay

    子树可以移动,唔. 还是用Splay维护DFS序即可. 子树的话直接截取出来就好了. 然后求前驱后继可能麻烦一些. 添加两个虚拟节点会比较好写. #include <map> #inclu ...

  8. [暑假集训--数位dp]hdu5787 K-wolf Number

    Alice thinks an integer x is a K-wolf number, if every K adjacent digits in decimal representation o ...

  9. Perl语言入门--4--列表

    1.列表也是数组的形式:(1,'a',2,3,4) 元素可以是任意类型,变量,表达式 2.空列表:() 单元素列表:(2)  .与值2不同 qw(1 $a str)   #qw是用空格作为分隔符,元素 ...

  10. QQ客服代码,支持临时会话

    <a target="_blank" href="http://wpa.qq.com/msgrd?v=3&uin=QQ号&site=qq&m ...