首页 > 解决方案 > Kubernetes pod 规范 - 是否可以指定 NodeAffinity 来选择请求最多的节点

问题描述

我正在尝试让 kubernetes 在请求最多的节点上创建新的 pod,而不是让 pod 将负载分散到可用节点上。基本原理是,如果 pod 被移动并且节点在自动缩放期间被杀死,这可以简化缩减场景和重新启动应用程序。

除垢的首选策略是 - 1)如果有任何正在运行的 pod,则永远不要杀死节点 2)优先在请求最多的节点上创建新的 pod 3)作业完成后 pod 将自毁。随着时间的推移,这应该会在任务完成后产生空闲节点,因此除垢将是安全的,我不需要担心正在运行的作业的弹性。

为此,有什么方法可以在 pod 规范中指定 NodeAffinity,例如:

    spec:
      affinity:
        nodeAffinity:
          RequiredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              nodeAffinityTerm: {MostRequestedPriority}

上面的代码没有效果。的文档NodeAffinity没有指定我是否可以MostRequestedPriority在这种情况下使用。MostRequestedPriority是 kubernetes 调度程序服务规范中的一个选项。但我想看看我是否可以直接将 t 放入 pod 规范中,而不是创建一个新的自定义 kubernetes 调度程序。

标签: kubernetes

解决方案


不幸的是,没有选项可以传递MostRequestedPriority给 nodeAffinity 字段。但是,您可以创建简单的调度程序来管理 pod 调度。以下配置就足够了。

首先,您必须为此调度程序创建Service Account和:ClusterRoleBinding

apiVersion: v1
kind: ServiceAccount
metadata:
  name: own-scheduler
  namespace: kube-system

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: own-scheduler
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: own-scheduler
  namespace: kube-system

然后使用所需policy字段创建配置映射,包括MostRequestedPriority. 谓词中的每个字段都可以修改以最好地满足您的需求,基本上它的作用是过滤节点以查找可以放置 pod 的位置,例如,PodFitsResources过滤器检查节点是否有足够的可用资源来满足 Pod 的特定资源要求:

apiVersion: v1
kind: ConfigMap
metadata:
  labels:
  k8s-addon: scheduler.addons.k8s.io
  name: own-scheduler
  namespace: kube-system
data:
  policy.cfg: |-
  {
  "kind" : "Policy",
  "apiVersion" : "v1",
  "predicates" : [
  {"name" : "PodFitsHostPorts"},
  {"name" : "PodFitsResources"},
  {"name" : "NoDiskConflict"},
  {"name" : "PodMatchNodeSelector"},
  {"name" : "PodFitsHost"}
  ],
  "priorities" : [
  {"name" : "MostRequestedPriority", "weight" : 1},
  {"name" : "EqualPriorityMap", "weight" : 1}
  ]
  }

然后将其包装在 Deployment 中:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    component: scheduler
    tier: control-plane
  name: own-scheduler
  namespace: kube-system
spec:
  selector:
    matchLabels:
      component: scheduler
      tier: control-plane
  replicas: 1
  template:
    metadata:
      labels:
        component: scheduler
        tier: control-plane
        version: second
    spec:
      serviceAccountName: own-scheduler
      containers:
      - command:
        - /usr/local/bin/kube-scheduler
        - --address=0.0.0.0
        - --leader-elect=false
        - --scheduler-name=own-scheduler
        - --policy-configmap=own-scheduler
        image: k8s.gcr.io/kube-scheduler:v1.15.4
        livenessProbe:
          httpGet:
            path: /healthz
            port: 10251
          initialDelaySeconds: 15
        name: kube-second-scheduler
        readinessProbe:
          httpGet:
            path: /healthz
            port: 10251
        resources:
          requests:
            cpu: '0.1'
        securityContext:
          privileged: false
        volumeMounts: []
      hostNetwork: false
      hostPID: false
      volumes: []

推荐阅读