不允许在kubernetes中的同一节点上使用同一应用程序的两个Pod

时间:2019-10-07 14:52:48

标签: kubernetes

我们现在遇到的情况是两个相同类型的Pod可以在同一节点上运行。有时,在重新启动和重新调度期间,两个Pod恰好位于同一节点上,并且当重新调度此节点本身时,我们所有的Pod都消失了一段时间,从而导致了连接故障(我们只有2个Pod已实现负载平衡)。

我认为解决此问题的最佳方法是不允许2个Pod在同一节点上运行,并为此使用Pod间反亲和力。

这是解决问题的正确方法吗?我试图理解它,但对topologyKey和语法感到有些困惑。有人可以解释/给出有关如何实现此目标的示例吗?

4 个答案:

答案 0 :(得分:2)

是的,您是对的Affinity是您在这里的朋友,并且是正确的解决方案。

Node Affinity:将帮助您的应用程序或微服务坚持某种特定类型的节点(在多节点体系结构中),例如在我的应用程序ngnix-ms下面始终坚持具有标签role=admin的节点。

pod antiAffinity规则:粘贴节点标签(topologyKey),并确保该节点组(标有topologyKey)。

如果有一个节点已经有一个标签为component=nginx的Pod,则K8将不允许旋转Pod。

以下是说明:

affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
          - matchExpressions:
            - key: role
              operator: In
              values:
              - app-1
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchExpressions:
              - key: component
                operator: In
                values:
                - nginx-ms
          topologyKey: "kubernetes.io/1-hostname"

kubectl get node --show-labels

NAME                  STATUS   ROLES    AGE   VERSION   LABELS
xx-admin-1      Ready    master   19d   v1.13.4   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/1-hostname=xx-admin-1,node-role.kubernetes.io/master=,role=admin
xx-admin-2      Ready    master   19d   v1.13.4   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/1-hostname=xx-admin-2,node-role.kubernetes.io/master=,role=admin
xx-plat-1-1     Ready    <none>   19d   v1.13.4   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/2-hostname=xx-plat-1-1,role=admin
xx-plat-2-1     Ready    <none>   19d   v1.13.4   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/2-hostname=xx-plat-2-1,role=admin

topologyKey的说明: 将其视为一个标签,现在您可以在同一群集中拥有两种不同的拓扑。

示例:kubernetes.io/1-hostnamekubernetes.io/2-hostname

现在,当您执行podAntinity时,您可以设置`topologyKey:

kubernetes.io/1-hostname

这时,您的规则在具有该拓扑密钥的所有节点中均有效,但在标记为topologyKey: kubernetes.io/2-hostname的节点中该规则无效。

因此,在我的示例中,pod被安排在带有标签kubernetes.io/1-hostname的节点内,并且隐含了podAntiAffinity,但是带有标签kubernetes.io/2-hostname的节点没有podAntiAffinity规则!

答案 1 :(得分:1)

我认为您需要为此创建NodeAffinity和污点。

用于节点关联

    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
          - matchExpressions:
            - key: role
              operator: In
              values:
              - app

用于污渍使用 kubectl taint nodes <nodename> key=example-key:NoSchedule

将此添加到您的yaml文件中。

  tolerations:
  - key: "example-key"
    operator: "Exists"
    effect: "NoSchedule"


答案 2 :(得分:1)

我最终决定不使用Pod Anti Affinity,而是使用Kubernetes中一种更简单的机制,即Pod Disruption Budget。一般说来,至少X个吊舱必须在给定的时间运行。

PS C:\Users\Administrator> (Get-Counter -Counter "\TCPv4\Connections Established").CounterSamples.CookedValue
DEBUG:    1+ (Get-Counter -Counter "\TCPv4\Connections Established").CounterSamples. <<<< CookedValue
DEBUG:    2+         $foundSuggestion = <<<<  $false
DEBUG:     ! SET $foundSuggestion = 'False'.
DEBUG:    4+         if <<<< ($lastError -and
DEBUG:   15+         $foundSuggestion <<<<

这将不允许在另一个Pod启动并运行之前将Pod逐出。这样可以解决节点受控的停机时间问题,但是如果节点无法控制的停机(硬件故障等),则无法保证,但希望这种情况不会经常发生。

答案 3 :(得分:0)

还有另一种出路,如果您不使用如上所述的Pod亲和力(或使用任何此类网络策略来简化操作),那么即使您的Node出现故障,您仍然可以实时处理此情况

设置警戒线,以便它不再出现在kubernetes上进行流量调度,最终它将对其他正在运行的节点执行此操作。

请浏览附件文件。

最后,一旦准备就绪,您就可以取消密码。cordon and uncordon the node