Label 和 Annotation-数据库论坛-技术分享-千百度社区

Label 和 Annotation

Label 和 Annotation

Label

Label(标签)是 Kubernetes 系统中另外一个核心概念。一个 Label 是一个 key=value 的键值对,其中 key 与 value 由用户自己指定。
Label 可以被附加到各种资源对象上,例如Node、Pod、Service、RC 等,一个资源对象可以定义任意数量的 Label,同一个 Label 也可以被添加到任意数量的资源对象上。Label 通常在资源对象定义时确定,也可以在对象创建后动态添加或者删除。

Label的定义

我们通常使用metadata.labels字段,来为对象添加Label。Label可以为多个。一个简单的例子如下:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
    release: stable
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80

上面的描述文件为名为nginx的Pod添加了两个Label,分别为app: nginx和release: stable。

我们可以通过给指定的资源对象捆绑一个或多个不同的Label来实 现多维度的资源分组管理功能,以便灵活、方便地进行资源分配、调 度、配置、部署等管理工作。例如,部署不同版本的应用到不同的环境 中;监控和分析应用(日志记录、监控、告警)等。一些常用的Label 示例如下。

  • 版本标签:”release”:”stable”、”release”:”canary”。
  • 环境标 签:”environment”:”dev”、”environment”:”qa”、”environment”:”production”。
  • 架构标 签:”tier”:”frontend”、”tier”:”backend”、”tier”:”middleware”。
  • 分区标签:”partition”:”customerA”、”partition”:”customerB”。
  • 质量管控标签:”track”:”daily”、”track”:”weekly”。

Label相当于我们熟悉的“标签”。给某个资源对象定义一个Label, 就相当于给它打了一个标签,随后可以通过Label Selector(标签选择 器)查询和筛选拥有某些Label的资源对象,Kubernetes通过这种方式实 现了类似SQL的简单又通用的对象查询机制。

label 添加、修改、删除、查询操作

添加

语法:
kubectl label nodes kube-node label_name=label_value
样例:

  1. 先查看node列表
[root@k8s-test01 ~]# kubectl get nodes
NAME         STATUS                     ROLES                  AGE   VERSION
k8s-test01   Ready,SchedulingDisabled   control-plane,master   35d   v1.22.3
k8s-test02   Ready                      <none>                 35d   v1.20.6
  1. 对k8s-test01添加标签:
kubectl label nodes k8s-test01 gpu=true
node/k8s-test01 labeled

查询

语法:
查看所有标签

kubectl get nodes --show-labels
NAME         STATUS                     ROLES                  AGE   VERSION   LABELS
k8s-test01   Ready,SchedulingDisabled   control-plane,master   35d   v1.22.3   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,gpu=true,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-test01,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=
k8s-test02   Ready                      <none>                 35d   v1.20.6   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-test02,kubernetes.io/os=linux,preferingress=nginx

或者
kubectl describe nodes k8s-test01

删除

删除一个label,只需在命令行最后指定label的key名并与一个减号相连即可:
kubectl label nodes k8s-test01 gpu-

修改

修改一个label的值,需要加上–overwrite参数:
kubectl label nodes k8s-test01 gpu=false --overwrite
或者直接kubectl edit nodes k8s-test01,就可以编辑这个node的配置,保存退出就可以了。

使用标签进行查询

支持使用转义字符,请使用单引号

[root@test basic]# kubectl get pod --show-labels -l 'se'
NAME       READY   STATUS    RESTARTS   AGE   LABELS
pod-demo   1/1     Running   0          21m   rel=stable,se=wang,tire=111

[root@test ~]# kubectl get pods -l ' se in ( wang )'
NAME       READY   STATUS    RESTARTS   AGE
pod-demo   1/1     Running   0          130m

LabelSelector

通过 label selector,客户端/用户可以指定一个对象集合,通过 label selector 对对象的集合进行操作;
Label selector 有两种类型:

  • equality-based:可以使用=、==、!=操作符,可以使用逗号分隔多个表达式
  • set-based :可以使用 in、notin、! 操作符,另外还可以没有操作符,直接写出某个 label的 key,表示过滤有某个 key 的object 而不管该 key 的 value 是何值,!表示没有该 label 的object。

Label Selector可以被类比为SQL语句中的where查询条件,例如, name=redis-slave这个Label Selector作用于Pod时,可以被类比为select * from pod where pod’s name =‘redis-slave’这样的语句。当前有两种Label Selector表达式:基于等式的(Equality-based)和基于集合的(Set- based),前者采用等式类表达式匹配标签,下面是一些具体的例子。

name=redis-slave:匹配所有具有标签name=redis-slave的资源对 象。
env!=production:匹配所有不具有标签env=production的资源对 象,比如env=test就是满足此条件的标签之一。

后者则使用集合操作类表达式匹配标签,下面是一些具体的例子。

  • name in(redis-master, redis-slave):匹配所有具有标签 name=redis-master或者name=redis-slave的资源对象。
  • name not in(php-frontend):匹配所有不具有标签name=php-frontend的资源对象。

可以通过多个Label Selector表达式的组合实现复杂的条件选择,多 个表达式之间用“,”进行分隔即可,几个条件之间是“AND”的关系,即 同时满足多个条件,比如下面的例子:
RC通过Label Selector机制实现对Pod副本的自动控制。 RC和Service在spec中定义Selector与Pod进行关联。

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: new_nginx<<=================

Deployment、Replica Set、DaemonSet和Job可以在Selector中使用基于集合的筛选条件定义。

 selector:
    matchLabels:
      app:new_nginx
    matchExpressions:
      - {key: tier, operator: In, values: [frontend]}
      - {key: environment, operator: NotIn, values: [dev]}

mathchLabels 用于定义一组Label,与直接写在Selector中相同; matchExpressions 用于定义一组基于集合的筛选条件,可以用的运算符包括:In NotIn Exists和DoesNotExIST。

提示:如果同时设置了matchLabels和matchExpressions,则两组条件为”AND” 关系,即所有条件需要同时满足时才能完成Selector的筛选。

Label Selector在Kubernetes中的重要使用场景如下。

  • kube-controller进程通过在资源对象RC上定义的Label Selector 来筛选要监控的Pod副本数量,使Pod副本数量始终符合预期设定的全自 动控制流程。
  • kube-proxy进程通过Service的Label Selector来选择对应的Pod, 自动建立每个Service到对应Pod的请求转发路由表,从而实现Service的 智能负载均衡机制。
  • 通过对某些Node定义特定的Label,并且在Pod定义文件中使用 NodeSelector这种标签调度策略,kube-scheduler进程可以实现Pod定向调 度的特性。

在前面的留言板例子中,我们只使用了一个name=XXX的Label Selector。看一个更复杂的例子:假设为Pod定义了3个Label:release、 env和role,不同的Pod定义了不同的Label值,如图1.7所示,如果设置“role=frontend”的Label Selector,则会选取到Node 1和Node 2上的Pod。
如果设置“release=beta”的Label Selector,则会选取到Node 2和Node3上的Pod。
总之,使用Label可以给对象创建多组标签,Label和Label Selector 共同构成了Kubernetes系统中核心的应用模型,使得被管理对象能够被 精细地分组管理,同时实现了整个集群的高可用性。

图1.7 Label Selector的作用范围1


image.png
image.png

LabelSelector API


kubectl -n payoutservice-stagingrnpci-2 get ai -oyaml -l sync.controller.federation.tess.io/watch=true -v=8
I1015 12:55:16.788921   41904 loader.go:375] Config loaded from file:  ~/.kube/config
I1015 12:55:16.800569   41904 round_trippers.go:420] GET https://cr-dev.abc.io/apis/apps.io/v1alpha2/namespaces/payoutservice-stagingrnpci-2/applicationinstances?labelSelector=sync.controller.federation.tess.io%2Fwatch%3Dtrue&limit=500
I1015 12:55:16.800583   41904 round_trippers.go:427] Request Headers:
I1015 12:55:16.800587   41904 round_trippers.go:431]     Accept: application/json
I1015 12:55:16.800591   41904 round_trippers.go:431]     User-Agent: tess/v0.0.0 (darwin/amd64) kubernetes/$Format
I1015 12:55:16.800595   41904 round_trippers.go:431]     Authorization: Bearer <masked>

Annotation

Annotation(注解)与 Label 类似,也使用 key/value 键值对的形式进行定义。
不同的是 Label 具有严格的命名规则,它定义的是 Kubernetes 对象的元数据(Metadata),并且用于Label Selector。Annotation则是用户任意定义的附加信息,以便于外部工具查找。在很多时候,Kubernetes 的模块自身会通过 Annotation 标记资源对象的一些特殊信息。

  • 键值型数据,资源注解,不受字符数量限制
  • 不能被标签选择器选择
  • 常用命令 kubectl annotate
  • 定义在metadata内嵌字段中
  • 使用describe查看
  • 用途 记录每次apply的差异信息

K8s中的Annotations是什么?
Annotations用于非识别信息,即 Kubernetes 不关心的元数据。因此,注解键和值没有约束。因此,如果您想为其他人添加有关给定资源的信息,则注解是更好的选择。

顾名思义,就是注释的意思。有两个功能:

  • 注释性信息,不影响调度
  • 工具和库等客户端可以检索Annotation数据

添加Annotations示例

# 为svc添加注解信息
kubectl annotate svc nginx -n devops kubemaster.top/owner=@marionxue

这样在使用中其实很方便定位和通知相关的工程师,提高问题在团队中排查解决的高效性,当然还可以添加其他的说明信息,如服务的描述信息,Owner,沟通channel,依赖信息,runbook等等

image.png

修改资源时添加注解
在命令行后添加 –save-config=true ,就会自动添加此次修改的注解.
–save-config参数默认值为false

kubectl edit pvc pv-volume --save-config=true

删除Annotations

# kubectl annotate 资源类型 资源名称 key-
kubectl annotate svc nginx -n devops kubemaster.top/owner-

查看Annotations信息

kubectl describe svc nginx
# 查看Annotations字段即可

作用

  • Annotation 的作用,一个是被controller 读取,进行相关的操作。例如
func (lbscheduler *HLBScheduler) getPaasRealm(defaultClient kubernetes.Interface, namespace string) (string, error) {
    // get paasRealm from namespace annotation firstly, and fallback to global config if not exists
    ns, err := defaultClient.CoreV1().Namespaces().Get(context.TODO(), namespace, metav1.GetOptions{})
    if err != nil {
        return "", err
    }
    if env, exist := ns.Annotations[ENVANNOTATION]; exist {
        return strings.Title(strings.ToLower(env)), nil
    }
    return "", errors.New(fmt.Sprintf("could not determine the paasRealm from namespace %s", namespace))
}

ENVANNOTATION 是定义在namespace spec 里medata 下面的annotation 的一个key。

  • 另外一个可以被引用,这样在动态生成spec 的时候,应用annotation 的值可以不用变化
meta:
   labels:
      applicationinstance.tess.io/name: a
  annotations:
      application.env.tess.io/name: b
 spec:
     containers:
        - env:
           - name: APP_INSTANCE_NAME
             valueFrom:
                 fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.labels['applicationinstance.tess.io/name']
           - name: ENV_NAME
             valueFrom:
                 fieldRef:
                   apiVersion: v1
                     fieldPath: metadata.annotations['application.env.tess.io/name']
.....

最后编辑于 : 2022.10.18 06:54:58 © 著作权归作者所有,转载或内容合作请联系作者

请登录后发表评论

    没有回复内容