kubernetes云原生纪元:资源管理Resource(下)
文章目录
Requests & limts 关联性
Requests & limts 他们的值是有关联的,服务可靠性的等级,就是这两个值来区分的。
- Requests==limts 服务完全可靠,等级最高
- 不设置(不建议) 不设置值服务就最不可靠,没有资源最先杀掉的就上这种
- limts >Requests 比较可靠的服务,根据优先级分配
重要的服务我们必须设置值一样
范围限制LimitsRnage
LimitRange从字面意义上来看就是对范围进行限制,实际上是在pod
和container
级别上对cpu和内存资源使用范围的限制 。
LimitsRnage 配置信息
max: #最大 cpu 4核 内存 2g
min: #最小 cpu 0.1核 内存 100m
maxLimitRequestRatio: #Request和limits
最大比例值
不能超过 cpu 3 解释:同一个配置里面limits的cpu最大可以比Request的cpu大3倍,超过3倍就创建不成功。type: 可以对pod 、Container 进行设置
default: #默认limits cpu 0.3核 内存 200m
defaultRequest: #默认Request cpu 200m 内存100m
apiVersion: v1
kind: LimitRange
metadata:
name: test-limits
spec:
limits: #limits限制
- max: #最大 cpu 4核 内存 2g
cpu: 4000m
memory: 2Gi
min: #最小 cpu 0.1核 内存 100m
cpu: 100m
memory: 100Mi
maxLimitRequestRatio: #Request和limits最大比例值不能超过 cpu 3 解释:同一个配置里面limits的cpu最大可以比Request的cpu大3倍,超过3倍就创建不成功。
cpu: 3
memory: 2
type: Pod #类型是pod 限制
- default: #默认 cpu 0.3核 内存 200m
cpu: 300m
memory: 200Mi
defaultRequest: #默认Request cpu 200m 内存100m
cpu: 200m
memory: 100Mi
maxLimitRequestRatio:
cpu: 5
memory: 4
type: Container #类型是容器 限制
为什么Container(容器)的限制比Pod 多了两个默认值default、defaultRequest ,为什么Pod 没有呢?**
pod本身是逻辑的概念,会包含多个容器,没有办法给出默认值,只能对Pod做一个限制。*
容器在配置文件yaml没有配置默认值,他就会自动使用LimitsRange 配置的这两个属性default、defaultRequest 的值。
创建LimitRange
在使用 limitsRange 前我们创建一个namespace ,他是基于namespace 设置各种的限制🚫
[root@master-001 ~]# kubectl create ns test
namespace/test created
创建LimitRange
[root@master-001 ~]# kubectl create -f limit-test.yaml -n test
limitrange/test-limits created
查看创建的LimitRange
注意⚠️Default Limit 就是我们yaml 中的==-Default:==
[root@master-001 ~]# kubectl describe limits -n test
Name: test-limits
Namespace: test
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Pod cpu 100m 4 - - 3
Pod memory 100Mi 2Gi - - 2
Container cpu - - 200m 300m 5
Container memory - - 100Mi 200Mi 4
使用LimitRange
我们使用一个web项目的demo,测试
Web-test.yaml
#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-demo
namespace: dev
spec:
selector:
matchLabels:
app: web-demo
replicas: 1
template:
metadata:
labels:
app: web-demo
spec:
containers:
- name: web-demo
image: hub.zhang.com/kubernetes/demo:2020011512381579063123
ports:
- containerPort: 8080
创建
[root@master-001 ~]# kubectl apply -f web-test.yaml -n test
deployment.apps/web-demo configured
查看下服务的yaml
[root@master-001 ~]# kubectl get pod -n test
NAME READY STATUS RESTARTS AGE
web-demo-58cd855cb7-v548m 1/1 Running 0 13s
[root@master-001 ~]# kubectl get pod -n test web-demo-58cd855cb7-v548m -o yaml
其他配置信息省略…
.............. spec: containers: - image: hub.zhang.com/kubernetes/demo:2020011512381579063123 imagePullPolicy: IfNotPresent name: web-demo ports: - containerPort: 8080 protocol: TCP resources: limits: #对应limitRange 的两个default cpu: 300m memory: 200Mi requests: cpu: 200m memory: 100Mi ...........
测试
测一个不和比例的limits超过Request cpu10倍,这里就不写代码了
经测试:无法创建pod ,这==maxLimitRequestRatio:==的配置信息起到的作用
测一个超出限制的配置,…
经测试:无法创建
很明显LimitRange起到决定性的控制
资源配额ResourceQuota
多个团队同时使用一个机器,需要考虑如何合理的分配资源,不能让一个团队把资源占满,这个时候就需要资源配额ResourceQuota。他可以给namespace做出各种各样的 限制。
配置
我们这里不啰嗦直接上配置信息:
compute-resource.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: resource-quota
spec:
hard: # 当前namespace 的限制如下
pods: 4 #最多可以有4个pod
requests.cpu: 2000m # requests.cpu最多可以使用 2核
requests.memory: 4Gi # requests.memory最多可以使用4g
limits.cpu: 4000m # limits.cpu 最多可以使用 4核
limits.memory: 8Gi # limits.memory 8g
除了对CPU 内存的一些限制他还有其他一些限制,比如可以对kubernetes 的资源做一些数量 限制
如下:
oject-count.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-counts
spec:
hard: # 当前namespace 的限制如下
configMaps: 10 #最多可以有10configMaps
persistentvolumeclaims: 4 #最多可以有4个persistentvolumeclaims
replicationcontrollers: 20
secrets: 10
services: 10 # 最多可以有10个service
使用
[root@master-001 ~]# kubectl apply -f compute-resource.yaml -n test
resourcequota/resource-quota created
[root@master-001 ~]# kubectl apply -f oject-count.yaml -n test
resourcequota/object-counts created
查看一下
[root@master-001 ~]# kubectl get quota -n test
NAME CREATED AT
object-counts 2020-01-16T16:05:01Z
resource-quota 2020-01-16T16:04:05Z
[root@master-001 ~]# kubectl describe quota resource-quota -n dev
Name: resource-quota
Namespace: dev
Resource Used Hard
-------- ---- ----
limits.cpu 300m 2
limits.memory 200Mi 8Gi
pods 1 4
requests.cpu 200m 1500
测试一下看下我们创建的ResourceQuota是否生效
- 我们创建5个pod看能否创建成功
#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-demo
namespace: dev
spec:
selector:
matchLabels:
app: web-demo
replicas: 5 #5个副本
template:
metadata:
labels:
app: web-demo
spec:
containers:
- name: web-demo
image: hub.zhang.com/kubernetes/demo:2020011512381579063123
ports:
- containerPort: 8080
[root@master-001 ~]# kubectl apply -f web-test.yaml -n dev
deployment.apps/web-demo configured
[root@master-001 ~]# kubectl get deploy -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
web-demo 4/5 4 4 56m
[root@master-001 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
web-demo-58cd855cb7-42nfp 1/1 Running 0 2m43s
web-demo-58cd855cb7-6q5pc 1/1 Running 0 2m43s
web-demo-58cd855cb7-h6lwj 1/1 Running 0 2m
只是创建了4个因为我在ResourceQuota中设置的pod 最多只能有4个的数量
我们看下pod使用量已经满了,同样我们把内存cpu 达到这个ResourceQuota 的上限,也不会被调度的。其他的就不一个个测试了。
[root@master-001 ~]# kubectl describe quota resource-quota -n dev
Name: resource-quota
Namespace: dev
Resource Used Hard
-------- ---- ----
limits.cpu 1200m 2
limits.memory 800Mi 8Gi
pods 4 4 #最多4个 当前已有4个
requests.cpu 800m 1500m
requests.memory 400Mi 4Gi
Pod驱逐Eviction
我们已经配置的各种各样的限制从容器到namespace 是不是就不会出现问题了,不会出现资源相关的问题了?
NO!当我不停的创建新的服务调度,最终有些节点会达到饱和,当有些服务实际使用的内存大于Request 设置的内存,就很有可能导致当前节点的物理内存不足。从而达到系统设置的预值,内核就可自动杀进程,甚至有可能把我们的dockerd 杀掉,严重影响我们的稳定性。kubernets 早就想到了这一点加入了Pod驱逐策略,保证我们的系统稳定性。
每个node节点上都跑着一个kubelet,他会持续的监控我们资源主机的使用情况,一旦出现资源紧缺,他就会主动停止一个或多个Pod,来回收一些资源。但是如何去判断驱逐哪一个Pod,kubernetes 提供了一些参数让我自己设置具体驱逐的策略。
pod驱逐策略非常重要,它是跟kubernetes稳定性息息相关,在生产环境必备的。
常驱逐策略
- –envction-soft=memory.available<1.5Gi. 当机器内存小于1.5G (soft不是发现就驱逐,而是有一个时间)
- –envction-soft-grace-period=memory.available=1m30s 当机器内存持续一分三十秒都小于1.5G的时候,就开始驱逐
这两个参数结合使用的缺一不可
- –envction-hard=memory.available<100Mi,nodefs.available<1G,nodefs.inodesFree<5% 当这些条件满足的时候立刻驱逐,比如:
memory.available<100Mi
内存小于100m或者nodefs.available<1G
磁盘小于1g或者nodefs.inodesFree<5%
剩余答应节点5% 都在自动驱逐
磁盘紧缺
kubectl 在磁盘紧缺的情况下先删除死掉的 pod 和容器和删除没有的镜像,如果磁盘 还是不够就去按优先级驱逐pod,他会在同级别选择占据磁盘最多的pod驱逐
- 删除死掉的 pod 和容器
- 删除没有的镜像
- 按优先级、资源占用情况驱逐pod
内存紧缺
kubectl找到不可靠的pod中找到内存最大的pod把他干掉。如果没有,就会基本可靠的pod先获取你实际使用的内存大于Request的设置的内存的pod按超过的越多驱逐的优先级越高的方式去驱逐,如果大家都没有超过request 内存,他就会直接驱逐占用内存最高的pod,最后实在不行他会删除可靠pod,删除的过程跟基本可靠pod是一致的
- 驱逐不可靠的pod
- 驱逐基本可靠内存的pod
- 可靠pod
这里就不做测试,比较麻烦耗时也比较长,可以在demo 做一个非常吃内存的Controller接口,访问这个接口,传人memory参数,让他在程序里面占用这么大的内存,这样做就非常贴近实际的案例。
关于Resource就讲这么多。