Deployment 如何强制Kubernetes在每个节点中使用pod更新部署

Deployment 如何强制Kubernetes在每个节点中使用pod更新部署,deployment,kubernetes,google-cloud-platform,Deployment,Kubernetes,Google Cloud Platform,我想知道是否有办法在部署期间强制Kubernetes使用集群中的每个节点。 这个问题是由于我做了一些尝试,我注意到这样的情况: 由3个节点组成的集群 我使用如下命令更新部署:kubectl set image deployment/deployment\u name my\u repo:v2.1.2 Kubernetes更新集群 最后,我执行了kubectl get pod,我注意到在同一个节点中部署了两个pod。 因此,在更新之后,集群具有以下配置: 一个节点有两个豆荚 一个节点和一个吊

我想知道是否有办法在部署期间强制Kubernetes使用集群中的每个节点。 这个问题是由于我做了一些尝试,我注意到这样的情况:

  • 由3个节点组成的集群

  • 我使用如下命令更新部署:
    kubectl set image deployment/deployment\u name my\u repo:v2.1.2

  • Kubernetes更新集群

最后,我执行了
kubectl get pod
,我注意到在同一个节点中部署了两个pod。 因此,在更新之后,集群具有以下配置:

  • 一个节点有两个豆荚
  • 一个节点和一个吊舱
  • 一个节点没有任何pod(完全没有任何工作负载)

调度程序将尝试在给定时间点找出最合理的调度方式,这种方式可能会在以后发生变化,并导致您所描述的情况。两种简单的管理方法是:

  • 使用守护程序而不是部署:将确保每个节点只有一个pod(匹配节点选择器/容差等)
  • 使用PodAntiAffinity:您可以确保同一版本中相同部署的两个pod永远不会部署在同一节点上。这是我个人喜欢的许多应用程序(除非我希望每个节点安排多个应用程序)。请注意,如果您决定将部署扩展到更多的复制副本,那么您就有点麻烦了。 我使用的版本化PodAntiAffinity示例:

    metadata:
      labels:
        app: {{ template "fullname" . }}
        version: {{ .Values.image.tag }}
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values: ["{{ template "fullname" . }}"]
              - key: version
                operator: In
                values: ["{{ .Values.image.tag }}"]
            topologyKey: kubernetes.io/hostname
    
  • 考虑一下,摆弄它就像是Kubes调度器组件的一对邪恶孪生兄弟,这将导致删除它们的POD,然后以不同的方式重新调度


我尝试了一些解决方案,目前的效果只是基于部署中的版本更改。守护程序控制器上的yaml

我的意思是:

1) 我必须在一个带有一些容器的pod上部署我的应用程序。这些pod应该部署在每个集群节点上(我有3个节点)。我在yaml文件中设置了部署设置,选项
replicas
等于3:

apiVersion: apps/v1beta2 # for versions before 1.8.0 use apps/v1beta1
kind: Deployment
metadata:
  name: my-deployment
  labels:
    app: webpod  
spec:
  replicas: 3
....

我在yaml文件中设置了守护程序集(或ds),选项UpdateStregy等于RollingUpdate:

例如,我的一个容器使用的版本是2.1


2) 我使用命令执行部署:
kubectl apply-f my deployment.yaml

我使用命令执行部署:
kubectl apply-f my daemonset.yaml


3) 每个节点都有一个吊舱,没有问题


4) 现在,我想更新部署,更改用于其中一个容器的映像的版本。因此,我只需将yaml文件编辑2.1更改为2.2。然后我重新启动命令:
kubectl apply-f my deployment.yaml

因此,我可以使用以下命令简单地更改图像的版本(2.1->2.2):

kubectl set image ds/my-daemonset my-container=my-repository:v2.2

5) 同样,我为每个节点获得一个pod,没有问题

如果改为使用以下命令,则行为会非常不同:

kubectl set image deployment/my-deployment my-container=xxxx:v2.2
kubectl rollout status ds/my-daemonset
在这种情况下,我得到了一个错误的结果,其中一个节点有2个pod,一个节点1个pod,最后一个节点没有任何pod。。。

要查看部署的进展情况,我可以启动以下命令:

kubectl set image deployment/my-deployment my-container=xxxx:v2.2
kubectl rollout status ds/my-daemonset
得到那样的东西

Waiting for rollout to finish: 0 out of 3 new pods have been updated...
Waiting for rollout to finish: 0 out of 3 new pods have been updated...
Waiting for rollout to finish: 1 out of 3 new pods have been updated...
Waiting for rollout to finish: 1 out of 3 new pods have been updated...
Waiting for rollout to finish: 1 out of 3 new pods have been updated...
Waiting for rollout to finish: 2 out of 3 new pods have been updated...
Waiting for rollout to finish: 2 out of 3 new pods have been updated...
Waiting for rollout to finish: 2 out of 3 new pods have been updated...
Waiting for rollout to finish: 2 of 3 updated pods are available...
daemon set "my-daemonset" successfully rolled out

我正在阅读文档(),这正是我想要的。但是有没有办法创建一个yaml部署文件来确保每个pod都部署在一个节点上?因此,要执行的是一个文件,而不是示例中的两个不同的yaml文件。我尝试使用PodAntiAffinity和deployment选项,但现在我面临另一个问题。事实上,当我尝试使用命令更新部署时:
kubectl set image deployment/apache deployment my_repo:v2.1.2
,我得到了一个错误:
apache-deployment-7c774d67f5-l69lb没有匹配所有谓词的节点可用:matcheinterpodafinity(3)
。有什么建议吗?这很奇怪,因为我从这里描述的示例()中获取了代码,只更改了应用程序的名称。部署正在工作,因此yaml文件应该是正确的。当我尝试更新部署时,问题就出现了,这是有道理的:)如果你更新,事情可能会变得有点棘手。这就是为什么我有两个用于反亲和性的标签,比如
app:myapp
version:v1.0.1
,这样反亲和性只限制相同版本的pod。请提供一个带有两个参数的pod反亲和性匹配表达式的示例?因为我不明白当您必须更新到1.0.2时,如何管理yaml文件中的
版本:v1.0.1
(即硬编码)