我有一个看起来像这样的Kubernetes部署(用'....'替换名称和其他东西):
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "3"
kubernetes.io/change-cause: kubectl replace deployment ....
-f - --record
creationTimestamp: 2016-08-20T03:46:28Z
generation: 8
labels:
app: ....
name: ....
namespace: default
resourceVersion: "369219"
selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/....
uid: aceb2a9e-6688-11e6-b5fc-42010af000c1
spec:
replicas: 2
selector:
matchLabels:
app: ....
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: ....
spec:
containers:
- image: gcr.io/..../....:0.2.1
imagePullPolicy: IfNotPresent
name: ....
ports:
- containerPort: 8080
protocol: TCP
resources:
requests:
cpu: "0"
terminationMessagePath: /dev/termination-log
dnsPolicy: ClusterFirst
restartPolicy: Always
securityContext: {}
terminationGracePeriodSeconds: 30
status:
availableReplicas: 2
observedGeneration: 8
replicas: 2
updatedReplicas: 2
我正在观察的问题是Kubernetes在同一节点上放置了两个副本(在部署中我要求两个)。如果该节点出现故障,我将丢失两个容器,并且该服务将脱机。
我想要Kubernetes做的是确保它不会在容器属于同一类型的同一节点上加倍容器 - 这只会消耗资源而不提供任何冗余。我查看了有关部署,副本集,节点等的文档,但我找不到任何可以告诉Kubernetes这样做的选项。
有没有办法告诉Kubernetes我想要一个容器的节点有多少冗余?
编辑:我不确定标签是否有效;标签约束节点将在哪里运行,以便它可以访问本地资源(SSD)等。我想要做的就是确保节点脱机时不会出现停机。
答案 0 :(得分:10)
我认为你正在寻找亲和/抗亲和选择者。
Affinity用于协同定位pod,因此我希望我的网站尝试在与我的缓存相同的主机上进行安排。另一方面,反亲和力是相反的,不按照一套规则在主机上安排。
因此,对于您正在做的事情,我会仔细研究这两个链接: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#never-co-located-in-the-same-node
https://kubernetes.io/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure
答案 1 :(得分:9)
如果您为该部署创建服务, 之前创建所述部署,Kubernetes将在节点之间传播您的pod。此行为来自Scheduler,它是在尽力而为的基础上提供的,只要您在两个节点上都有足够的可用资源。
来自Kubernetes文档(Managing Resources):
最好先指定服务,因为这样可以确保调度程序可以扩展与服务关联的pod,因为它们是由控制器创建的,例如部署。
答案 2 :(得分:2)
There is now a proper way of doing this. 如果只想将标签散布在所有节点上,则可以使用“ kubernetes.io/hostname”中的标签。意思是,如果您有一个Pod的两个副本和两个节点,则如果它们的名称不同,则每个节点都应该得到一个副本。
答案 3 :(得分:1)
如果某个节点发生故障,其上运行的任何pod都将在另一个节点上自动重启。
如果你开始准确指定它们想要运行的位置,那么你实际上已经失去了Kubernetes在不同节点上重新安排它们的能力。
通常的做法是简单地让Kubernetes做它的事情。
但是,如果您确实有特定要求在特定节点上运行pod,由于某些本地卷类型的要求等,请阅读:
答案 4 :(得分:1)
我同意Antoine Cotten为您的部署使用服务。如果由于某种原因,某个pod在某个节点中死亡,则服务始终通过创建新pod来保持任何服务。但是,如果您只想在所有节点之间分发部署,则可以在pod清单文件中使用pod anti affinity。我在gitlab page上添加了一个示例,您也可以在Kubernetes Blog找到该示例。为了您的方便,我也在这里提供示例。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- nginx
topologyKey: kubernetes.io/hostname
containers:
- name: nginx
image: gcr.io/google_containers/nginx-slim:0.8
ports:
- containerPort: 80
在此示例中,每个Deployment都有一个标签,即app,此标签的值为nginx。在pod规范中,您有podAntiAffinity,它将限制在一个节点中拥有两个相同的pod(标签app:nginx)。如果要在一个节点中放置多个部署,也可以使用podAffinity。
答案 5 :(得分:0)
也许DaemonSet
会更好用。我正在使用DaemonStets
和nodeSelector
在特定节点上运行pod并避免重复。