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
那如何根据标签反查询其对应的资源呢?
kubectl get node -l disktype=ssd
# 该命令就可以查出哪些节点具备disktype=ssd标签
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。minReplicas
和maxReplicas
字段,以确定 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 访问具有 Labelapp: backend
的backend
Pod。这个 NetworkPolicy 将确保只有
frontend
Pod 可以与backend
Pod 通信,而其他 Pod 不允许与它们通信。
2.8 Pod Affinity and Anti-Affinity Rules
在 Kubernetes 中,Pod 亲和性(Affinity)和反亲和性(Anti-Affinity)规则用于定义在节点调度中如何将 Pod 定位到节点的策略。这些规则可以用来优化节点的选择,以满足性能、可用性或其他需求。
比如我们有一个分布式应用程序,其中有两种类型的服务:frontend(前端)
和 backend(后端)
。我们希望将 frontend
和 backend
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 规则
以确保
frontend
和backend
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