Kubernetes pod 在内存不足时传输

Kubernetes pod transferring on insufficient memory

我正在尝试找到一种优雅的方法来解决以下情况。

我们有一个 ASW Kubernetes 集群,每个集群有 6 个 16G 内存的节点, 集群有各种 pods 资源需求在 1G 到 6G 之间的最小请求内存。

有一种情况是由于内存不足导致 pod 挂起。 当我们需要升级一些具有不同内存要求的 pods 时,就会发生这种情况。由于没有节点有 6G 可用,因此具有 6G 的 pod 正在等待处理。

我希望 Kubernetes 在节点之间重新安排 pods,以便在特定节点上释放 6G,而不是在两个差异注释(总共 10G)和 returns 上保持 5G 空闲内存不足。

有没有办法让 Kubernetes 更好地初始化内存并自动处理。

我在考虑 pod 优先级功能。内存请求越少,优先级越低。想知道基于此设置,Kubernetes 是否能够在部署较大的 pod 后重新启动不太重要(较小)的 pod,以这种方式在节点之间重新排列它们。

任何想法将不胜感激

默认情况下,Kubernetes 调度程序永远不会终止任何容器以容纳更新的容器。那是因为如果这样做,运行 容器可能会被迫在其他节点上重新安排,这是不希望的。 Kubernetes 会尊重集群的当前状态并努力保持稳定的环境。

关于这个问题你可以做的是,当你部署 6G RAM 应用程序时,你可以部署它然后删除 1G RAM 请求 pods,这样 Kubernetes 调度程序可以先在可用节点上部署更大的应用程序并部署其他 pods到其他节点。这也是 Kubernetes 调度程序的默认操作,总是尝试先放置较大的部分,以便它也可以更好地放置较小的部分。

没有银弹解决方案,但您可以使用 Pod Affinity/Pod AntiAffinity, Node Affinity, and Pod Topology Spread Constraints 进行组合操作。它还取决于您的工作负载优先级。

如果你有 6 个节点,你可以有这样的东西:

NAME    STATUS   ROLES    AGE     VERSION   LABELS
node1   Ready    <none>   4m26s   v1.16.0   node=node1,type=heavy
node2   Ready    <none>   3m58s   v1.16.0   node=node2,type=heavy
node3   Ready    <none>   3m17s   v1.16.0   node=node3,type=heavy
node4   Ready    <none>   2m43s   v1.16.0   node=node4,type=light
node5   Ready    <none>   3m17s   v1.16.0   node=node5,type=light
node6   Ready    <none>   2m43s   v1.16.0   node=node6,type=light

然后在您的 6G Pod 规范中,它将根据具有 PodAffinity 的重 pods 在重节点上以 3 的倾斜度安排在 node1-node6 上。

kind: Pod
apiVersion: v1
metadata:
  name: mypod
  labels:
    workload: heavy
spec:
  topologySpreadConstraints:
  - maxSkew: 3
    topologyKey: type
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        workload: heavy
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: workload
            operator: In
            values:
            - heavy
        topologyKey: type
  containers:
  - name: myheavyapp
    image: myapp:latest
  ...

然后您可以使用 NodeAffinity 仅在轻型节点上安排您的 1G 轻型 pods。

kind: Pod
apiVersion: v1
metadata:
  name: mylightpod
  labels:
    workload: light
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: type
            operator: In
            values:
            - light
    ...

这只是一个示例,您可以更改标签和倾斜以适应您的任何用例。

此外,为了防止停机,您可以配置 PodDisruptionBudget