K8s 中的资源请求与限制高级策略:细粒度资源管理与公平性

好的,各位观众,各位“码农”朋友们,欢迎来到今天的“K8s资源请求与限制高级策略:细粒度资源管理与公平性”主题讲座!我是你们的老朋友,人称“Bug终结者”的码神小李。😎

今天,咱们不搞那些死板的理论,咱们聊点实在的,聊聊如何在K8s这个“云上乐园”里,让你的应用住得舒舒服服,还能和其他“小伙伴”和平共处,不吵不闹。

第一幕:K8s资源管理,一场“房产分配”大戏

想象一下,K8s集群就像一个大型的“共享公寓”,里面住着各种各样的应用,它们都需要CPU、内存这些“生活必需品”。而K8s的角色,就像一位精明的“房产管理员”,负责分配资源,维持秩序。

但问题来了,有的应用是“土豪”,胃口大,需要大量的资源才能运行;有的应用是“小清新”,吃得少,一点资源就能满足。如果资源分配不均,就会出现“贫富差距”,导致“土豪”应用独占资源,而“小清新”应用饿肚子。😱

所以,我们需要一套合理的资源管理策略,既要保证“土豪”应用的正常运行,也要照顾“小清新”应用的生存需求,实现“共同富裕”。

第二幕:资源请求(Requests),我是来“预订”的!

在K8s中,资源请求(Requests)就像你的应用向“房产管理员”发出的“预订申请”。它告诉K8s:“我需要这么多的CPU和内存才能正常运行,请提前预留给我!”

举个例子,你可以在Pod的YAML文件中这样设置资源请求:

apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: my-container
    image: my-app-image
    resources:
      requests:
        cpu: "1"  # 预订1个CPU
        memory: "2Gi" # 预订2GB内存

这里,“cpu: "1"”表示你的应用需要预订1个CPU核心;“memory: "2Gi"”表示需要预订2GB内存。

K8s会根据你的资源请求,找到满足条件的Node(节点),并将你的Pod调度到该节点上。这样,你的应用就能获得它所需要的资源,保证正常运行。👍

敲黑板!重点来了:

  • 资源请求是“承诺”,不是“保证”! K8s会尽力满足你的资源请求,但如果集群资源紧张,它也可能无法完全满足。
  • 合理设置资源请求非常重要! 如果你设置得太高,可能会导致资源浪费,甚至无法调度;如果设置得太低,可能会导致应用性能下降,甚至崩溃。

第三幕:资源限制(Limits),我是有“底线”的!

资源限制(Limits)就像给你的应用设置的“消费上限”。它告诉K8s:“我最多只能使用这么多的CPU和内存,超过这个量就给我‘断电’!”

你可以在Pod的YAML文件中这样设置资源限制:

apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: my-container
    image: my-app-image
    resources:
      requests:
        cpu: "1"
        memory: "2Gi"
      limits:
        cpu: "2"  # 限制最多使用2个CPU
        memory: "4Gi" # 限制最多使用4GB内存

这里,“cpu: "2"”表示你的应用最多只能使用2个CPU核心;“memory: "4Gi"”表示最多只能使用4GB内存。

资源限制的作用是什么呢?

  1. 防止“资源抢占”: 限制可以防止某个应用过度消耗资源,影响其他应用的运行。
  2. 提高集群稳定性: 限制可以防止应用出现“内存泄漏”等问题,导致整个集群崩溃。
  3. 控制成本: 限制可以帮助你控制应用的资源使用量,避免不必要的浪费,降低云服务费用。💰

再敲黑板!记住这些:

  • 资源限制是“强制”的! 如果你的应用超过了资源限制,K8s会采取行动,例如限制CPU使用率,或者直接杀死Pod。
  • 资源限制应该大于或等于资源请求! 如果资源限制小于资源请求,K8s会认为你的配置有问题,可能会拒绝调度你的Pod。

第四幕:资源QoS(服务质量),我是有“等级”的!

K8s使用QoS(服务质量)来对Pod进行分类,根据其资源请求和限制的设置,将Pod分为三个等级:

  1. Guaranteed(保证): 这是最高的等级。只有当Pod的所有容器都设置了相等的资源请求和限制,并且CPU和内存都设置了时,才能被认为是Guaranteed。这类Pod享有最高的优先级,K8s会尽力保证它们的资源需求。
  2. Burstable(突发): 当Pod满足以下条件之一时,会被认为是Burstable:

    • Pod的所有容器都设置了资源请求,但资源请求和限制不相等。
    • Pod的部分容器设置了资源请求。
    • Pod的某些容器设置了limits, 但没有设置requests。

    这类Pod的优先级中等,它们可以在资源空闲时使用超出资源请求的资源,但在资源紧张时,可能会被K8s回收资源。

  3. BestEffort(尽力而为): 这是最低的等级。只有当Pod的所有容器都没有设置资源请求和限制时,才会被认为是BestEffort。这类Pod的优先级最低,K8s会尽力运行它们,但在资源紧张时,它们最容易被K8s回收资源。

你可以通过kubectl describe pod <pod-name>命令来查看Pod的QoS等级。

QoS等级的重要性:

  • 资源调度: K8s会优先调度Guaranteed Pod,然后是Burstable Pod,最后是BestEffort Pod。
  • 资源回收: 当集群资源紧张时,K8s会优先回收BestEffort Pod的资源,然后是Burstable Pod,最后是Guaranteed Pod。

第五幕:高级策略,让资源管理更上一层楼

仅仅设置资源请求和限制还不够,我们还需要一些高级策略,才能更好地管理K8s集群的资源。

  1. ResourceQuota(资源配额): 资源配额可以限制Namespace(命名空间)中可以使用的资源总量。它可以防止某个团队或应用过度消耗资源,影响其他团队或应用的运行。

    你可以使用kubectl create quota命令来创建资源配额。

    apiVersion: v1
    kind: ResourceQuota
    metadata:
      name: my-quota
    spec:
      hard:
        pods: "10"  # 限制最多创建10个Pod
        requests.cpu: "10" # 限制CPU请求总和为10个核心
        requests.memory: "20Gi" # 限制内存请求总和为20GB
        limits.cpu: "20" # 限制CPU限制总和为20个核心
        limits.memory: "40Gi" # 限制内存限制总和为40GB
  2. LimitRange(限制范围): 限制范围可以为Namespace中的Pod和Container设置默认的资源请求和限制,以及允许的最小和最大资源请求和限制。它可以帮助你规范Pod和Container的资源使用,防止出现不合理的资源配置。

    你可以使用kubectl create limitrange命令来创建限制范围。

    apiVersion: v1
    kind: LimitRange
    metadata:
      name: my-limit-range
    spec:
      limits:
      - default:
          cpu: "1"
          memory: "2Gi"
        defaultRequest:
          cpu: "0.5"
          memory: "1Gi"
        max:
          cpu: "2"
          memory: "4Gi"
        min:
          cpu: "0.1"
          memory: "100Mi"
        type: Container
  3. PodDisruptionBudget(Pod中断预算): Pod中断预算可以保证在进行维护或升级时,至少有一定数量的Pod处于运行状态。它可以提高应用的可用性,防止因Pod中断导致服务中断。

    你可以使用kubectl create pdb命令来创建Pod中断预算。

    apiVersion: policy/v1
    kind: PodDisruptionBudget
    metadata:
      name: my-pdb
    spec:
      minAvailable: 2 # 至少保持2个Pod可用
      selector:
        matchLabels:
          app: my-app
  4. Node Affinity and Taints/Tolerations(节点亲和性和污点/容忍): 节点亲和性可以让你指定Pod只能调度到特定的节点上,而污点/容忍可以让你防止Pod调度到不合适的节点上。它们可以帮助你更好地控制Pod的调度行为,提高应用的性能和稳定性。

    • Node Affinity:
    apiVersion: v1
    kind: Pod
    metadata:
      name: my-app
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: disktype
                operator: In
                values:
                - ssd
    • Taints and Tolerations:
    # Taint
    kubectl taint nodes <node-name> key=value:NoSchedule
    
    # Toleration in Pod
    apiVersion: v1
    kind: Pod
    metadata:
      name: my-app
    spec:
      containers:
      - name: my-container
        image: my-app-image
      tolerations:
      - key: "key"
        operator: "Equal"
        value: "value"
        effect: "NoSchedule"

第六幕:最佳实践,让你的K8s集群更健康

  1. 监控你的应用: 使用Prometheus、Grafana等监控工具,实时监控你的应用的资源使用情况,及时发现和解决问题。
  2. 根据实际情况调整资源请求和限制: 不要盲目设置资源请求和限制,要根据你的应用的实际需求,不断调整,找到最佳的平衡点。
  3. 使用Horizontal Pod Autoscaler(HPA): HPA可以根据CPU利用率等指标,自动调整Pod的数量,保证应用的性能和可用性。
  4. 定期审查你的资源配置: 定期审查你的资源配额、限制范围、Pod中断预算等配置,确保它们仍然符合你的需求。
  5. 了解你的应用特性: 不同的应用类型(例如:CPU密集型,内存密集型,IO密集型)对资源的需求是不一样的,需要根据应用特性合理设置资源。

总结:

K8s的资源请求和限制是一个非常重要的概念,它可以帮助你更好地管理K8s集群的资源,提高应用的性能和可用性。

希望今天的讲座能对你有所帮助。记住,K8s资源管理就像一场“房产分配”大戏,我们需要精打细算,才能让每个应用都住得舒舒服服,实现“共同富裕”。

谢谢大家!👏

(小李深鞠躬,挥手告别,留下一串神秘的微笑和一句经典台词:“Bug终结者,永远守护你的代码!”) 😊

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注