K8S Resources

Kubernetes 资源管理

   在 Kubernetes 调度 Pod 时,节点有足够的资源用来运行容器非常重要。如果想将一个大的应用调度到一个资源受限的节点,节点可能会耗尽 Memory 或 CPU,导致无法正常工作。

   在 Kubernetes 中提供了 requests 和 limits 来解决调度时选择合适资源的问题。requests 和 limits 是用于控制资源的机制,例如 CPU 和 Memory。

   在 Kubernetes 中 scheduler 使用 CPU 和 Memory 的值来确定在哪里运行 Pod。Pod 中的每个容器都可以设置自己的 requests 和 limits,这些都是附加值。CPU 资源使用 millicores 定义,Memory 使用 million 定义。

requests 资源
limits 资源

Kubernetes Resources

  requests 代表一定能获取到的资源,如果一个容器设置了 requests 属性,Kubernetes 会将其调度到能够提供这些资源的节点上。

  requests 有两种类型的资源:

  • CPU:需要使用 CPU 的核数,单位是 millicores。如:1/4 核设置为 250m,1 核设置为 1000m。

  • Memory:需要使用 Memory 的容量,单位时 million。如:100 兆设置为 100Mi,200 兆设置为 200Mi。

    apiVersion: v1
    kind: Pod
    metadata:
      name: resource-demo
      labels:
        app: resource-demo
    spec:
      containers:
        - name: resource-demo
          image: nginx:1.9
          ports:
            - name: http
              containerPort: 80
          resources:
            requests:
              memory: "32Mi"
              cpu: "200m"

Kubernetes Limits

  limits 代表容器能获取的资源上限,如果一个容器设置了 limits 属性,Kubernetes 只允许容器上升到 limits,然后被限制住。

  limits 有两种类型的资源:

  • CPU:需要使用 CPU 的核数,单位是 millicores。如:1/4 核设置为 250m,1 核设置为 1000m。

  • Memory:需要使用 Memory 的容量,单位时 million。如:100 兆设置为 100Mi,200 兆设置为 200Mi。

    apiVersion: v1
    kind: Pod
    metadata:
      name: resource-demo
      labels:
        app: resource-demo
    spec:
      containers:
        - name: resource-demo
          image: nginx:1.9
          ports:
            - name: http
              containerPort: 80
          resources:
            limites:
              memory: "64Mi"
              cpu: "300m"

Kubernetes ResourceQuotas

   为了防止运维人员未限制资源使用或者使用过大的资源,Kubernetes 提供了 ResourceQuotas 资源配额来限制 Namespace 命名空间中所有容器所能使用的资源之合。

  • requests.cpu:命名空间中所有容器所能达到的合计 CPU requests 的最大值。例如:50 个 10m requests 的容器。

  • requests.memory:命名空间中所有容器能达到的合计 Memory request 的最大值。例如:5 个 20MB requests 的容器。

  • limits.cpu:命名空间中所有容器所能达到的合计 CPU limits 的最大值。

  • limits.memory:命名空间中所有容器能达到的合计 Memory limits 的最大值。

  • pods:命名空间中 Pod 最大实例数。

  • secrets:命名空间中 Secret 最大实例数。

  • services:命名空间中 Service 最大实例数。

  • configmaps:命名空间中 ConfigMap 最大实例数。

  • persistentvolumeclaims:命名空间中 PVC 最大实例数。

  • replicationcontrollers:命名空间中 RC 最大实例数。

    apiVersion: v1
    kind: ResourceQuota
    metadata:
      name: resource-quota-demo
    spec:
      hard:
        requests.cpu: 0.5
        requests.memory: 100Mi
        limits.cpu: 1
        limits.memory: 500Mi
        pods: 10
        secrets: 10
        services: 10
        configmaps: 10
        persistentvolumeclaims: 10
        replicationcontrollers: 10

Kubernetes LimitRange

   通过 LimitRange 可以有效的防止我们在命名空间内创建超小型或超大型的容器。它与针对每个命名空间的 ResourceQuotas 不同,LimitRange 会加强到每个容器上。LimitRange 是对 Pod 和 Container 级别的资源进行限制。

  • default:Pod 中容器默认 limits,任何没有明确设置 limits 的容器,都将使用这个默认值。

  • defaultRequest:Pod 中容器默认 requests,任何没有明确设置 requests 的容器,都将使用这个默认值。

  • max:Pod 中容器可以设置的最大 limits 值。default 不能大于 max 值,同样容器中设置的值也不能大于该值。如果设置了 max 而为设置 default,那么 max 将成为默认值。

  • min:Pod 中容器可以设置的最小 requests 值。defaultRequest 不能小于 min 值,同样容器中设置的值也不能小于该值。如果设置了 min 而为设置 defaultRequest,那么 min 将成为默人值。

  • maxLimitRequestRatio:limit / request 限制值与请求值的比值上限。例如 Pod 中 CPU 的 Limit 值为 3,而 Requests 值为 0.5,此时比值为 6,创建 Pod 会失效。

    apiVersion: v1
    kind: LimitRange
    metadata:
      name: limit-range-demo
    sepc:
      limits:
        - max:
            cpu: "4"
            memory: 2Gi
          min:
            cpu: 200m
            memory: 6Mi
          maxLimitRequestRatio: # max value for limit / request 限制值与请求值的比例
            cpu: 3
            memory: 2
          type: Pod
        - default:
            cpu: 600m
            memory: 100Mi
          defaultRequest:
            cpu: 100m
            memory: 50Mi
          max:
            cpu: 1000m
            memory: 200Mi
          min: # min request
            cpu: 10m
            memory: 10Mi
          maxLimitRequestRatio: # max value for limit / request 限制值与请求值的比例
            cpu: 2
            memory: 2
          type: Container

Kubernets 资源超出

   当 CPU 超过负载时,Kubernetes 会限制每个 Pod 可用 CPU 的资源,但会确保每个 Pod 都有可用的 CPU 资源。

限制 CPU 资源

   当 Memory 超过负载时,首先 Kubernetes 会将资源超出 requests 的 Pods 终止运行,如果某个 Pod 没有配置 requests 那么这个 Pod 就满足资源超出 requests 的条件,所以这个 Pod 是终止运行的最佳候选。

将超出 requests 终止运行

   其次 Kubernetes 会将资源超出 requests 但仍低于 limits 的 Pod 终止运行,如果 Kubernetes 找出了多个符合条件的 Pod 会对这些 Pods 进行优先级(Priority)排序,然后终止运行。

将优先级 priority 最低的终止运行

   最后如果所有 Pods 优先级一致,那么 Kubernets 会终止运行超出 requests 最多的 Pod。

将超出 requests 最多的终止运行

注意事项

  • 如果设置 CPU 核数大于最大节点的核数,那么这个 Pod 将永远无法得到调度。如果应用不是以计算为主,那么 requests 最好设置为 1 或 以下,然后通过更多副本来扩展。这样可以给系统更大的灵活性。

  • CPU 作为一种可压缩资源,当 CPU 使用达到上限时,Kubernetes 将会限制资源使用,这意味着 CPU 将受到认为的限制,给应用带来潜在的性能问题,然而 CPU 无法终止或收回。

  • Memory 作为一种不可压缩的资源,我们无法控制内存的使用,如果容器的内存使用超过了 limits 它将被终止。

  • 如果集群中所有节点都无法满足 Pod 需要的资源,那么 Pod 将被挂起。

requests 过大无法调度


Kubernetes     

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!