Kubernetes Label && Selector

Kubernetes-BestPractices

Author:rab



前言

在 Kubernetes 中,Label 和 Selector 是用于标识和选择对象的两个关键概念,它们在定义和管理资源对象之间的关系和关联时非常有用。

一、Labels

1.1 定义

Label 是键值对(key-value),可以附加到 K8s 对象上,如 Pod、Service、Deployment 等,允许您自定义对象的属性,例如,您可以为一个 Pod 添加标签来指示其用途、环境或拥有者(如 app=web, environment=production, owner=ops)。Label 用于标识和分类对象,以及在不同的上下文中筛选和选择这些对象,但不会对对象的行为产生直接影响。

1.2 案例

1.2.1 节点标签

默认情况下,Scheduler 会将 Pod 调度到所有可用的 Work 节点,不过在某些情况下我们需要将 Pod 部署到指定的 Work 节点,比如将有大量磁盘 I/O 的 Pod 部署到有 SSD 的 work 节点上来保证其 I/O。

kubectl label node k8s-work2 disktype=ssd

如何查看节点的标签?

# 查看所有节点标签
kubectl get node --show-labels

# 查看指定节点标签
kubectl get node k8s-work2 --show-labels

image-20231026143640117

那如何根据标签反查询其对应的资源呢?

kubectl get node -l disktype=ssd

# 该命令就可以查出哪些节点具备disktype=ssd标签

image-20231026143852724

1.2.2 对象标签

我们除了给节点打标签,也可对 Pod、Service、Deployment 等对象进行标签,一般地,我们会在 yaml 文件直接指定对应资源的标签,当然你也可以通过命令的方式给对象添加标签。

1、命令行模式

kubectl label svc mynginx -n yournamespace env=canary version=v1

# 将service资源mynginx打上两个标签,分别为env=canary标签和version=v1标签

2、Yaml 文件的方式

apiVersion: apps/v1
kind: Deployment
metadata:
  name: example-deployment
spec:
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: nginx:latest

labels: 处进行标签定义,同样可定义多组标签,该案例的标签为app: my-app

如何查看节点的标签?

# 查看所有service标签
kubectl get svc -n yournamespace --show-labels

# 查看指定service标签
kubectl get svc mynginx -n yournamespace --show-labels

那如何根据标签反查询其对应的资源呢?

# 查看所有名称空间下具有version=v1标签的资源
kubectl get svc --all-namespaces -l version=v1

# 查看指定名称空间下具有version=v1标签的资源
kubectl get svc -n yournamespace -l version=v1

二、Selector

在 Kubernetes 中,Selectors(选择器)用于根据标签(Labels)来筛选和选择资源对象。Selectors 是用于定义关联性和依赖性,以及在不同对象之间建立关系的关键概念。

2.1 Node Selector

该选择器用于将 Pod 部署到你指定标签的主机节点上,具体 yml 配置如下。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: demo
spec:
  replicas: 4
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
      - name: nginx
        image: nginx:1.20.0
        ports:
        - containerPort: 80
      nodeSelector:
        disktype: ssd

这样的话,我的 Nginx 服务就会部署在节点标签为disktype: ssd 的节点上。

2.2 Service Selector

在 Kubernetes 中,Service 资源通常使用 Selectors 来选择与其关联的 Pod。Service 允许您将请求路由到匹配特定标签的 Pod。例如,您可以创建一个 Service,并使用 Label Selector 来将它关联到特定的应用程序或版本,然后通过 Service 来访问这些 Pod。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nginx
  namespace: myweb-2
  labels:
    app: stateful
spec:
  serviceName: myweb-2
  replicas: 5
  updateStrategy:
    type: RollingUpdate
  selector:
    matchLabels:
      app: demo-2
  template:
    metadata:
      labels:
        app: demo-2
    spec:
      containers:
      - name: nginx
        image: nginx:1.21.4
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-srv
  namespace: myweb-2
spec:
  selector:
    app: demo-2
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30334
  type: NodePort

看 yml 文件最后的 Service 部分 spec.selector 中,app: demo-2 就是指与 Service 关联的 Pod 资源,只要是在该名称空间中具备 app: demo-2 标签的 Pod 都归这个 Service “管理”

2.3 Deployment Selector

在 ReplicaSet 和 Deployment 配置中,Selector 用于确定这些控制器将管理哪些 Pod。当创建 ReplicaSet 或 Deployment 时,您可以指定它们的 Selector,以确保它们管理具有特定标签的 Pod。

apiVersion: v1
kind: Namespace
metadata:
  name: myweb
  labels:
    name: ops
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: myweb
  labels:
    app: webdemo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
      - name: nginx
        image: nginx:1.21.4
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-srv
  namespace: myweb
spec:
  selector:
    app: demo
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30333
  type: NodePort

看 yml 文件中间的 Deployment 部分 spec.selector.matchLabels 中,app: demo 就是指与 Deployment 关联的 Pod 资源,这些 Pod 都归这个 Deployment “管理”

2.4 StatefulSet Selector

StatefulSet Selector 与 Deployment Selector 类似(这里不再案例演示),它也是使用 Selector 来选择要管理的 Pod。不同之处在于,StatefulSet 管理有状态应用,通常需要将每个 Pod 命名并标记为特定的次序(自动命令)。

2.5 DaemonSet Selector

同样与 Deployment Selector 类似(这里不再案例演示),在 DaemonSet 中,Selector 用于选择在每个节点上运行的 Pod。您可以使用 Label Selector 来确定在哪些节点上运行 DaemonSet 的 Pod。

2.6 HorizontalPodAutoscaler Selector

HorizontalPodAutoscaler(HPA)用于自动缩放 Pod 副本数量,它使用 Label Selector 来选择要自动扩展的 Pod,以根据 CPU 使用率或其他指标来满足应用程序的性能需求。

比如,有一个 Deployment 用于运行应用程序。您希望根据 CPU 使用率来自动扩展 Pod 的数量。在 Deployment 的配置中,您可以使用 Selector 来选择这些 Pod。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app-container
        image: my-app:latest

接下来,您可以创建一个 HorizontalPodAutoscaler 资源来配置自动扩展。

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app-deployment
  minReplicas: 2
  maxReplicas: 5
  metrics:
  - type: Resource
    resource:
      name: cpu
      targetAverageUtilization: 50

字段说明:

  • scaleTargetRef 字段,以确定要自动扩展的目标 Deployment。
  • minReplicasmaxReplicas 字段,以确定 Pod 副本数量的范围。
  • metrics 字段,以配置要监视的指标。在这里,我们配置了 CPU 使用率,并设置目标平均利用率为 50%。

在这个示例中,HPA 的 Selector 是由 scaleTargetRef 中的目标 Deployment 决定的,因为它会选择要自动扩展的 Pod 副本。要自动扩展其他类型的资源(比如 statefulset 资源),可根据需要调整 scaleTargetRef 的配置即可。

2.7 NetworkPolicy Selector

在 NetworkPolicy 中,Selector 用于定义网络策略,以允许或拒绝特定标签的 Pod 之间的通信,这有助于实施网络安全策略。以下是一个简单的 NetworkPolicy 示例,演示如何使用 Selector 来控制流量:

环境:有两个应用程序,一个是 frontend 应用程序,另一个是 backend 应用程序,你希望 frontend 可以访问 backend,但不希望 frontend 能够与其他应用程序通信。

  • backend 程序

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: backend-app
    spec:
      selector:
        matchLabels:
          app: backend
      template:
        metadata:
          labels:
            app: backend
        spec:
          containers:
            - name: backend-container
              image: backend-image:latest
    
  • frontend 程序

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: frontend-app
    spec:
      selector:
        matchLabels:
          app: frontend
      template:
        metadata:
          labels:
            app: frontend
        spec:
          containers:
            - name: frontend-container
              image: frontend-image:latest
    
  • 创建 NetworkPolicy(实现流量控制)

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-frontend-to-backend
    spec:
      podSelector:
        matchLabels:
          app: frontend
      policyTypes:
        - Ingress
      ingress:
        - from:
          - podSelector:
              matchLabels:
                app: backend
    

    在上述示例中,我们创建了一个名为 allow-frontend-to-backend 的 NetworkPolicy。此 NetworkPolicy 允许 frontend Pod 访问具有 Label app: backendbackend Pod。

    这个 NetworkPolicy 将确保只有 frontend Pod 可以与 backend Pod 通信,而其他 Pod 不允许与它们通信。

2.8 Pod Affinity and Anti-Affinity Rules

在 Kubernetes 中,Pod 亲和性(Affinity)和反亲和性(Anti-Affinity)规则用于定义在节点调度中如何将 Pod 定位到节点的策略。这些规则可以用来优化节点的选择,以满足性能、可用性或其他需求。

比如我们有一个分布式应用程序,其中有两种类型的服务:frontend(前端)backend(后端)。我们希望将 frontendbackend Pod 部署到不同的节点上,以确保可用性。此时我们就可以使用 Pod 反亲和性规则。

  • 创建 Pod 资源并打标签

    下面示例中,frontend Pod 和 backend Pod 都分配了不同的标签。

    apiVersion: v1
    kind: Pod
    metadata:
      name: frontend-pod
      labels:
        app: frontend
    spec:
      containers:
        - name: frontend-container
          image: my-frontend-image:latest
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: backend-pod
      labels:
        app: backend
    spec:
      containers:
        - name: backend-container
          image: my-backend-image:latest
    
  • 建一个 Pod Anti-Affinity 规则

    以确保 frontendbackend Pods 不会被调度到同一节点上。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-app-deployment
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: frontend
      template:
        metadata:
          labels:
            app: frontend
        spec:
          affinity:
            podAntiAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                - labelSelector:
                    matchExpressions:
                      - key: app
                        operator: In
                        values:
                          - frontend
                  topologyKey: kubernetes.io/hostname
          containers:
            - name: frontend-container
              image: my-frontend-image:latest
    

    简单的字段解释:

    affinity:定义 Pod 亲和性(Affinity)规则,控制 Pod 如何被调度到节点上。

    podAntiAffinity:定义反亲和性规则,确保 Pod 不会与其他具有相同标签的 Pod 被调度到相同的节点上。

    requiredDuringSchedulingIgnoredDuringExecution:指定规则要求在调度时强制执行。

    labelSelector:定义要匹配的标签选择器。

    matchExpressions:包含一组标签匹配条件。

    key: app:标签的键是 “app”。

    operator: In:使用 “In” 操作符,表示匹配标签值在给定的值列表中。

    values: [frontend]:匹配的值是 “frontend”。

    topologyKey: kubernetes.io/hostname:指定用于节点的拓扑域选择器,这里使用节点主机名作为拓扑域的选择器。

总结

1、Labels

  • 标识应用程序和组件:Labels 可以用于标识和区分不同的应用程序和组件。

    通过为 Pods、Services、Deployments 等资源对象添加适当的 Labels,就可以清晰地了解哪些资源属于哪个应用程序或服务。

  • 环境划分:Labels 可用于将资源对象分组到不同的环境中,例如开发、测试和生产环境。

    这使得可以在不同环境中管理和部署相同的应用程序,同时确保资源的分离和隔离。

  • 版本管理:Labels 可以用于标识不同版本的应用程序或服务。

    这对于在不同版本之间进行滚动升级或回滚非常有用。

  • 拥有者和应用层次结构:Labels 可以用于跟踪资源对象的拥有者,并创建应用层次结构。

    例如,可以使用 Labels 标识哪个 Deployment 管理了哪个 ReplicaSet,ReplicaSet 管理了哪些 Pods。

  • 查询和筛选:Labels 可以用于执行查询和筛选操作,以查找符合特定标准的资源对象。

    这对于执行操作、监控或调试非常有用。

2、Selector

  • Service 选择器:在创建 Kubernetes Service 时,可以使用 Selector 来选择要将流量路由到哪些 Pod。

    可以将 Service 关联到具有特定标签的 Pod,以提供负载均衡和服务发现。

  • Deployment 和 ReplicaSet 选择器:可以使用 Selector 来确定要由这些控制器管理的 Pod。

    可以轻松地将控制器与具有特定标签的 Pod 关联。

  • StatefulSet 选择器:StatefulSet 用于管理有状态的应用程序,如数据库。

    可以使用 Selector 来选择 StatefulSet 管理的 Pod,以确保它们符合特定的标签要求。

  • NetworkPolicy 选择器:在创建 NetworkPolicy 时,可以使用 Selector 来定义允许或拒绝哪些 Pod 之间的网络通信。

    这有助于实施网络安全策略。

  • Pod 亲和性和反亲和性规则:Pod 亲和性和反亲和性规则允许我们根据标签选择器定义 Pod 如何调度到节点上。

    通过定义规则,确保具有特定标签的 Pod 不会调度到同一节点上,以提高可用性和可靠性。

  • DaemonSet 选择器:在创建 DaemonSet 时,可以使用 Selector 来选择在哪些节点上运行 DaemonSet 的 Pod。

    这对于在特定节点上运行系统级任务非常有用。

  • Horizontal Pod Autoscaler (HPA) 选择器:HPA 使用 Selector 来选择目标 Deployment 或 ReplicaSet 中的 Pod,并基于 CPU 使用率等指标来自动扩展或缩小 Pod 副本数量。

  • 自定义控制器选择器:如果您创建自定义控制器,可以使用 Selector 来选择您的控制器要管理的资源对象,以及如何将它们与您的控制器相关联。

—END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云计算-Security

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值