CPU、GPU、内存、持久化存储

Requests

kubernetes 会根据 Request 的值去查找有足够资源的 node 来调度此 pod

request 设置 10Gb 内存,那么 Node 会为它预留 10Gb 的内存,如果不够,pod 无法被正常调度

Limits

limit 对应资源量的上限, 既最多允许使用这个上限的资源量, 由于 cpu 是可压缩的, 进程是无法突破上限的, 而memory 是不可压缩资源, 当进程试图请求超过 limit 限制时的 memory, 此进程就会被 kubernetes 杀掉

查看 Node 资源占用

  1. 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 - 服务最可靠
  • 不设置 - 服务最不可靠
  • Limits > Request - 比较可靠的服务

    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

    内存紧缺

  • 驱除不可靠的 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 状态