我们现在遇到的情况是两个相同类型的Pod可以在同一节点上运行。有时,在重新启动和重新调度期间,两个Pod恰好位于同一节点上,并且当重新调度此节点本身时,我们所有的Pod都消失了一段时间,从而导致了连接故障(我们只有2个Pod已实现负载平衡)。
我认为解决此问题的最佳方法是不允许2个Pod在同一节点上运行,并为此使用Pod间反亲和力。
这是解决问题的正确方法吗?我试图理解它,但对topologyKey
和语法感到有些困惑。有人可以解释/给出有关如何实现此目标的示例吗?
答案 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-hostname
和kubernetes.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)