部署选择器未选择 Pod

Pod is not getting selected by Deployment selector

我有这个部署对象:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-webserver-nginx
  annotations:
    description: This is a demo deployment for nginx webserver 
  labels:
    app: deployment-webserver-nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: deployment-webserver-pods
  template:
    metadata:
      labels:
        app: deployment-webserver-pods
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        ports:
        - containerPort: 80

我对这个 Deployment 对象的理解是,任何带有 app:deployment-webserver-pods 标签的 Pod 都会被选中。当然,这个 Deployment 对象创建了 3 个副本,但是我想像这样显式地添加一个 Pod,所以我创建了一个 Pod 对象并将其标签设置为 app:deployment-webserver-pods,下面是它的 Pod 定义:

apiVersion: v1
kind: Pod
metadata:
  name: deployment-webserver-nginx-extra-pod
  labels:
    app: deployment-webserver-pods
spec:
  containers:
  - name: nginx-alpine-container-1
    image: nginx:alpine
    ports:
      - containerPort: 81

我的期望是连续 运行 Deployment Controller 会选择这个新的 Pod,当我这样做时 kubectl get deploy 然后我会看到 4 pods 运行。但那并没有发生。

我什至尝试先用这个标签创建这个 pod,然后创建我的 Deployment,我想也许现在这个明确的 Pod 会被选中,但仍然没有发生。

标签和选择器不是这样工作的吗? 我知道我可以通过部署扩展到 4 个副本,但我想了解如何使用标签和选择器选择 Pods/其他 Kubernetes 对象。

My expectation was that continuously running Deployment Controller will pick this new Pod, and when I do kubectl get deploy then I will see 4 pods running. But that didn't happen.

Deployment Controller 不是那样工作的,它会侦听 Deployment-资源并将它们“驱动”到所需状态。这通常意味着,如果 template: 部分发生任何变化,则会创建一个具有副本数量的新 ReplicaSet。除了更改 replicas: 之外,您不能以其他方式将 Pod 添加到 Deployment - 每个实例都是从相同的 Pod 模板创建的并且是相同的。

Doesn't Labels and Selectors work like this?

... but I am trying to understand how Pods / other Kubernetes objects are selected using Labels and Selectors.

是的,标签和选择器在 Kubernetes 中用于很多事情,但并非用于所有事情。当您创建一个带有标签的 Deployment 和一个带有相同标签的 Pod,最后是带有 select 的 Service 或 - 然后指向该服务的流量将把流量分配给您的 Deployment 实例以及您的额外 Pod。

示例:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: deployment-webserver-pods
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080

Labels and Selector 在使用例如kubectl。您可以为 Teams 添加标签,例如应用程序,那么您可以 select 所有部署或 Pods 属于该团队或应用程序(例如,如果该应用程序包含应用程序部署和缓存部署),例如:

kubectl get pods -l team=myteam,app=customerservice

My expectation was that continuously running Deployment Controller will pick this new Pod, and when I do kubectl get deploy then I will see 4 pods running. But that didn't happen.

Kubernetes 是一个运行“声明式”而不是“命令式[​​=17=]”的系统,这意味着您写下应用程序的期望状态通常通过 YAML 文件在集群中,这些声明的所需状态定义了应用程序的所有部分。

如果按照您期望的方式强制配置集群,将很难理解和复制集群是如何进入该状态的。

来自official docs

Note: You should not create other Pods whose labels match this selector, either directly, by creating another Deployment, or by creating another controller such as a ReplicaSet or a ReplicationController. If you do so, the first Deployment thinks that it created these other Pods. Kubernetes does not stop you from doing this.

如文档中所述,不建议使用上述方法扩展部署的副本。


文档同一部分要注意的另一个要点:

If you have multiple controllers that have overlapping selectors, the controllers will fight with each other and won't behave correctly.

在上面的解释中补充一下,如果我们尝试手动创建 pod 并进行管理,那么在 K8s 中设置控制器的目的是什么。

My expectation was that continuously running Deployment Controller will pick this new Pod, and when I do kubectl get deploy then I will see 4 pods running. But that didn't happen.

根据您的 yaml replicas:3 已经设置,因此部署不会将新的 pod 作为第 4 个副本。