Requests
kubernetes 会根据 Request 的值去查找有足够资源的 node 来调度此 pod
request 设置 10Gb 内存,那么 Node 会为它预留 10Gb 的内存,如果不够,pod 无法被正常调度
Limits
limit 对应资源量的上限, 既最多允许使用这个上限的资源量, 由于 cpu 是可压缩的, 进程是无法突破上限的, 而memory 是不可压缩资源, 当进程试图请求超过 limit 限制时的 memory, 此进程就会被 kubernetes 杀掉
查看 Node 资源占用
k describe node nodeName
注意:修改 pod 的资源大小,pod 会被重启
如果一个 pod 占用了非常多内存,k8s 会 killed 占用内存的进程,它并不会 killed pod;不同的是 CPU 占用非常多,k8s 不会 killed 占用 CPU 非常多的进程(CPU 是可压缩资源)
- k8s 调度策略不依赖 limits ,即使 pod limits 突破物理机的限制,pod 仍然可以被调度
- k8s 调度策略依赖 Request,当 pod Request 内存或者 CPU 超过 Node 上的资源时,pod 会处于 pending 状态
注意:如果 Node 10Gb 内存,一个 deployment replicas 为 3(3个副本),每个 pod Request 4 Gb 内存,那么 同一个 Node 只有2个 Pod 会正常调度,另外一个 处于 pending 状态
服务可靠性等级
- Request == Limits - 服务最可靠
- 不设置 - 服务最不可靠
-
LimitRange
限制容器的资源占用
作用:保证每个服务都有合理的配置k describe limits当 pod 的 CPU、内存超过 Container limitRange 的限制,那么 pod 将不会被调度
ResourceQuota
资源配额,限制 namespace 对 k8s 资源的分配
pod 个数
- request.cpu
- request.memory
- limits.cpu
- limits.memory
其它资源限制
- configmaps
- persịstentvolumeclaims
- replicationcontrollers
- secrets
- services
查看 quota 使用的数量和限制的数量
k describe quota quotaName
Pod 驱除 - Eviction(生产环境必备的配置)
常见驱逐策略配置:
—eviction-soft= memory.available < 1.5Gi(节点内存小于 1.5Gb)
—eviction-soft-grace-period= memory.available = 1m30s(当内存持续 1m30s 都小于 1.5Gb 时,开始驱除)
—eviction-hard = memory.available < 100Mi, nodefs.available < 1Gi,nodefs.inodesFree < 5%(但这些条件都满足条件时,立刻驱除)
磁盘紧缺
- 删除死掉的 Pod、容器
- 删除没用的镜像
-
内存紧缺
驱除不可靠的 Pod(k8s 会在不可靠的 Pod 中,找到占用内存最大的 Pod,把它干掉)
- 驱逐基本可靠的 Pod(k8s 会找到你实际使用的内存,大于你 request 的 Pod,超过的越多,优先把它删除;如果都没有超过 request,那么 k8s 会把占用最多资源的应用 killed)
- 驱逐可靠的 Pod(同上)
Label
Key = Value
可以贴到:pod、deploy、service、node等type=backend cpu=better
# 定义
metadata.labels.key=value
# 选择
selector.matchLabels.key=value
service 的 label 机制
定义 2 个相同的 deployment(metadata.name 不同)。它们的创建 pod 的 label.name 虽然都叫 app=web-demo,但是 pod 并不会混在一起
#deploy1
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-demo
spec:
selector:
matchLabels:
app: web-demo
replicas: 1
template:
metadata:
labels:
app: web-demo # pod label name 相同
#deploy2
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-demo-new
spec:
selector:
matchLabels:
app: web-demo
replicas: 1
template:
metadata:
labels:
app: web-demo # pod label name 相同
#service
apiVersion: v1
kind: Service
metadata:
name: web-demo
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
app: web-demo # 选择 label.app=web-demo 的 pod
service 的 spec.selector 选择了 app=web-demo 的 pod(这个选择器在 deploy1 和 deploy2 都有定义,那么 service 会选择哪个 deploy(定义的pod) 呢?)
当有多个 deploy(定义的pod)可以选择时,service 会通过轮询负载均衡,将流量打到 deploy1(定义的pod)和 deploy2(定义的pod)上
matchExpressions
matchLabels:
app: web-demo
matchExpressions:
- {key: group, operator: In, values: [dev, test]}
matchLabels 并且 matchExpressions 同时满足条件才会被选中
app=web-demo 并且 group=[dev | test] 才会被选中
注意:selector 一旦定义,不应该随便修改(k8s 会阻止你这么做,当然也可以 kubectl delete,如何在重新 kubectl apply 使配置生效 )
通过 label 过滤资源
kubectl get pod -l app=web-demo
# app=web-demo并且group=dev
kubectl get pod -l app=web-demo,group=dev
# group!=dev
kubectl get pod -l 'group notin (dev)'
nodeSelector
node 选择器
如果没有合适的 label,那么 pod 会进入 pending 状态
