首页 > 解决方案 > Kubernetes 节点自动缩放和对每个节点的 pod 的精细控制

问题描述

我正在尝试在 Kubernetes 中复制 Azure Batch API,我有一个作为服务运行的 Web api,而它又使用 Kubernetes API 来动态创建批处理作业。

到目前为止,一切都很好。

我遇到困难的地方通常是这些作业中的每个任务都是一些非常困难的 TensorFlow 深度学习,所以理想情况下,我希望 Kubernetes 只为每个节点安排一个 pod,然后结合节点自动缩放器,它可以根据需要扩展我的集群。

在 Azure Batch 中,可以基于每个作业指定每个 VM 的任务,类似于 Kubernetes 中每个节点的 pod。似乎 Kubernetes API 不支持这一点,只能通过 kubelet max pods 配置获得,这并不理想,因为它比我想要的更硬编码。

所以我的问题是有一种方法可以在作业规范中使用某种指标来强制 Kubernetes 限制每个节点的 pod 实例。理想情况下,这将是调度程序的主动决策,因为它不会调度 Pod,只是稍后才意识到它没有获得任何资源。

标签: kubernetes

解决方案


您可以使用 pod 亲和性/反亲和性规则来确保一旦特定应用程序的一个 pod 被调度到一个节点上,那么同一应用程序的其他 pod 不会被调度到该节点上。

从文档网站复制 Redis 的示例部署:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-cache
spec:
  selector:
    matchLabels:
      app: store
  replicas: 3
  template:
    metadata:
      labels:
        app: store
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - store
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: redis-server
        image: redis:3.2-alpine

这将确保在单个节点上 - 只有一个 Redis 缓存实例正在运行。需要注意的一些关键事项:

  1. 标签app=store对于识别应用程序很重要

  2. 使用标签 - 匹配节点的主机名来决定调度:topologyKey: "kubernetes.io/hostname"

  3. experssionrequiredDuringSchedulingIgnoredDuringExecution确保这是调度期间的一个艰难决定,如果不满足条件,则不会执行 pod 调度。

请在此处查看各种日程安排选项以获取更多详细信息。


推荐阅读