如何跨节点分发部署?

时间:2016-08-23 03:56:12

标签: kubernetes google-cloud-platform

我有一个看起来像这样的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)等。我想要做的就是确保节点脱机时不会出现停机。

6 个答案:

答案 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,因为它们是由控制器创建的,例如部署。

还相关:Configuration best practices - Service

答案 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会更好用。我正在使用DaemonStetsnodeSelector在特定节点上运行pod并避免重复。

http://kubernetes.io/docs/admin/daemons/