如何跨节点分发部署?

Jun*_*des 22 google-cloud-platform kubernetes

我有一个看起来像这样的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
Run Code Online (Sandbox Code Playgroud)

我观察到的问题是Kubernetes在同一节点上放置了两个副本(在部署中我要求两个).如果该节点出现故障,我将丢失两个容器,并且该服务将脱机.

我希望Kubernetes做的是确保它不会使容器属于同一类型的同一节点上的容器加倍 - 这只消耗资源而不提供任何冗余.我查看了有关部署,副本集,节点等的文档,但我找不到任何可以让我告诉Kubernetes这样做的选项.

有没有办法告诉Kubernetes我想要一个容器的节点有多少冗余?

编辑:我不确定标签是否有效; 标签约束节点将在哪里运行,以便它可以访问本地资源(SSD)等.我想要做的就是确保节点脱机时不会出现停机.

小智 14

现在有一种正确的方法可以做到这一点。 如果您只想将其分布在所有节点上,您可以使用“kubernetes.io/hostname”中的标签。这意味着如果您有一个 pod 的两个副本和两个节点,如果它们的名称不同,则每个副本都应该得到一个。

  • 接受的答案应该更改为这个。这需要更多的支持。从K8s 1.19开始就是这样了。 (16认同)

小智 11

我想你正在寻找亲和/抗亲和选择器.

Affinity用于协同定位pod,因此我希望我的网站尝试在与我的缓存相同的主机上进行安排.另一方面,反亲和力是相反的,不按照一组规则在主机上安排.

所以对于你正在做的事情,我会仔细研究这两个链接:https: //kubernetes.io/docs/concepts/configuration/assign-pod-node/#never-co-located-in-the-同一节点

https://kubernetes.io/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure

  • 这不再是这个问题的最佳答案。从 Kubernetes 1.19 开始,您可以使用拓扑约束来执行此操作。接受的答案应更改为 Anton Blomström 的答案。 (3认同)

Ant*_*ten 9

如果为该部署创建服务,则创建所述部署之前,Kubernetes将在节点之间传播您的pod.此行为来自Scheduler,它是在尽力而为的基础上提供的,前提是您在两个节点上都有足够的可用资源.

从Kubernetes文档(管理资源):

最好先指定服务,因为这样可以确保调度程序可以扩展与服务关联的pod,因为它们是由控制器创建的,例如Deployment.

还相关:配置最佳实践 - 服务.


Abu*_*oeb 6

我同意 Antoine Cotten 使用服务进行部署。如果由于某种原因某个节点中的某个 Pod 即将死亡,服务始终会通过创建新的 Pod 来保持任何服务的运行。但是,如果您只想在所有节点之间分配部署,那么您可以在 pod 清单文件中使用 pod 反亲和力。我在gitlab 页面上放了一个示例,您也可以在Kubernetes 博客中找到该示例。为了您的方便,我也在此处提供示例。

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
Run Code Online (Sandbox Code Playgroud)

在这个例子中,每个Deployment都有一个标签为app,该标签的值为nginx。在 pod 规范中,您有 podAntiAffinity,它将限制在一个节点中拥有两个相同的 pod(标签 app:nginx)。如果您想在一个节点中放置多个 Deployment,您还可以使用 podAffinity。

  • 服务不会创建或重新启动 Pod。这是由部署启动的副本集完成的。该服务仅收集可用端点。 (3认同)
  • 在上面的 yaml 片段中,“topologyKey”元素的缩进已关闭,它应该与“labelSelector”处于同一级别,请参阅文档中的示例:https://kubernetes.io/docs/concepts/configuration/assign -pod-node/#亲和力和反亲和力 (3认同)