资源身份标签Labels
在 Kubernetes 中,标签(Labels)是用于标识和选择 Kubernetes 对象(如 Pod、Deployment、Service、Namespace 等)的键值对。标签提供了一种简单而灵活的方式来组织和筛选对象,使得管理和查询 Kubernetes 对象变得更加方便。
主要用途
- 分类和组织:通过标签可以将对象分组,如将同一应用的所有 Pod 标记为一个标签。
- 筛选和管理:使用标签选择器(Label Selector)来选择和操作特定标签的对象。
- 自动化操作:结合标签选择器,可以在自动化流程中操作和管理对象,如自动缩放、自动部署等。
使用方法
1. 为对象添加标签
可以在创建对象时或创建后为其添加标签。以下是在创建 Pod 时添加标签的示例:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
labels:
app: my-app
environment: production
spec:
containers:
- name: my-container
image: nginx
在这个例子中,Pod my-pod
被标记了两个标签:app=my-app
和 environment=production
。
2. 使用 kubectl
添加或修改标签
可以使用 kubectl label
命令为现有对象添加或修改标签:
kubectl label pod my-pod owner=john
这条命令为 my-pod
添加了一个新的标签 owner=john
。
3. 使用标签选择器
标签选择器是用于根据标签筛选对象的机制。以下是几种常见的标签选择器示例:
- 等式选择器:选择与指定标签键值对匹配的对象。
kubectl get pods -l app=my-app
这条命令选择所有带有 app=my-app
标签的 Pod。参数 -l, --selector=
用于指定标签。
- 集合选择器:选择标签值在指定集合中的对象。
kubectl get pods -l environment in (production, staging)
这条命令选择所有带有 environment
标签,且值为 production
或 staging
的 Pod。
- 存在性选择器:选择具有指定标签键的对象。
kubectl get pods -l owner
这条命令选择所有带有 owner
标签的 Pod,不论其值是什么。
4. 在其他对象中使用标签选择器
标签选择器不仅可以在 kubectl
命令中使用,还可以在其他 Kubernetes 对象的配置中使用,如 Deployment
、Service
、Job
等。以下是一个在 Deployment
中使用标签选择器的示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-container
image: nginx
在这个 Deployment
配置中:
matchLabels
:定义了Deployment
管理的 Pod 的标签选择器,这里选择所有带有app=my-app
标签的 Pod。spec.template.metadata.labels
:定义了新创建的 Pod 的标签,这里为每个新创建的 Pod 添加app: my-app
标签。
结合使用
标签和标签选择器在 Kubernetes 中有广泛的应用,以下是一些常见的结合使用场景:
- 服务发现:使用标签选择器将
Service
绑定到特定的 Pod,实现负载均衡和服务发现。 - 自动化编排:使用标签选择器自动化编排,如使用
HorizontalPodAutoscaler
根据标签选择器自动扩展 Pod。 - 资源分组:使用标签将相关资源分组,便于管理和查询。
最佳实践
- 命名规范:使用有意义的标签键和值,便于理解和维护。
- 避免过度标签:避免添加过多不必要的标签,保持标签的简洁性和实用性。
- 一致性:在不同对象和团队之间保持标签的一致性,便于协作和自动化管理。
通过合理使用标签和标签选择器,可以大大提高 Kubernetes 集群的管理效率和灵活性。
案例:
labels标签,在kubernetes我们会经常见到,它的功能非常关键,就相关于服务pod的身份证信息,如果我们创建一个deployment资源,它之所有能守护下面启动的N个pod以达到期望的数据,service之所以能把流量准确无误的转发到指定的pod上去,归根结底都是labels在这里起作用,下面我们来实际操作下,相信大家跟着操作完成后,就会理解labels的功效了
# 我们先来创建一个nginx的deployment资源
kubectl create deployment nginx --image=nginx:1.21.6 --replicas=3
# 等服务pod都运行好,这时候按我们期待的状态就是3个pod,没问题
kubectl get pod -w
# 我们现在来修改其中一个pod的label,你会发现这个pod会被deployment抛弃,因为失去了labels这个标签,deployment已经不认识这个pod了,它就成了无主的pod,这时我们直接删除这个pod,它就会直接消失,就和我们用kubectl run 一个独立的pod资源一样
kubectl label pod nginx-69747f9bdb-tb27v app=web01 --overwrite=True
# 查看标签
kubectl get pod --show-labels
# 删除修改过标签的pod,不会重启,它已经不受deployment的控制了。
kubectl delete pod nginx-69747f9bdb-tb27v
# 我们再来基于这个nginx的deployment来创建一个service服务
kubectl expose deployment nginx --port=80 --target-port=80 --name=nginx
# 直接利用svc的ip来请求下,发现都是正常的对吧
kubectl get svc nginx
# 这个时候我来来修改下svc资源的选择labels,看看会出现什么情况
kubectl patch services nginx -p '{"spec":{"selector":{"app": "nginxaaa"}}}'
# 这时再请求这个svc的ip,你会发现已经请求不通了,这也证明了它已经关联不到后面对应label的pod了
# 我们修改回来后,会发现一切恢复正常了
kubectl patch services nginx -p '{"spec":{"selector":{"app": "nginx"}}}'
labels受namespace管控,在同一个namespace下面的服务labels,如果只有一个,就需要注意其唯一性,不要有重复的存在,不然服务就会跑串,出现一些奇怪的现象,我们在资源中可以配置多个lables来一起组合使用,这样就会大大降低重复的情况了。
# 多deployment混合运行模式
# 首先导出多服务配置
# kubectl get deployments.apps nginx -o yaml > nginx-other.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx-other # 把名称换一下
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:1.21.6
imagePullPolicy: IfNotPresent
name: nginx
resources: {}
# kubectl describe svc nginx
# kubectl apply -f nginx-other.yaml
# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 5m57s
nginx-other 1/1 1 1 14s