如何强制将Pods/Deployments调度到Master节点?

20

我已经设置了一个 Kubernetes 1.5 集群,并将三个主节点标记为 dedicated=master:NoSchedule。现在我想仅在主节点上部署 Nginx Ingress Controller,因此我已添加了 tolerations:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-ingress-controller
  namespace: kube-system
  labels:
    kubernetes.io/cluster-service: "true"
spec:
  replicas: 3
  template:
    metadata:
      labels:
        k8s-app: nginx-ingress-lb
        name: nginx-ingress-lb
      annotations:
        scheduler.alpha.kubernetes.io/tolerations: |
          [
            {
              "key": "dedicated",
              "operator": "Equal",
              "value": "master",
              "effect": "NoSchedule"
            }
          ]
    spec:
    []

很遗憾,这并没有产生期望的效果:Kubernetes会在工作节点上调度所有Pod。当将副本数扩展到更大的数量时,Pod也会部署在工作节点上。

我如何只将Pod调度到Master节点上?

感谢您的帮助。

4个回答

27

容忍并不意味着Pod必须被调度到具有这种污点的节点上,而是表示Pod可以容忍这种污点。如果您希望将Pod“吸引”到特定的节点上,则需要将标签附加到专用Master节点,并在Pod中设置nodeSelector以查找该标签。

将标签附加到每个特殊使用节点:

kubectl label nodes name_of_your_node dedicated=master

Kubernetes 1.6及以上版本的语法

将nodeSelector加入您的pod中:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx-ingress-controller
  namespace: kube-system
  labels:
    kubernetes.io/cluster-service: "true"
spec:
  replicas: 3
  template:
    metadata:
      labels:
        k8s-app: nginx-ingress-lb
        name: nginx-ingress-lb
      annotations:
    spec:
      nodeSelector:
        dedicated: master
      tolerations:
      - key: dedicated
        operator: Equal
        value: master
        effect: NoSchedule
    []
如果你不喜欢nodeSelector,你可以在spec:下面添加affinity:
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
        matchExpressions:
        - key: dedicated
          operator: Equal
          values: ["master"]

1.6之前的语法

将nodeSelector添加到您的Pod中:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-ingress-controller
  namespace: kube-system
  labels:
    kubernetes.io/cluster-service: "true"
spec:
  replicas: 3
  template:
    metadata:
      labels:
        k8s-app: nginx-ingress-lb
        name: nginx-ingress-lb
      annotations:
        scheduler.alpha.kubernetes.io/tolerations: |
          [
            {
              "key": "dedicated",
              "operator": "Equal",
              "value": "master",
              "effect": "NoSchedule"
            }
          ]
    spec:
      nodeSelector:
        dedicated: master
    []

如果您不喜欢使用nodeSelector,您也可以添加类似这样的注释:

如果您不喜欢使用nodeSelector,您也可以添加类似这样的注释:

scheduler.alpha.kubernetes.io/affinity: >
  {
    "nodeAffinity": {
      "requiredDuringSchedulingIgnoredDuringExecution": {
        "nodeSelectorTerms": [
          {
            "matchExpressions": [
              {
                "key": "dedicated",
                "operator": "Equal",
                "values": ["master"]
              }
            ]
          }
        ]
      }
    }
  }

请注意,NoSchedule不会驱逐已经被调度的Pod。

上述信息来自https://kubernetes.io/docs/user-guide/node-selection/,并且那里还有更多细节。


工作正常。根据文档,nodeSelector 将继续像往常一样工作,但最终将被弃用,因为节点亲和力可以表达 nodeSelector 可以表达的所有内容。因此最好直接使用亲和性和反亲和性... - Stephan
1
至少在我的情况下(kubernetes版本1.11),tolerations需要一个数组,因此我不得不在“key”标签前面添加“-”,例如:“- key:dedicated”。我不知道这是否是v.1.11中的新添加还是自1.6以来的某个早期版本,但值得一提。 - Liquid
@JanosLenart,能否将 dedicated->master 标签与 k8s 自动放置的 node-role.kubernetes.io/master-> 标志(无值标签)进行交换? - Adirio

3
  tolerations:
  - key: node-role.kubernetes.io/master
    effect: NoSchedule

4
请勿仅以代码作为答案,同时提供解释您的代码是如何解决问题的,并且如何实现其功能。带有解释的答案通常质量更高,更可能吸引点赞。 - Mark Rotteveel
1
我在过去的15分钟内使用了多个搜索引擎,但这个答案立即帮助了我并给了我想要的答案。只有那两行代码就是我一直在寻找的东西。我的错误在于我没有在结尾处使用“/master”,因此我的Pod未按预期计划。有时候,不需要太多的言语,只需要代码。 - maiky

0
在我的情况下,我必须指定以下内容。
tolerations:
- effect: NoSchedule
  operator: Exists
- key: CriticalAddonsOnly
  operator: Exists
- effect: NoExecute
  operator: Exists

0

如果您想深入了解将Pod分配给节点文档,请参考以下内容:基本上,您应该向节点添加一些标签,例如:

kubectl label nodes <node-name> <label-key>=<label-value>

然后在你的Pod规范中引用它,就像这样:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
  nodeSelector:
    label: value

但是我不确定当特定节点被污染时,这是否适用于非关键插件。更多细节可以在这里找到。


主节点通常具有污点,因此“nodeSelector”不足,Pod还需要容忍。 - Đinh Anh Huy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接